Merge pull request #1 from athenaer/master

please cheche the source code
This commit is contained in:
Jie Liu 2013-04-17 23:02:26 -07:00
commit 04bfc3e5af
18693 changed files with 1791203 additions and 0 deletions

359
pom.xml Normal file
View File

@ -0,0 +1,359 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.ac.iscas</groupId>
<artifactId>haflow</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>haflow</name>
<properties>
<!-- Plugin的属性定义 -->
<!-- 主要依赖库的版本定义 -->
<springside.version>4.1.0-SNAPSHOT</springside.version>
<spring.version>3.2.0.RELEASE</spring.version>
<hibernate.version>4.1.9.Final</hibernate.version>
<spring-data-jpa.version>1.2.0.RELEASE</spring-data-jpa.version>
<commons-dbcp.version>1.4</commons-dbcp.version>
<sitemesh.version>2.4.2</sitemesh.version>
<shiro.version>1.2.1</shiro.version>
<hibernate-validator.version>4.3.1.Final</hibernate-validator.version>
<jackson.version>2.1.2</jackson.version>
<slf4j.version>1.7.2</slf4j.version>
<logback.version>1.0.9</logback.version>
<commons-lang3.version>3.1</commons-lang3.version>
<guava.version>13.0.1</guava.version>
<joda-time.version>2.1</joda-time.version>
<junit.version>4.11</junit.version>
<mockito.version>1.9.5</mockito.version>
<selenium.version>2.28.0</selenium.version>
<jetty.version>7.6.8.v20121106</jetty.version>
<h2.version>1.3.170</h2.version>
<!-- Plugin的属性定义 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdk.version>1.6</jdk.version>
<!-- 项目属性 -->
<jdbc.driver.groupId>mysql</jdbc.driver.groupId>
<jdbc.driver.artifactId>mysql-connector-java</jdbc.driver.artifactId>
<jdbc.driver.version>5.1.21</jdbc.driver.version>
</properties>
<repositories>
<!--
如有Nexus私服, 取消注释并指向正确的服务器地址. <repository> <id>nexus</id> <name>Team
Nexus Repository</name>
<url>http://localhost:8081/nexus/content/groups/public</url>
</repository>
-->
<repository>
<id>central</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<!--
设定插件仓库 如有Nexus私服, 取消注释并指向正确的服务器地址. <pluginRepositories>
<pluginRepository> <id>nexus</id> <name>Team Nexus Repository</name>
<url>http://localhost:8081/nexus/content/groups/public</url>
<snapshots> <enabled>false</enabled> </snapshots> </pluginRepository>
</pluginRepositories>
-->
<!-- 依赖项定义 -->
<dependencies>
<!-- Jackson JSON Mapper -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.12</version>
</dependency>
<!-- spring data access -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>${spring-data-jpa.version}</version>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit-dep</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>${jdbc.driver.groupId}</groupId>
<artifactId>${jdbc.driver.artifactId}</artifactId>
<version>${jdbc.driver.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- WEB begin -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>opensymphony</groupId>
<artifactId>sitemesh</artifactId>
<version>${sitemesh.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<!-- WEB end -->
<!-- GENERAL UTILS begin -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<!-- GENERAL UTILS end -->
</dependencies>
<build>
<plugins>
<!-- compiler插件, 设定JDK版本 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
<!-- war打包插件, 设定war包名称不带版本号 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
<!-- test插件, 仅测试名称为*Test的类,使用支持分组测试的surefire-junit47 driver -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
<argLine>-Xmx256M</argLine>
</configuration>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.12.4</version>
</dependency>
</dependencies>
</plugin>
<!-- 增加functional test的Source目录 -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>add-functional-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/test/functional</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<!-- cobertura插件, 设置不需要计算覆盖率的类 -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<instrumentation>
<excludes>
<exclude>**/entity/**/*.class</exclude>
<exclude>**/*Controller.class</exclude>
</excludes>
</instrumentation>
</configuration>
</plugin>
<!-- eclipse插件, 设定wtp版本 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<downloadSources>true</downloadSources>
<downloadJavadocs>false</downloadJavadocs>
<wtpversion>2.0</wtpversion>
<!-- 增加设置项目encoding的文件 -->
<additionalConfig>
<file>
<name>.settings/org.eclipse.core.resources.prefs</name>
<content>
<![CDATA[eclipse.preferences.version=1${line.separator}encoding/<project>=${project.build.sourceEncoding}${line.separator}]]>
</content>
</file>
</additionalConfig>
</configuration>
</plugin>
<!-- enforcer插件, 设定环境与依赖的规则 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<id>enforce-banned-dependencies</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireMavenVersion>
<version>3.0.3</version>
</requireMavenVersion>
<requireJavaVersion>
<version>1.6</version>
</requireJavaVersion>
<bannedDependencies>
<searchTransitive>true</searchTransitive>
<!-- 避免引入过期的jar包 -->
<excludes>
<exclude>commons-logging</exclude>
<exclude>aspectj:aspectj*</exclude>
<exclude>org.springframework:2.*</exclude>
<exclude>org.springframework:3.0.*</exclude>
</excludes>
</bannedDependencies>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
<!-- resource插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
</plugin>
<!-- install插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.4</version>
</plugin>
<!-- clean插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
</plugin>
<!-- ant插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
</plugin>
<!-- dependency插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
</plugin>
</plugins>
</build>
<profiles>
</profiles>
</project>

View File

@ -0,0 +1,20 @@
package haflow;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
public class HelloWorldController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
// TODO Auto-generated method stub
ModelAndView mav = new ModelAndView("hello.jsp");
mav.addObject("message", "Hello World!");
return mav;
}
}

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<description>Spring公共配置 </description>
<bean id="bean1" class="haflow.HelloWorld" />
</beans>

View File

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Class-Path:

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- ======================== controller ======================== -->
<bean id="HelloWorldController"
class="haflow.HelloWorldController">
</bean>
<!-- ======================== mappings ======================== -->
<bean id="urlHandlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="hello.do">HelloWorldController</prop>
</props>
</property>
</bean>
</beans>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>hadoop dataflow</display-name>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>testDojo.html</welcome-file>
</welcome-file-list>
</web-app>

788
src/main/webapp/demo.html Normal file
View File

@ -0,0 +1,788 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Theme Previewer</title>
<link rel="stylesheet" href="static/dojolib/dijit/themes/claro/document.css"/>
<link rel="stylesheet" href="static/dojolib/dijit/themes/claro/claro.css"/>
<link rel="stylesheet" href="static/css/demo.css"/>
<script type="text/javascript" src="static/dojolib/dojo/dojo.js"
data-dojo-config="parseOnLoad: false, async:true"></script>
<script type="text/javascript" src="src.js"></script>
</head>
<body class="claro">
<!-- basic preloader: -->
<div id="loader"><div id="loaderInner" style="direction:ltr;white-space:nowrap;overflow:visible;">Loading ... </div></div>
<div data-dojo-type="dijit.Menu" id="submenu1" data-dojo-props='contextMenuForWindow:true, style:"display:none"' style="display: none;">
<div data-dojo-type="dijit.MenuItem">Enabled Item</div>
<div data-dojo-type="dijit.MenuItem" data-dojo-props="disabled:true">Disabled Item</div>
<div data-dojo-type="dijit.MenuSeparator"></div>
<div data-dojo-type="dijit.MenuItem" data-dojo-props="iconClass:'dijitIconCut'">Cut</div>
<div data-dojo-type="dijit.MenuItem" data-dojo-props="iconClass:'dijitIconCopy'">Copy</div>
<div data-dojo-type="dijit.MenuItem" data-dojo-props="iconClass:'dijitIconPaste'">Paste</div>
<div data-dojo-type="dijit.MenuSeparator"></div>
<div data-dojo-type="dijit.PopupMenuItem">
<span>Enabled Submenu</span>
<div data-dojo-type="dijit.Menu" id="submenu2">
<div data-dojo-type="dijit.MenuItem">Submenu Item One</div>
<div data-dojo-type="dijit.MenuItem">Submenu Item Two</div>
<div data-dojo-type="dijit.PopupMenuItem">
<span>Deeper Submenu</span>
<div data-dojo-type="dijit.Menu" id="submenu4">
<div data-dojo-type="dijit.MenuItem">Sub-sub-menu Item One</div>
<div data-dojo-type="dijit.MenuItem">Sub-sub-menu Item Two</div>
</div>
</div>
</div>
</div>
<div data-dojo-type="dijit.PopupMenuItem" data-dojo-props="disabled:true">
<span>Disabled Submenu</span>
<div data-dojo-type="dijit.Menu" id="submenu3" style="display: none;">
<div data-dojo-type="dijit.MenuItem">Submenu Item One</div>
<div data-dojo-type="dijit.MenuItem">Submenu Item Two</div>
</div>
</div>
<div data-dojo-type="dijit.PopupMenuItem">
<span>Different popup</span>
<div data-dojo-type="dijit.ColorPalette"></div>
</div>
<div data-dojo-type="dijit.PopupMenuItem">
<span>Different popup</span>
<div data-dojo-type="dijit.Calendar"></div>
</div>
</div>
<!-- end contextMenu -->
<div id="main" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="liveSplitters:false, design:'sidebar'">
<div id="header" data-dojo-type="dijit.MenuBar" data-dojo-props="region:'top'">
<div data-dojo-type="dijit.PopupMenuBarItem" id="edit">
<span>Edit</span>
<div data-dojo-type="dijit.Menu" id="editMenu">
<div data-dojo-type="dijit.MenuItem" id="cut" data-dojo-props="
iconClass:'dijitIconCut'
">Cut</div>
<div data-dojo-type="dijit.MenuItem" id="copy" data-dojo-props="
iconClass:'dijitIconCopy'
">Copy</div>
<div data-dojo-type="dijit.MenuItem" id="paste" data-dojo-props="iconClass:'dijitIconPaste'">Paste</div>
<div data-dojo-type="dijit.MenuSeparator" id="separator"></div>
<div data-dojo-type="dijit.MenuItem" id="undo" data-dojo-props="iconClass:'dijitIconUndo'">Undo</div>
</div>
</div>
<div data-dojo-type="dijit.PopupMenuBarItem" id="view">
<span>View</span>
<div data-dojo-type="dijit.Menu" id="viewMenu">
<div data-dojo-type="dijit.MenuItem">Normal</div>
<div data-dojo-type="dijit.MenuItem">Outline</div>
<div data-dojo-type="dijit.PopupMenuItem">
<span>Zoom</span>
<div data-dojo-type="dijit.Menu" id="zoomMenu">
<div data-dojo-type="dijit.MenuItem">50%</div>
<div data-dojo-type="dijit.MenuItem">75%</div>
<div data-dojo-type="dijit.MenuItem">100%</div>
<div data-dojo-type="dijit.MenuItem">150%</div>
<div data-dojo-type="dijit.MenuItem">200%</div>
</div>
</div>
</div>
</div>
<div data-dojo-type="dijit.PopupMenuBarItem" id="themes">
<span>Themes</span>
<div data-dojo-type="dijit.Menu" id="themeMenu"></div>
</div>
<div data-dojo-type="dijit.PopupMenuBarItem" id="dialogs">
<span>Dialogs</span>
<div data-dojo-type="dijit.Menu" id="dialogMenu">
<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick: showDialog">slow loading</div>
<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick: showDialogAb">action bar</div>
</div>
</div>
<div data-dojo-type="dijit.PopupMenuBarItem" id="inputPadding">
<span>TextBox Padding</span>
<div data-dojo-type="dijit.Menu" id="inputPaddingMenu">
<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding, checked:true">theme default</div>
<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">0px</div>
<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">1px</div>
<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">2px</div>
<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">3px</div>
<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">4px</div>
<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">5px</div>
</div>
</div>
<div data-dojo-type="dijit.PopupMenuBarItem" id="help">
<span>Help</span>
<div data-dojo-type="dijit.Menu" id="helpMenu">
<div data-dojo-type="dijit.MenuItem">Help Topics</div>
<div data-dojo-type="dijit.MenuItem">About Dijit</div>
</div>
</div>
<div data-dojo-type="dijit.PopupMenuBarItem" data-dojo-props="disabled:true">
<span>Disabled</span>
<div data-dojo-type="dijit.Menu">
<div data-dojo-type="dijit.MenuItem">You should not see this</div>
</div>
</div>
</div>
<div data-dojo-type="dijit.layout.AccordionContainer" data-dojo-props="region:'leading', splitter:true, minSize:20"
style="width: 300px;" id="leftAccordion">
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Popups and Alerts"'><div style="padding:8px">
<h2>Tooltips</h2>
<ul>
<li>
<span id="ttRich"><b>rich</b> <i>text</i> tooltip</span>
<span data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'ttRich'" style="display:none;">
Embedded <b>bold</b> <i>RICH</i> text <span style="color:#309; font-size:x-large;">weirdness!</span>
</span>
</li>
<li><a id="ttOne" href='#bogus'>anchor tooltip</a>
<span data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:"ttOne"' style="display:none;">tooltip on anchor</span>
</li>
</ul>
<table style="width: 100%;">
<tr>
<td></td>
<td>
<div id="ttBelow">tooltip below</div>
<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'ttBelow', position:['below']" style="display:none; width: 100px;">I'm <i>below</i>!</div>
</td>
<td></td>
</tr>
<tr>
<td>
<div id="ttRight">tooltip after</div>
<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'ttRight', position:['after']" style="display:none;">I'm on the <i>right</i>!<br>(or left on RTL systems)</div>
</td>
<td></td>
<td>
<div id="ttLeft">tooltip before</div>
<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'ttLeft', position:['before','after']" style="display:none;">I'm on the <i>left</i>!<br>(or right on RTL systems)</div>
</td>
</tr>
<tr>
<td></td>
<td>
<div id="ttAbove">tooltip above</div>
<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'ttAbove', position:['above']" style="display:none;">I'm <i>above</i>!</div>
</td>
<td></td>
</tr>
</table>
<hr class="spacer">
<h2>Dialogs</h2>
<ul>
<li><a href="#" onclick="dijit.byId('dialog1').show()">slow loading modal dialog</a></li>
<li><a href="#" onclick="dijit.byId('dialogAB').show()">modal dialog w/action bar</a></li>
</ul>
<div data-dojo-type="dijit.form.DropDownButton">
<span>Show Tooltip Dialog</span>
<div data-dojo-type="dijit.TooltipDialog" id="tooltipDlg" data-dojo-props='title:"Enter Login information"'>
<table>
<tr>
<td><label for="user">User:</label></td>
<td><input data-dojo-type="dijit.form.TextBox" type="text" id="user" name="user" ></td>
</tr>
<tr>
<td><label for="pwd">Password:</label></td>
<td><input data-dojo-type="dijit.form.TextBox" type="password" id="pwd" name="pwd"></td>
</tr>
<tr>
<td colspan="2">
<button data-dojo-type="dijit.form.Button" type="submit" name="submit">Login</button>
</tr>
</table>
</div>
</div>
</div>
</div>
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tree"'>
<!-- tree widget -->
<div data-dojo-type="dijit.Tree"
data-dojo-props="model: continentModel, query:{ type:'continent'}, label:'Continents', openOnClick:true"
></div>
</div>
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Rootless Tree'">
<div id="rootlessTree" data-dojo-type="dijit.Tree" data-dojo-props="
model:continentModel,
query:{ type:'continent' },
showRoot: false,
openOnClick:true
"></div>
</div>
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:true, title:"Calendar"'>
<!-- calendar widget pane -->
<input id="calendar1" data-dojo-type="dijit.Calendar">
</div>
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Color Picker"'>
<p>
Selecting a color will change the background color of the page.
Use this to test how tooltips and drop downs appear with different backgrounds.
</p>
<h2 class="testHeader">3x4</h2>
<script>
function setBackground(color){
dojo.query('.dijitAccordionBody').style('background', color);
dojo.query('.dijitTabPaneWrapper').style('background', color);
}
</script>
<div data-dojo-type="dijit.ColorPalette" data-dojo-props="palette:'3x4', onChange:setBackground"></div>
<h2 class="testHeader">7x10</h2>
<div data-dojo-type="dijit.ColorPalette" data-dojo-props="onChange:setBackground"></div>
</div>
</div><!-- end AccordionContainer -->
<!-- top tabs (marked as "center" to take up the main part of the BorderContainer) -->
<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props="region:'center', tabStrip:true" id="topTabs">
<div id="basicFormTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Basic Form Widgets', style:'padding:10px;display:none;'">
<h2>Buttons</h2>
<p>Buttons can do an action, display a menu, or both:</p>
Enabled:
<button data-dojo-type="dijit.form.Button" data-dojo-props="iconClass:'dijitIconTask'">
Simple
</button>
<div data-dojo-type="dijit.form.DropDownButton" data-dojo-props="iconClass:'dijitIconEdit'">
<span>Drop Down</span>
<div data-dojo-type="dijit.Menu" id="editMenu1" style="display: none;">
<div data-dojo-type="dijit.MenuItem" data-dojo-props="
iconClass:'dijitIconCut'
">Cut</div>
<div data-dojo-type="dijit.MenuItem" data-dojo-props="
iconClass:'dijitIconCopy'
">Copy</div>
<div data-dojo-type="dijit.MenuItem" data-dojo-props="
iconClass:'dijitIconPaste'
">Paste</div>
</div>
</div>
<div data-dojo-type="dijit.form.ComboButton" data-dojo-props='iconClass:"dijitIconSave", optionsTitle:"save options"'>
<span>Combo</span>
<div data-dojo-type="dijit.Menu" id="saveMenu1" style="display: none;">
<div data-dojo-type="dijit.MenuItem" data-dojo-props="
iconClass:'dijitIconSave'
">Save</div>
<div data-dojo-type="dijit.MenuItem">Save As</div>
</div>
</div>
<div data-dojo-type="dijit.form.ToggleButton" data-dojo-props="
checked:true
"> Toggle </div>
<hr class="spacer">
Disabled:
<button data-dojo-type="dijit.form.Button" data-dojo-props='iconClass:"dijitIconTask", disabled:true' disabled>
Simple
</button>
<div data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"dijitIconEdit", disabled:true'>
<span>Drop Down</span>
<ul data-dojo-type="dijit.Menu" id="editMenu2" style="display: none;">
<li data-dojo-type="dijit.MenuItem" data-dojo-props="
iconClass:'dijitIconCut'
">Cut</li>
<li data-dojo-type="dijit.MenuItem" data-dojo-props="
iconClass:'dijitIconCopy'
">Copy</li>
<li data-dojo-type="dijit.MenuItem" data-dojo-props="
iconClass:'dijitIconPaste'
">Paste</li>
</ul>
</div>
<div data-dojo-type="dijit.form.ComboButton" data-dojo-props="iconClass:'dijitIconSave', optionsTitle:'save options', disabled:true">
<span>Combo</span>
<div data-dojo-type="dijit.Menu" id="saveMenu2" style="display: none;">
<div data-dojo-type="dijit.MenuItem" data-dojo-props="
iconCLass:'dijitIconSave'
">Save</div>
<div data-dojo-type="dijit.MenuItem">
Save As
</div>
</div>
</div>
<button data-dojo-type="dijit.form.ToggleButton" data-dojo-props="checked:true, disabled:true, iconClass:'dijitCheckBoxIcon'">
Toggle
</button>
<hr class="spacer">
<h2>CheckBox</h2>
<fieldset>
<input id="check1" type="checkBox" data-dojo-type="dijit.form.CheckBox">
<label for="check1">unchecked</label>
<input id="check2" type="checkBox" data-dojo-type="dijit.form.CheckBox" data-dojo-props="checked:true" checked="checked">
<label for="check2">checked</label>
<input id="check3" type="checkBox" data-dojo-type="dijit.form.CheckBox" data-dojo-props='disabled:true' disabled>
<label for="check3">disabled</label>
<input id="check4" type="checkBox" data-dojo-type="dijit.form.CheckBox" data-dojo-props='disabled:true, checked:true' checked="checked" disabled>
<label for="check4">disabled and checked</label>
</fieldset>
<h2>Radio Buttons</h2>
<fieldset>
<input type="radio" name="g1" id="g1rb1" value="news" data-dojo-type="dijit.form.RadioButton">
<label for="g1rb1">news</label>
<input type="radio" name="g1" id="g1rb2" value="talk" data-dojo-type="dijit.form.RadioButton" data-dojo-props='checked:true' checked>
<label for="g1rb2">talk</label>
<input type="radio" name="g1" id="g1rb3" value="weather" data-dojo-type="dijit.form.RadioButton" data-dojo-props='disabled:true' disabled>
<label for="g1rb3">weather (disabled)</label>
</fieldset>
</div> <!-- end of basic form widgets -->
<div id="textboxTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Text Input Widgets", style:"padding:10px;display:none;"'>
<h2>dijit.form.DateTextBox</h2>
<label for="date1">Enabled w/placeHolder:</label>
<input id="date1" name="date1" type="text" data-dojo-type="dijit.form.DateTextBox" data-dojo-props="placeHolder:'Birthday'">
<label for="date2">Disabled w/placeHolder:</label>
<input id="date2" name="date2" type="text" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='placeHolder:"Birthday", disabled:true'>
<label for="date2">Disabled w/value:</label>
<input id="date3" name="date3" type="text" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='value:"2008-12-25", disabled:true'>
<h2>dijit.form.TimeTextBox</h2>
<label for="time1">Enabled:</label>
<input id="time1" name="time1" type="text" data-dojo-type="dijit.form.TimeTextBox" value="T17:45:00">
<label for="time2">Disabled:</label>
<input id="time2" name="time2" type="text" data-dojo-type="dijit.form.TimeTextBox" value="T17:45:00" data-dojo-props='disabled:true' disabled>
<h2>dijit.form.CurrencyTextBox</h2>
<label for="currency1">Enabled:</label>
<input id="currency1" type="text" name="income1" value="54775.53" data-dojo-type="dijit.form.CurrencyTextBox"
data-dojo-props="
required:true, constraints:{ fractional:true }, currency:'USD',
value:54775.53,
invalidMessage:'Invalid amount. Include dollar sign, commas, and cents. Cents are mandatory.'
">
<label for="currency2">Disabled:</label>
<input id="currency2" type="text" name="income1" value="54775.53"
data-dojo-type="dijit.form.CurrencyTextBox" data-dojo-props="required:true, constraints:{ fractional:true },
currency:'USD', invalidMessage:'Invalid amount. Include dollar sign, commas, and cents. Cents are mandatory.',
disabled:true
">
<hr class="spacer">
<h2>dijit.form.NumberSpinner max=100</h2>
<label for="spinner1">Enabled: </label>
<input data-dojo-type="dijit.form.NumberSpinner" data-dojo-props='constraints:{max:100,places:0}, value:10' id="spinner1">
<label for="spinner2">Disabled: </label>
<input data-dojo-type="dijit.form.NumberSpinner" data-dojo-props='constraints:{max:100,places:0}, value:10, disabled:true' id="spinner2">
</div>
<div id="selectTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Select Widgets', style:'padding:10px;display:none;'">
<h2>dijit.form.Select</h2>
<!-- fixme: <label for=""> but target a form element like input select etc -->
<label>Enabled:</label>
<div id="selectEnabled" data-dojo-type="dijit.form.Select" data-dojo-props="value:'AK'">
<span data-dojo-value="AL"><b>Alabama</b></span>
<span data-dojo-value="AK"><span style="color:red">A</span><span style="color:orange">l</span><span style="color:yellow">a</span><span style="color:green">s</span><span style="color:blue">k</span><span style="color:purple">a</span></span>
<span data-dojo-value="AZ"><i>Arizona</i></span>
<span data-dojo-value="AR"><span class="ark">Arkansas</span></span>
<span data-dojo-value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a</span></span>
<span data-dojo-value="NM">New<br>&nbsp;&nbsp;Mexico</span>
</div>
<label>Disabled: </label>
<div id="selectDisabled" data-dojo-props="value:'AK', disabled:true" data-dojo-type="dijit.form.Select">
<span data-dojo-value="AL"><b>Alabama</b></span>
<span data-dojo-value="AK"><span style="color:red">A</span><span style="color:orange">l</span><span style="color:yellow">a</span><span style="color:green">s</span><span style="color:blue">k</span><span style="color:purple">a</span></span>
<span data-dojo-value="AZ"><i>Arizona</i></span>
<span data-dojo-value="AR"><span class="ark">Arkansas</span></span>
<span data-dojo-value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a</span></span>
<span data-dojo-value="NM">New<br>&nbsp;&nbsp;Mexico</span>
</div>
<hr class="spacer">
<h2>dijit.form.FilteringSelect</h2>
<label for="filteringSelect">Enabled w/placeHolder: </label>
<input id="filteringSelect" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props="
placeHolder:'State',
store:stateStore,
searchAttr:'name',
name:'state2'
">
<label for="filteringSelect2">Disabled w/placeHolder: </label>
<input id="filteringSelect2" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props="
disabled:true, store:stateStore, name:'state2', searchAttr:'name'
">
<label for="filteringSelect3">Disabled w/value: </label>
<input id="filteringSelect3" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props="
store: stateStore, searchAttr:'name', disabled:true, value:'CA'
">
</div>
<div id="textareaTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Textarea", style:"padding:10px;"'>
<!-- &#8234; and &#8236; are inserted solely for testing purposes to mark the beginning and end of left-to-right text so that
cogniscent browsers don't render garbled punctuation nor exhibit strange home/end key behavior while in right-to-left mode -->
<h2>dijit.form.Textarea</h2>
<p>Enabled:</p>
<textarea data-dojo-type="dijit.form.Textarea" data-dojo-props='name:"areText"' name="areText">This text area will expand and contract as you type &#8234;text.&#8236;
Lorem ipsum dolor sit &#8234;amet,&#8236;
consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci
tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo &#8234;consequat.&#8236;
</textarea>
<br>
<p>Disabled:</p>
<textarea data-dojo-type="dijit.form.Textarea" data-dojo-props="disabled: true">This text
area is disabled and you shouldn't be able to type in &#8234;it.&#8236;
</textarea>
<h2>dijit.form.SimpleTextarea</h2>
<p></p>
<p>Enabled:</p>
<textarea data-dojo-type="dijit.form.SimpleTextarea">This text area has a constant height and displays a scrollbar when &#8234;necessary.&#8236;
Lorem ipsum dolor sit &#8234;amet,&#8236;
consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci
tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis
autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie &#8234;consequat,&#8236;
vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait
nulla &#8234;facilisi.&#8236;
</textarea>
<p>Disabled:</p>
<textarea data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props="disabled: true">Lorem ipsum dolor sit &#8234;amet,&#8236;
consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci
tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis
autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie &#8234;consequat,&#8236;
vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait
nulla &#8234;facilisi.&#8236;
</textarea>
</div><!-- end of Textarea tab -->
<div id="editorTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Editor", style:"padding:10px;"'>
<p>Enabled:</p>
<!-- FIXME:
set height on this node to size the whole editor, but causes the tab to not scroll
until you select another tab and come back. alternative is no height: here, but that
causes editor to become VERY tall, and size to a normal height when selected (like the
dijit.form.TextArea in "Form Feel" Tab), but in reverse. refs #3980 and is maybe new bug?
-->
<div data-dojo-type="dijit.Editor" data-dojo-props="height:175, extraPlugins:['|', 'createLink', 'fontName'], styleSheets:'../../dijit/themes/claro/document.css'">
<ul>
<li>Lorem <a href="http://dojotoolkit.org">and a link</a>, what do you think?</li>
<li>This is the Editor with a Toolbar attached.</li>
</ul>
</div>
<p>Disabled:</p>
<div data-dojo-type="dijit.Editor" data-dojo-props="height:175, extraPlugins:['|', 'createLink', 'fontName'], styleSheets:'../../dijit/themes/claro/document.css', disabled:true">
<ul>
<li>Lorem <a href="http://dojotoolkit.org">and a link</a>, what do you think?</li>
<li>This is the Editor with a Toolbar attached.</li>
</ul>
</div>
</div><!-- end of Editor tab -->
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Sliders', style:'padding:10px;display:none;'">
<!-- Sliders: -->
<h2>Enabled</h2>
<div style="float:right;">
<div id='slider2' data-dojo-type="dijit.form.VerticalSlider" data-dojo-props="
onChange: function(a){ dojo.byId('slider2input').value = a; },
value:10, maximum:100, minimum:0, discreetValues:11, style:'height:176px; clear:both'
">
<ol data-dojo-type="dijit.form.VerticalRuleLabels" data-dojo-props="container:'leftDecoration', style:'width:2em;', labelStyle:'right:0px;'">
<li>0
<li>100
</ol>
<div data-dojo-type="dijit.form.VerticalRule" data-dojo-props="container:'leftDecoration', style:'width:5px;', count:11"></div>
<div data-dojo-type="dijit.form.VerticalRule" data-dojo-props="container:'rightDecoration', style:'width:5px;', count:11"></div>
<ol data-dojo-type="dijit.form.VerticalRuleLabels" data-dojo-props="container:'rightDecoration', style:'width:2em;', maximum:100, count:6, numericMargin:1, constraints:{ pattern:'#' }"></ol>
</div>
<br> Slider2 Value:<input disabled id="slider2input" size="3" value="10" autocomplete="off">
</div>
<div id="horizontal1" data-dojo-type="dijit.form.HorizontalSlider" data-dojo-props="
value:10, maximum:100, minimum:0, showButtons:false, intermediateChanges:true, style:'width:50%; height:20px',
onChange: function(a){ dojo.byId('slider1input').value = dojo.number.format(a / 100, { places:1, pattern:'#%' }) }
">
<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"topDecoration", style:"height:1.2em;font-size:75%;", numericMargin:1, count:6'></ol>
<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"topDecoration", count:11, style:"height:5px;"'></div>
<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:5, style:"height:5px;"'></div>
<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:"height:1em;font-size:75%;"'>
<li>lowest
<li>normal
<li>highest
</ol>
</div>
<br>Value: <input disabled id="slider1input" size="5" value="10.0%" autocomplete="off">
<div id="horizontal2" data-dojo-type="dijit.form.HorizontalSlider" data-dojo-props="
minimum:1, value:2, maximum:3, discreteValues:3, showButtons:false, intermediateChanges:true,
style:'width:300px; height:40px'
">
<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:3, style:"height:5px;"'></div>
<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:"height:1em;font-size:75%;"'>
<li><span style="font-size: small">small</span>
<li><span style="font-size: medium">medium</span>
<li><span style="font-size: large">large</span>
</ol>
</div>
<h2 style="clear:both">Disabled</h2>
<div style="float:right;">
<div data-dojo-type="dijit.form.VerticalSlider" data-dojo-props="
value:10, maximum:100, minimum:0, discreteValues:11,
style:'height:175px; clear:both', disabled:true
">
<ol data-dojo-type="dijit.form.VerticalRuleLabels" data-dojo-props='container:"leftDecoration", style:"width:2em;", labelStyle:"right:0px;"'>
<li>0
<li>100
</ol>
<div data-dojo-type="dijit.form.VerticalRule" data-dojo-props='container:"leftDecoration", count:11, style:"width:5px;"'></div>
<div data-dojo-type="dijit.form.VerticalRule" data-dojo-props='container:"rightDecoration", count:11, style:"width:5px;"'></div>
<ol data-dojo-type="dijit.form.VerticalRuleLabels" data-dojo-props='container:"rightDecoration", style:"width:2em;", maximum:100, count:6, numericMargin:1, constraints:{ pattern:"#"}'></ol>
</div>
</div>
<div data-dojo-type="dijit.form.HorizontalSlider" id="hs-1width" data-dojo-props="
value:10, maximum:100, minimum:0, showButtons:false, intermediateChanges:true, disabled:true
">
<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"topDecoration", style:"height:1.2em;font-size:75%;", numericMargin:1, count:6'></ol>
<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"topDecoration", count:11, style:"height:5px;"'></div>
<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:5, style:"height:5px;"'></div>
<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:"height:1em;font-size:75%;"'>
<li>lowest
<li>normal
<li>highest
</ol>
</div>
<div data-dojo-type="dijit.form.HorizontalSlider" data-dojo-props="
minimum:1, value:2, maximum:3, discreteValues:3, showButtons:false, intermediateChanges:true,
style:'width:300px; height:40px', disabled:true
">
<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:3, style:"height:5px;"'></div>
<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:"height:1em;font-size:75%;"'>
<li><span style="font-size: small">small</span>
<li><span style="font-size: medium">medium</span>
<li><span style="font-size: large">large</span>
</ol>
</div>
</div>
<div id="variousTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Various Dijits", style:"padding:10px; display:none;"'>
<h2>TitlePane</h2>
<div data-dojo-type="dijit.TitlePane" data-dojo-props="title:'my pane', width:275">
<p>This is a title pane. It can be expanded and collapsed.</p>
<p>Sed sollicitudin suscipit risus. Nam
ullamcorper. Sed nisl lectus, pellentesque nec,
malesuada eget, ornare a, libero. Lorem ipsum dolor
sit amet, consectetuer adipiscing elit.</p>
</div><!-- end title pane -->
<hr class="spacer">
<h2>ProgressBar</h2>
<div data-dojo-props="maximum:200, value:20" id="setTestBar" data-dojo-type="dijit.ProgressBar"></div>
Indeterminate:
<div id="indTestBar" data-dojo-props="indeterminate:true" data-dojo-type="dijit.ProgressBar"></div>
</div><!-- end:various dijits upper tab -->
<div id="InlineEditBoxTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"InlineEditBox", style:"padding:10px;"'>
<h2 class="testTitle">dijit.InlineEditBox + dijit.form.TextBox on &lt;h3&gt;</h2>
(HTML before)
<h3 id="editable" style="font-size:larger;" data-dojo-type="dijit.InlineEditBox">
Edit me - I trigger the onChange callback
</h3>
(HTML after)
<hr class="spacer">
<h2>dijit.InlineEditBox + dijit.form.Textarea</h2>
(HTML before)
<p id="areaEditable" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor: dijit.form.Textarea, autoSave:false'>
I'm one big &#8234;paragraph.&#8236; Go ahead and edit &#8234;me.&#8236; I dare &#8234;you.&#8236;
The quick brown fox jumped over the lazy &#8234;dog.&#8236; Blah blah blah blah blah blah &#8234;blah ...&#8236;
</p>
(HTML after)
<p>
These links will
<a href="#" onclick="dijit.byId('areaEditable').set('disabled', true)">disable</a> /
<a href="#" onclick="dijit.byId('areaEditable').set('disabled', false)">enable</a>
the text area above.
</p>
<hr class="spacer">
<h2>dijit.form.DateTextBox</h2>
(HTML inline before)
<!-- set programmatically to match locale; a server might generate this content also. -->
<span id="backgroundArea" data-dojo-type="dijit.InlineEditBox" data-dojo-props="editor: dijit.form.DateTextBox, width:'170px'"></span>
(HTML after)
<hr class="spacer">
<h2>dijit.form.TimeTextBox</h2>
(HTML inline before)
<!-- set programmatically to match locale; a server might generate this content also. -->
<span id="timePicker" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:dijit.form.TimeTextBox, width:"150px"'></span>
(HTML after)
<hr class="spacer">
<h2>dijit.form.FilteringSelect + Inline + remote data store</h2>
(HTML inline before)
<span id="backgroundArea2" data-dojo-type="dijit.InlineEditBox" data-dojo-props='
editor: dijit.form.FilteringSelect,
editorParams:{ store: stateStore, autoComplete: true, promptMessage: "Please enter a state"},
width:"300px"
'>Indiana</span>
(HTML after)
</div><!-- end InlineEditBox tab -->
<div id="dndTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"DnD", style:"padding:10px; display:none;"'>
<div style="float:left; margin:5px;">
<h3>Source 1</h3>
<div data-dojo-type="dojo.dnd.Source" style="border:3px solid #ccc; padding: 1em 3em; ">
<div class="dojoDndItem">Item <strong>X</strong></div>
<div class="dojoDndItem">Item <strong>Y</strong></div>
<div class="dojoDndItem">Item <strong>Z</strong></div>
</div>
</div>
<div style="float:left; margin:5px; ">
<h3>Source 2</h3>
<div data-dojo-type="dojo.dnd.Source" style="border:3px solid #ccc; padding: 1em 3em; ">
<div class="dojoDndItem">Item <strong>1</strong></div>
<div class="dojoDndItem">Item <strong>2</strong></div>
<div class="dojoDndItem">Item <strong>3</strong></div>
</div>
</div>
</div><!-- end DnD tab -->
<div id="closableTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Closable",
style:"display:none; padding:10px;", closable:true'>
This pane is closable, just for the icon ...
</div>
</div><!-- end of region="center" TabContainer -->
<!-- bottom right tabs -->
<div data-dojo-type="dijit.layout.TabContainer" id="bottomTabs"
data-dojo-props="
tabPosition:'bottom', selectedchild:'btab1', region:'bottom',
splitter:true, tabStrip:true
">
<!-- btab 1 -->
<div id="btab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Info", style:" padding:10px; "'>
<p>You can explore this single page after applying a Theme
for use in creation of your own theme.</p>
<p>There is a right-click [context] pop-up menu here, as well.</p>
</div><!-- end:info btab1 -->
<div id="btab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Alternate Themes", style:"padding:20px;"'>
<span id="themeData"></span>
</div><!-- btab2 -->
<div id="btab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Bottom 3", closable:true'>
<p>I am the last Tab</p>
<div id="dialog2" data-dojo-type="dijit.Dialog" data-dojo-props='title:"Encased Dialog", style:"display:none;"'>
I am the second dialog. I am
parented by the Low Tab Pane #3
</div>
</div><!-- btab3 -->
</div><!-- end Bottom TabContainer -->
</div><!-- end of BorderContainer -->
<!-- dialog in body -->
<div id="dialog1" data-dojo-type="dijit.Dialog" style="display:none;" data-dojo-props="
title:'Floating Modal Dialog from href',
href:'../../dijit/tests/layout/getResponse.php?delay=3000&amp;messId=3',
style: 'width: 400px;',
refreshOnShow:true
"></div>
<div id="dialogAB" data-dojo-type="dijit.Dialog" data-dojo-props="title:'Floating Modal Dialog'" style="display:none;">
<div class="dijitDialogPaneContentArea">
<table>
<tr>
<td><label for="name">Name: </label></td>
<td><input data-dojo-type="dijit.form.TextBox" type="text" name="name" id="name"></td>
</tr>
<tr>
<td><label for="loc">Location: </label></td>
<td><input data-dojo-type="dijit.form.TextBox" type="text" name="loc" id="loc"></td>
</tr>
<tr>
<td><label for="date">Date: </label></td>
<td><input data-dojo-type="dijit.form.DateTextBox" type="text" name="date" id="date"></td>
</tr>
</table>
</div>
<div class="dijitDialogPaneActionBar">
<button data-dojo-type="dijit.form.Button" type="submit" id="ABdialog1button1">OK</button>
<button data-dojo-type="dijit.form.Button" type="button" data-dojo-props="onClick:function(){ dijit.byId('dialogAB').onCancel(); }"
id="ABdialog1button2">Cancel</button>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,17 @@
dependencies = {
layers: [
{
name: "src.js",
resourceName: "demos.themePreviewer.src",
dependencies: [
"demos.themePreviewer.src"
]
}
],
prefixes: [
[ "dijit", "../dijit" ],
[ "dojox", "../dojox" ],
[ "demos", "../demos" ]
]
}

13
src/main/webapp/hello.jsp Normal file
View File

@ -0,0 +1,13 @@
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
世界,你好!
${message}
</body>
</html>

View File

@ -0,0 +1,36 @@
{
"identifier": "wishId",
"label": "description",
"items": [ {
"wishId": 4455, "description": "Don Pepin Garcia Delicias", "size": "7-50",
"origin": "Nicaragua", "wrapper": "Corojo", "shape": "Straight"
}, {
"wishId": 4456, "description": "601 Habano Robusto", "size": "5-50",
"origin": "Nicaragua", "wrapper": "Natural", "shape": "Straight"
}, {
"wishId": 4457, "description": "Black Pearl Rojo Robusto", "size": "4 3/4-52",
"origin": "Nicaragua", "wrapper": "Natural", "shape": "Straight"
}, {
"wishId": 4458, "description": "Padron Churchill", "size": "6 7/8-46",
"origin": "Nicaragua", "wrapper": "Natural", "shape": "Straight"
}, {
"wishId": 4459, "description": "Davidoff Aniversario No. 2", "size": "7-48",
"origin": "Dominican Republic", "wrapper": "Natural", "shape": "Straight"
}, {
"wishId": 4460, "description": "Cohiba Churchill", "size": "7-49",
"origin": "Dominican Republic", "wrapper": "Sungrown", "shape": "Straight"
}, {
"wishId": 4461, "description": "Gurkha Legend Torpedo", "size": "6 3/4-53",
"origin": "Honduras", "wrapper": "Colorado Maduro", "shape": "Straight"
}, {
"wishId": 4462, "description": "Cohiba Black Supremo", "size": "6-54",
"origin": "Dominican Republic", "wrapper": "Sungrown", "shape": "Straight"
}, {
"wishId": 4463, "description": "La Flor Dominicana Ligero Mysterio", "size": "6 1/8-54",
"origin": "Dominican Republic", "wrapper": "Natural", "shape": "Perfecto"
}, {
"wishId": 4464, "description": "Camacho Triple Maduro Torpedo", "size": "6-54",
"origin": "Honduras", "wrapper": "Cameroon", "shape": "Torpedo"
}
]
}

343
src/main/webapp/src.js Normal file
View File

@ -0,0 +1,343 @@
require([
"require",
"dojo/_base/array",
"dojo/_base/config",
"dojo/dom",
"dojo/dom-class",
"dojo/dom-construct",
"dojo/_base/kernel",
"dojo/query",
"dojo/ready",
"dojo/_base/window",
"dojo/_base/fx",
"dijit/registry",
"dijit/MenuItem",
"dojo/date/locale",
"dojo/parser",
"dojo/data/ItemFileReadStore",
"dijit/tree/ForestStoreModel",
"dojo/number", // dojo.number.format
"dojo/dnd/Source", // dojo.dnd.Source
"dojo/_base/json", // dojo.toJson
"dijit/dijit-all" // dijit.*
], function(require, array, config, dom, domClass, domConstruct, kernel, query, ready, win, fx, registry, MenuItem, locale, parser, ItemFileReadStore, ForestStoreModel){
continentStore = new ItemFileReadStore({ data: {
identifier: 'id',
label: 'name',
items: [
{ id: 'AF', name:'Africa', type:'continent', population:'900 million', area: '30,221,532 sq km',
timezone: '-1 UTC to +4 UTC',
children:[{_reference:'EG'}, {_reference:'KE'}, {_reference:'SD'}] },
{ id: 'EG', name:'Egypt', type:'country' },
{ id: 'KE', name:'Kenya', type:'country',
children:[{_reference:'Nairobi'}, {_reference:'Mombasa'}] },
{ id: 'Nairobi', name:'Nairobi', type:'city' },
{ id: 'Mombasa', name:'Mombasa', type:'city' },
{ id: 'SD', name:'Sudan', type:'country',
children:{_reference:'Khartoum'} },
{ id: 'Khartoum', name:'Khartoum', type:'city' },
{ id: 'AS', name:'Asia', type:'continent',
children:[{_reference:'CN'}, {_reference:'IN'}, {_reference:'RU'}, {_reference:'MN'}] },
{ id: 'CN', name:'China', type:'country' },
{ id: 'IN', name:'India', type:'country' },
{ id: 'RU', name:'Russia', type:'country' },
{ id: 'MN', name:'Mongolia', type:'country' },
{ id: 'OC', name:'Oceania', type:'continent', population:'21 million',
children:{_reference:'AU'}},
{ id: 'AU', name:'Australia', type:'country', population:'21 million'},
{ id: 'EU', name:'Europe', type:'continent',
children:[{_reference:'DE'}, {_reference:'FR'}, {_reference:'ES'}, {_reference:'IT'}] },
{ id: 'DE', name:'Germany', type:'country' },
{ id: 'FR', name:'France', type:'country' },
{ id: 'ES', name:'Spain', type:'country' },
{ id: 'IT', name:'Italy', type:'country' },
{ id: 'NA', name:'North America', type:'continent',
children:[{_reference:'MX'}, {_reference:'CA'}, {_reference:'US'}] },
{ id: 'MX', name:'Mexico', type:'country', population:'108 million', area:'1,972,550 sq km',
children:[{_reference:'Mexico City'}, {_reference:'Guadalajara'}] },
{ id: 'Mexico City', name:'Mexico City', type:'city', population:'19 million', timezone:'-6 UTC'},
{ id: 'Guadalajara', name:'Guadalajara', type:'city', population:'4 million', timezone:'-6 UTC' },
{ id: 'CA', name:'Canada', type:'country', population:'33 million', area:'9,984,670 sq km',
children:[{_reference:'Ottawa'}, {_reference:'Toronto'}] },
{ id: 'Ottawa', name:'Ottawa', type:'city', population:'0.9 million', timezone:'-5 UTC'},
{ id: 'Toronto', name:'Toronto', type:'city', population:'2.5 million', timezone:'-5 UTC' },
{ id: 'US', name:'United States of America', type:'country' },
{ id: 'SA', name:'South America', type:'continent',
children:[{_reference:'BR'}, {_reference:'AR'}] },
{ id: 'BR', name:'Brazil', type:'country', population:'186 million' },
{ id: 'AR', name:'Argentina', type:'country', population:'40 million' }
]
}});
stateStore = new ItemFileReadStore({ data: {
identifier:"abbreviation",
label: "name",
items: [
{name:"Alabama", label:"<img width='97px' height='127px' src='images/Alabama.jpg'/>Alabama",abbreviation:"AL"},
{name:"Alaska", label:"Alaska",abbreviation:"AK"},
{name:"American Samoa", label:"American Samoa",abbreviation:"AS"},
{name:"Arizona", label:"Arizona",abbreviation:"AZ"},
{name:"Arkansas", label:"Arkansas",abbreviation:"AR"},
{name:"Armed Forces Europe", label:"Armed Forces Europe",abbreviation:"AE"},
{name:"Armed Forces Pacific", label:"Armed Forces Pacific",abbreviation:"AP"},
{name:"Armed Forces the Americas", label:"Armed Forces the Americas",abbreviation:"AA"},
{name:"California", label:"California",abbreviation:"CA"},
{name:"Colorado", label:"Colorado",abbreviation:"CO"},
{name:"Connecticut", label:"Connecticut",abbreviation:"CT"},
{name:"Delaware", label:"Delaware",abbreviation:"DE"},
{name:"District of Columbia", label:"District of Columbia",abbreviation:"DC"},
{name:"Federated States of Micronesia", label:"Federated States of Micronesia",abbreviation:"FM"},
{name:"Florida", label:"Florida",abbreviation:"FL"},
{name:"Georgia", label:"Georgia",abbreviation:"GA"},
{name:"Guam", label:"Guam",abbreviation:"GU"},
{name:"Hawaii", label:"Hawaii",abbreviation:"HI"},
{name:"Idaho", label:"Idaho",abbreviation:"ID"},
{name:"Illinois", label:"Illinois",abbreviation:"IL"},
{name:"Indiana", label:"Indiana",abbreviation:"IN"},
{name:"Iowa", label:"Iowa",abbreviation:"IA"},
{name:"Kansas", label:"Kansas",abbreviation:"KS"},
{name:"Kentucky", label:"Kentucky",abbreviation:"KY"},
{name:"Louisiana", label:"Louisiana",abbreviation:"LA"},
{name:"Maine", label:"Maine",abbreviation:"ME"},
{name:"Marshall Islands", label:"Marshall Islands",abbreviation:"MH"},
{name:"Maryland", label:"Maryland",abbreviation:"MD"},
{name:"Massachusetts", label:"Massachusetts",abbreviation:"MA"},
{name:"Michigan", label:"Michigan",abbreviation:"MI"},
{name:"Minnesota", label:"Minnesota",abbreviation:"MN"},
{name:"Mississippi", label:"Mississippi",abbreviation:"MS"},
{name:"Missouri", label:"Missouri",abbreviation:"MO"},
{name:"Montana", label:"Montana",abbreviation:"MT"},
{name:"Nebraska", label:"Nebraska",abbreviation:"NE"},
{name:"Nevada", label:"Nevada",abbreviation:"NV"},
{name:"New Hampshire", label:"New Hampshire",abbreviation:"NH"},
{name:"New Jersey", label:"New Jersey",abbreviation:"NJ"},
{name:"New Mexico", label:"New Mexico",abbreviation:"NM"},
{name:"New York", label:"New York",abbreviation:"NY"},
{name:"North Carolina", label:"North Carolina",abbreviation:"NC"},
{name:"North Dakota", label:"North Dakota",abbreviation:"ND"},
{name:"Northern Mariana Islands", label:"Northern Mariana Islands",abbreviation:"MP"},
{name:"Ohio", label:"Ohio",abbreviation:"OH"},
{name:"Oklahoma", label:"Oklahoma",abbreviation:"OK"},
{name:"Oregon", label:"Oregon",abbreviation:"OR"},
{name:"Pennsylvania", label:"Pennsylvania",abbreviation:"PA"},
{name:"Puerto Rico", label:"Puerto Rico",abbreviation:"PR"},
{name:"Rhode Island", label:"Rhode Island",abbreviation:"RI"},
{name:"South Carolina", label:"South Carolina",abbreviation:"SC"},
{name:"South Dakota", label:"South Dakota",abbreviation:"SD"},
{name:"Tennessee", label:"Tennessee",abbreviation:"TN"},
{name:"Texas", label:"Texas",abbreviation:"TX"},
{name:"Utah", label:"Utah",abbreviation:"UT"},
{name:"Vermont", label:"Vermont",abbreviation:"VT"},
{name: "Virgin Islands, U.S.",label:"Virgin Islands, U.S.",abbreviation:"VI"},
{name:"Virginia", label:"Virginia",abbreviation:"VA"},
{name:"Washington", label:"Washington",abbreviation:"WA"},
{name:"West Virginia", label:"West Virginia",abbreviation:"WV"},
{name:"Wisconsin", label:"Wisconsin",abbreviation:"WI"},
{name:"Wyoming", label:"Wyoming",abbreviation:"WY"}
]
}});
continentModel = new ForestStoreModel({store:continentStore, query:{type:"continent"},rootId:"continentRoot", rootLabel:"Continents", childrenAttrs:["children"]});
showDialog = function(){
var dlg = registry.byId('dialog1');
dlg.show();
// avoid (trying to) restore focus to a closed menu, go to MenuBar instead
dlg._savedFocus = dom.byId("header");
};
showDialogAb = function(){
var dlg = registry.byId('dialogAB');
dlg.show();
// avoid (trying to) restore focus to a closed menu, go to MenuBar instead
dlg._savedFocus = dom.byId("header");
};
// current setting (if there is one) to override theme default padding on TextBox based widgets
var currentInputPadding = "";
setTextBoxPadding = function(){
// summary:
// Handler for when a MenuItem is clicked to set non-default padding for
// TextBox widgets
// Effectively ignore clicks on the currently checked MenuItem
if(!this.get("checked")){
this.set("checked", true);
}
// val will be "theme default", "0px", "1px", ..., "5px"
var val = this.get("label");
// Set class on body to get requested padding, and remove any previously set class
if(currentInputPadding){
domClass.remove(win.body(), currentInputPadding);
currentInputPadding = "";
}
if(val != "theme default"){
currentInputPadding = "inputPadding" + val.replace("px", "");
domClass.add(win.body(), currentInputPadding);
}
// Clear previously checked MenuItem (radio-button effect).
array.forEach(this.getParent().getChildren(), function(mi){
if(mi != this){
mi.set("checked", false);
}
}, this);
};
ready(function(){
// Delay parsing until the dynamically injected theme <link>'s have had time to finish loading
setTimeout(function(){
parser.parse(dom.byId('container'));
dom.byId('loaderInner').innerHTML += " done.";
setTimeout(function hideLoader(){
fx.fadeOut({
node: 'loader',
duration:500,
onEnd: function(n){
n.style.display = "none";
}
}).play();
}, 250);
// Fill in menu/links to get to other themes.
// availableThemes[] is just a list of 'official' dijit themes, you can use ?theme=String
// for 'un-supported' themes, too. (eg: yours)
var availableThemes = [
{ theme:"claro", author:"Dojo", baseUri:"static/dojolib/dijit/themes/" },
{ theme:"tundra", author:"Dojo", baseUri:"static/dojolib/dijit/themes/" },
{ theme:"soria", author:"nikolai", baseUri:"static/dojolib/dijit/themes/" },
{ theme:"nihilo", author:"nikolai", baseUri:"static/dojolib/dijit/themes/" }
];
var tmpString='';
array.forEach(availableThemes,function(theme){
tmpString +=
'<a href="?theme='+theme.theme+'">'+theme.theme+'</'+'a> (' +
'<a href="?theme='+theme.theme+'&dir=rtl">RTL</'+'a> ' +
'<a href="?theme='+theme.theme+'&a11y=true">high-contrast</'+'a> ' +
'<a href="?theme='+theme.theme+'&dir=rtl&a11y=true">RTL+high-contrast</'+'a> )' +
' - by: '+theme.author+' <br>';
registry.byId('themeMenu').addChild(new MenuItem({
label: theme.theme,
onClick: function(){ location.search = "?theme=" + theme.theme; }
}))
});
dom.byId('themeData').innerHTML = tmpString;
// It's the server's responsibility to localize the date displayed in the (non-edit) version of an InlineEditBox,
// but since we don't have a server we'll hack it in the client
registry.byId("backgroundArea").set('value', locale.format(new Date(2005, 11, 30), { selector: 'date' }));
var nineAm = new Date(0);
nineAm.setHours(9);
registry.byId("timePicker").set('value', locale.format(nineAm, { selector: 'time' }));
}, 320);
});
// you should NOT be using this in a production environment. include
// your css and set your classes manually. for test purposes only ...
var dir = "",
theme = false,
themeModule = "dijit",
testMode = null,
defTheme = "claro",
vars={};
if(window.location.href.indexOf("?") > -1){
var str = window.location.href.substr(window.location.href.indexOf("?")+1).split(/#/);
var ary = str[0].split(/&/);
for(var i=0; i<ary.length; i++){
var split = ary[i].split("="),
key = split[0],
value = (split[1]||'').replace(/[^\w]/g, ""); // replace() to prevent XSS attack
switch(key){
case "locale":
// locale string | null
kernel.locale = config.locale = locale = value;
break;
case "dir":
// rtl | null
document.getElementsByTagName("html")[0].dir = value;
dir = value;
break;
case "theme":
// tundra | soria | nihilo | claro | null
theme = value;
break;
case "a11y":
if(value){ testMode = "dijit_a11y"; }
break;
case "themeModule":
// moduleName | null
if(value){ themeModule = value; }
}
vars[key] = value;
}
}
kernel._getVar = function(k, def){ // TODO: not sure what this is
return vars[k] || def;
};
// BIDI
if(dir == "rtl"){
ready(0, function(){
// pretend all the labels are in an RTL language, because
// that affects how they lay out relative to inline form widgets
query("label").attr("dir", "rtl");
});
}
// a11y
if(testMode){
ready(0, function(){
var b = win.body();
if(testMode){
domClass.add(b, testMode);
}
});
}
// If URL specifies a non-claro theme then pull in those theme CSS files and modify
// <body> to point to that new theme instead of claro.
//
// Also defer parsing and any dojo.ready() calls that the test file makes
// until the CSS has finished loading.
if(theme){
// Wait until JS modules have finished loading so this doesn't confuse
// AMD loader.
ready(1, function(){
// Reset <body> to point to the specified theme
var b = win.body();
domClass.replace(b, theme, defTheme);
// Remove claro CSS
query('link[href$="claro.css"]').orphan();
query('link[href$="claro/document.css"]').orphan();
// Load theme CSS.
// Eventually would like to use [something like]
// https://github.com/unscriptable/curl/blob/master/src/curl/plugin/css.js
// to load the CSS and then know exactly when it finishes loading.
var modules = [
require.toUrl(themeModule+"/themes/"+theme+"/"+theme+".css"),
require.toUrl(themeModule+"/themes/"+theme+"/"+theme+"_rtl.css"),
require.toUrl("static/dojolib/dojo/resources/dojo.css")
];
var head = query("head")[0];
array.forEach(modules, function(css){
if(document.createStyleSheet){
// For IE
document.createStyleSheet(css);
}else{
// For other browsers
domConstruct.place('<link rel="stylesheet" type="text/css" href="'+css+'"/>',
head);
}
});
});
}
});

View File

@ -0,0 +1,81 @@
h1.testTitle {
font-size:2em;
margin:0 0 1em 0;
}
html, body {
height: 100%;
width: 100%;
padding: 0;
border: 0;
}
#main {
height: 100%;
width: 100%;
border: 0;
}
#header {
margin: 0;
}
#leftAccordion {
width: 25%;
}
#bottomTabs {
height: 40%;
}
#hs-1width {
width:400px;
height:40px;
}
/* pre-loader specific stuff to prevent unsightly flash of unstyled content */
#loader {
padding:0;
margin:0;
position:absolute;
top:0; left:0;
width:100%; height:100%;
background:#ededed;
z-index:999;
vertical-align:middle;
}
#loaderInner {
padding:5px;
position:relative;
left:0;
top:0;
width:175px;
background:#3c3;
color:#fff;
}
#indTestBar,
#setTestBar {
width:400px;
}
hr.spacer {
border:0;
background-color:#ededed;
width:80%;
height:1px;
}
/* rules used to test custom setting of TextBox padding */
.inputPadding0 .dijitInputField {
padding: 0 !important;
}
.inputPadding1 .dijitInputField {
padding: 1px !important;
}
.inputPadding2 .dijitInputField {
padding: 2px !important;
}
.inputPadding3 .dijitInputField {
padding: 3px !important;
}
.inputPadding4 .dijitInputField {
padding: 4px !important;
}
.inputPadding5 .dijitInputField {
padding: 5px !important;
}

View File

@ -0,0 +1,25 @@
8
dir
7131
svn://133.133.133.108/mapreducegroup/lili/springDemo/src/main/webapp/static/dojolib
svn://133.133.133.108
2013-04-15T01:59:24.008611Z
7131
liqiyuan
svn:special svn:externals svn:needs-lock
dijit
dir
dojox
dir
dojo
dir

View File

@ -0,0 +1 @@
8

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
8

View File

@ -0,0 +1,63 @@
//>>built
define("dijit/BackgroundIframe",["require","./main","dojo/_base/config","dojo/dom-construct","dojo/dom-style","dojo/_base/lang","dojo/on","dojo/sniff","dojo/_base/window"],function(_1,_2,_3,_4,_5,_6,on,_7,_8){
var _9=new function(){
var _a=[];
this.pop=function(){
var _b;
if(_a.length){
_b=_a.pop();
_b.style.display="";
}else{
if(_7("ie")<9){
var _c=_3["dojoBlankHtmlUrl"]||_1.toUrl("dojo/resources/blank.html")||"javascript:\"\"";
var _d="<iframe src='"+_c+"' role='presentation'"+" style='position: absolute; left: 0px; top: 0px;"+"z-index: -1; filter:Alpha(Opacity=\"0\");'>";
_b=_8.doc.createElement(_d);
}else{
_b=_4.create("iframe");
_b.src="javascript:\"\"";
_b.className="dijitBackgroundIframe";
_b.setAttribute("role","presentation");
_5.set(_b,"opacity",0.1);
}
_b.tabIndex=-1;
}
return _b;
};
this.push=function(_e){
_e.style.display="none";
_a.push(_e);
};
}();
_2.BackgroundIframe=function(_f){
if(!_f.id){
throw new Error("no id");
}
if(_7("ie")||_7("mozilla")){
var _10=(this.iframe=_9.pop());
_f.appendChild(_10);
if(_7("ie")<7||_7("quirks")){
this.resize(_f);
this._conn=on(_f,"resize",_6.hitch(this,function(){
this.resize(_f);
}));
}else{
_5.set(_10,{width:"100%",height:"100%"});
}
}
};
_6.extend(_2.BackgroundIframe,{resize:function(_11){
if(this.iframe){
_5.set(this.iframe,{width:_11.offsetWidth+"px",height:_11.offsetHeight+"px"});
}
},destroy:function(){
if(this._conn){
this._conn.remove();
this._conn=null;
}
if(this.iframe){
_9.push(this.iframe);
delete this.iframe;
}
}});
return _2.BackgroundIframe;
});

View File

@ -0,0 +1,110 @@
define("dijit/BackgroundIframe", [
"require", // require.toUrl
"./main", // to export dijit.BackgroundIframe
"dojo/_base/config",
"dojo/dom-construct", // domConstruct.create
"dojo/dom-style", // domStyle.set
"dojo/_base/lang", // lang.extend lang.hitch
"dojo/on",
"dojo/sniff", // has("ie"), has("mozilla"), has("quirks")
"dojo/_base/window" // win.doc.createElement
], function(require, dijit, config, domConstruct, domStyle, lang, on, has, win){
// module:
// dijit/BackgroundIFrame
// TODO: remove _frames, it isn't being used much, since popups never release their
// iframes (see [22236])
var _frames = new function(){
// summary:
// cache of iframes
var queue = [];
this.pop = function(){
var iframe;
if(queue.length){
iframe = queue.pop();
iframe.style.display="";
}else{
if(has("ie") < 9){
var burl = config["dojoBlankHtmlUrl"] || require.toUrl("dojo/resources/blank.html") || "javascript:\"\"";
var html="<iframe src='" + burl + "' role='presentation'"
+ " style='position: absolute; left: 0px; top: 0px;"
+ "z-index: -1; filter:Alpha(Opacity=\"0\");'>";
iframe = win.doc.createElement(html);
}else{
iframe = domConstruct.create("iframe");
iframe.src = 'javascript:""';
iframe.className = "dijitBackgroundIframe";
iframe.setAttribute("role", "presentation");
domStyle.set(iframe, "opacity", 0.1);
}
iframe.tabIndex = -1; // Magic to prevent iframe from getting focus on tab keypress - as style didn't work.
}
return iframe;
};
this.push = function(iframe){
iframe.style.display="none";
queue.push(iframe);
}
}();
dijit.BackgroundIframe = function(/*DomNode*/ node){
// summary:
// For IE/FF z-index schenanigans. id attribute is required.
//
// description:
// new dijit.BackgroundIframe(node).
//
// Makes a background iframe as a child of node, that fills
// area (and position) of node
if(!node.id){ throw new Error("no id"); }
if(has("ie") || has("mozilla")){
var iframe = (this.iframe = _frames.pop());
node.appendChild(iframe);
if(has("ie")<7 || has("quirks")){
this.resize(node);
this._conn = on(node, 'resize', lang.hitch(this, function(){
this.resize(node);
}));
}else{
domStyle.set(iframe, {
width: '100%',
height: '100%'
});
}
}
};
lang.extend(dijit.BackgroundIframe, {
resize: function(node){
// summary:
// Resize the iframe so it's the same size as node.
// Needed on IE6 and IE/quirks because height:100% doesn't work right.
if(this.iframe){
domStyle.set(this.iframe, {
width: node.offsetWidth + 'px',
height: node.offsetHeight + 'px'
});
}
},
destroy: function(){
// summary:
// destroy the iframe
if(this._conn){
this._conn.remove();
this._conn = null;
}
if(this.iframe){
_frames.push(this.iframe);
delete this.iframe;
}
}
});
return dijit.BackgroundIframe;
});

View File

@ -0,0 +1,122 @@
//>>built
define("dijit/Calendar",["dojo/_base/array","dojo/date","dojo/date/locale","dojo/_base/declare","dojo/dom-attr","dojo/dom-class","dojo/_base/event","dojo/_base/kernel","dojo/keys","dojo/_base/lang","dojo/sniff","./CalendarLite","./_Widget","./_CssStateMixin","./_TemplatedMixin","./form/DropDownButton"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c,_d,_e,_f,_10){
var _11=_4("dijit.Calendar",[_c,_d,_e],{cssStateNodes:{"decrementMonth":"dijitCalendarArrow","incrementMonth":"dijitCalendarArrow","previousYearLabelNode":"dijitCalendarPreviousYear","nextYearLabelNode":"dijitCalendarNextYear"},setValue:function(_12){
_8.deprecated("dijit.Calendar:setValue() is deprecated. Use set('value', ...) instead.","","2.0");
this.set("value",_12);
},_createMonthWidget:function(){
return new _11._MonthDropDownButton({id:this.id+"_mddb",tabIndex:-1,onMonthSelect:_a.hitch(this,"_onMonthSelect"),lang:this.lang,dateLocaleModule:this.dateLocaleModule},this.monthNode);
},postCreate:function(){
this.inherited(arguments);
this.connect(this.domNode,"onkeydown","_onKeyDown");
this.connect(this.dateRowsNode,"onmouseover","_onDayMouseOver");
this.connect(this.dateRowsNode,"onmouseout","_onDayMouseOut");
this.connect(this.dateRowsNode,"onmousedown","_onDayMouseDown");
this.connect(this.dateRowsNode,"onmouseup","_onDayMouseUp");
},_onMonthSelect:function(_13){
var _14=new this.dateClassObj(this.currentFocus);
_14.setDate(1);
_14.setMonth(_13);
var _15=this.dateModule.getDaysInMonth(_14);
var _16=this.currentFocus.getDate();
_14.setDate(Math.min(_16,_15));
this._setCurrentFocusAttr(_14);
},_onDayMouseOver:function(evt){
var _17=_6.contains(evt.target,"dijitCalendarDateLabel")?evt.target.parentNode:evt.target;
if(_17&&((_17.dijitDateValue&&!_6.contains(_17,"dijitCalendarDisabledDate"))||_17==this.previousYearLabelNode||_17==this.nextYearLabelNode)){
_6.add(_17,"dijitCalendarHoveredDate");
this._currentNode=_17;
}
},_onDayMouseOut:function(evt){
if(!this._currentNode){
return;
}
if(evt.relatedTarget&&evt.relatedTarget.parentNode==this._currentNode){
return;
}
var cls="dijitCalendarHoveredDate";
if(_6.contains(this._currentNode,"dijitCalendarActiveDate")){
cls+=" dijitCalendarActiveDate";
}
_6.remove(this._currentNode,cls);
this._currentNode=null;
},_onDayMouseDown:function(evt){
var _18=evt.target.parentNode;
if(_18&&_18.dijitDateValue&&!_6.contains(_18,"dijitCalendarDisabledDate")){
_6.add(_18,"dijitCalendarActiveDate");
this._currentNode=_18;
}
},_onDayMouseUp:function(evt){
var _19=evt.target.parentNode;
if(_19&&_19.dijitDateValue){
_6.remove(_19,"dijitCalendarActiveDate");
}
},handleKey:function(evt){
var _1a=-1,_1b,_1c=this.currentFocus;
switch(evt.keyCode){
case _9.RIGHT_ARROW:
_1a=1;
case _9.LEFT_ARROW:
_1b="day";
if(!this.isLeftToRight()){
_1a*=-1;
}
break;
case _9.DOWN_ARROW:
_1a=1;
case _9.UP_ARROW:
_1b="week";
break;
case _9.PAGE_DOWN:
_1a=1;
case _9.PAGE_UP:
_1b=evt.ctrlKey||evt.altKey?"year":"month";
break;
case _9.END:
_1c=this.dateModule.add(_1c,"month",1);
_1b="day";
case _9.HOME:
_1c=new this.dateClassObj(_1c);
_1c.setDate(1);
break;
case _9.ENTER:
case _9.SPACE:
this.set("value",this.currentFocus);
break;
default:
return true;
}
if(_1b){
_1c=this.dateModule.add(_1c,_1b,_1a);
}
this._setCurrentFocusAttr(_1c);
return false;
},_onKeyDown:function(evt){
if(!this.handleKey(evt)){
_7.stop(evt);
}
},onValueSelected:function(){
},onChange:function(_1d){
this.onValueSelected(_1d);
},getClassForDate:function(){
}});
_11._MonthDropDownButton=_4("dijit.Calendar._MonthDropDownButton",_10,{onMonthSelect:function(){
},postCreate:function(){
this.inherited(arguments);
this.dropDown=new _11._MonthDropDown({id:this.id+"_mdd",onChange:this.onMonthSelect});
},_setMonthAttr:function(_1e){
var _1f=this.dateLocaleModule.getNames("months","wide","standAlone",this.lang,_1e);
this.dropDown.set("months",_1f);
this.containerNode.innerHTML=(_b("ie")==6?"":"<div class='dijitSpacer'>"+this.dropDown.domNode.innerHTML+"</div>")+"<div class='dijitCalendarMonthLabel dijitCalendarCurrentMonthLabel'>"+_1f[_1e.getMonth()]+"</div>";
}});
_11._MonthDropDown=_4("dijit.Calendar._MonthDropDown",[_d,_f],{months:[],templateString:"<div class='dijitCalendarMonthMenu dijitMenu' "+"data-dojo-attach-event='onclick:_onClick,onmouseover:_onMenuHover,onmouseout:_onMenuHover'></div>",_setMonthsAttr:function(_20){
this.domNode.innerHTML=_1.map(_20,function(_21,idx){
return _21?"<div class='dijitCalendarMonthLabel' month='"+idx+"'>"+_21+"</div>":"";
}).join("");
},_onClick:function(evt){
this.onChange(_5.get(evt.target,"month"));
},onChange:function(){
},_onMenuHover:function(evt){
_6.toggle(evt.target,"dijitCalendarMonthLabelHover",evt.type=="mouseover");
}});
return _11;
});

View File

@ -0,0 +1,312 @@
define("dijit/Calendar", [
"dojo/_base/array", // array.map
"dojo/date",
"dojo/date/locale",
"dojo/_base/declare", // declare
"dojo/dom-attr", // domAttr.get
"dojo/dom-class", // domClass.add domClass.contains domClass.remove domClass.toggle
"dojo/_base/event", // event.stop
"dojo/_base/kernel", // kernel.deprecated
"dojo/keys", // keys
"dojo/_base/lang", // lang.hitch
"dojo/sniff", // has("ie")
"./CalendarLite",
"./_Widget",
"./_CssStateMixin",
"./_TemplatedMixin",
"./form/DropDownButton"
], function(array, date, local, declare, domAttr, domClass, event, kernel, keys, lang, has,
CalendarLite, _Widget, _CssStateMixin, _TemplatedMixin, DropDownButton){
// module:
// dijit/Calendar
var Calendar = declare("dijit.Calendar",
[CalendarLite, _Widget, _CssStateMixin], // _Widget for deprecated methods like setAttribute()
{
// summary:
// A simple GUI for choosing a date in the context of a monthly calendar.
//
// description:
// See CalendarLite for general description. Calendar extends CalendarLite, adding:
//
// - month drop down list
// - keyboard navigation
// - CSS classes for hover/mousepress on date, month, and year nodes
// - support of deprecated methods (will be removed in 2.0)
// Set node classes for various mouse events, see dijit._CssStateMixin for more details
cssStateNodes: {
"decrementMonth": "dijitCalendarArrow",
"incrementMonth": "dijitCalendarArrow",
"previousYearLabelNode": "dijitCalendarPreviousYear",
"nextYearLabelNode": "dijitCalendarNextYear"
},
setValue: function(/*Date*/ value){
// summary:
// Deprecated. Use set('value', ...) instead.
// tags:
// deprecated
kernel.deprecated("dijit.Calendar:setValue() is deprecated. Use set('value', ...) instead.", "", "2.0");
this.set('value', value);
},
_createMonthWidget: function(){
// summary:
// Creates the drop down button that displays the current month and lets user pick a new one
return new Calendar._MonthDropDownButton({
id: this.id + "_mddb",
tabIndex: -1,
onMonthSelect: lang.hitch(this, "_onMonthSelect"),
lang: this.lang,
dateLocaleModule: this.dateLocaleModule
}, this.monthNode);
},
postCreate: function(){
this.inherited(arguments);
// Events specific to Calendar, not used in CalendarLite
this.connect(this.domNode, "onkeydown", "_onKeyDown");
this.connect(this.dateRowsNode, "onmouseover", "_onDayMouseOver");
this.connect(this.dateRowsNode, "onmouseout", "_onDayMouseOut");
this.connect(this.dateRowsNode, "onmousedown", "_onDayMouseDown");
this.connect(this.dateRowsNode, "onmouseup", "_onDayMouseUp");
},
_onMonthSelect: function(/*Number*/ newMonth){
// summary:
// Handler for when user selects a month from the drop down list
// tags:
// protected
// move to selected month, bounding by the number of days in the month
// (ex: jan 31 --> feb 28, not feb 31)
var date = new this.dateClassObj(this.currentFocus);
date.setDate(1);
date.setMonth(newMonth);
var daysInMonth = this.dateModule.getDaysInMonth(date);
var currentDate = this.currentFocus.getDate();
date.setDate(Math.min(currentDate, daysInMonth));
this._setCurrentFocusAttr(date);
},
_onDayMouseOver: function(/*Event*/ evt){
// summary:
// Handler for mouse over events on days, sets hovered style
// tags:
// protected
// event can occur on <td> or the <span> inside the td,
// set node to the <td>.
var node =
domClass.contains(evt.target, "dijitCalendarDateLabel") ?
evt.target.parentNode :
evt.target;
if(node && (
(node.dijitDateValue && !domClass.contains(node, "dijitCalendarDisabledDate"))
|| node == this.previousYearLabelNode || node == this.nextYearLabelNode
)){
domClass.add(node, "dijitCalendarHoveredDate");
this._currentNode = node;
}
},
_onDayMouseOut: function(/*Event*/ evt){
// summary:
// Handler for mouse out events on days, clears hovered style
// tags:
// protected
if(!this._currentNode){ return; }
// if mouse out occurs moving from <td> to <span> inside <td>, ignore it
if(evt.relatedTarget && evt.relatedTarget.parentNode == this._currentNode){ return; }
var cls = "dijitCalendarHoveredDate";
if(domClass.contains(this._currentNode, "dijitCalendarActiveDate")){
cls += " dijitCalendarActiveDate";
}
domClass.remove(this._currentNode, cls);
this._currentNode = null;
},
_onDayMouseDown: function(/*Event*/ evt){
var node = evt.target.parentNode;
if(node && node.dijitDateValue && !domClass.contains(node, "dijitCalendarDisabledDate")){
domClass.add(node, "dijitCalendarActiveDate");
this._currentNode = node;
}
},
_onDayMouseUp: function(/*Event*/ evt){
var node = evt.target.parentNode;
if(node && node.dijitDateValue){
domClass.remove(node, "dijitCalendarActiveDate");
}
},
handleKey: function(/*Event*/ evt){
// summary:
// Provides keyboard navigation of calendar.
// description:
// Called from _onKeyDown() to handle keypress on a stand alone Calendar,
// and also from `dijit/form/_DateTimeTextBox` to pass a keydown event
// from the `dijit/form/DateTextBox` to be handled in this widget
// returns:
// False if the key was recognized as a navigation key,
// to indicate that the event was handled by Calendar and shouldn't be propagated
// tags:
// protected
var increment = -1,
interval,
newValue = this.currentFocus;
switch(evt.keyCode){
case keys.RIGHT_ARROW:
increment = 1;
//fallthrough...
case keys.LEFT_ARROW:
interval = "day";
if(!this.isLeftToRight()){ increment *= -1; }
break;
case keys.DOWN_ARROW:
increment = 1;
//fallthrough...
case keys.UP_ARROW:
interval = "week";
break;
case keys.PAGE_DOWN:
increment = 1;
//fallthrough...
case keys.PAGE_UP:
interval = evt.ctrlKey || evt.altKey ? "year" : "month";
break;
case keys.END:
// go to the next month
newValue = this.dateModule.add(newValue, "month", 1);
// subtract a day from the result when we're done
interval = "day";
//fallthrough...
case keys.HOME:
newValue = new this.dateClassObj(newValue);
newValue.setDate(1);
break;
case keys.ENTER:
case keys.SPACE:
this.set("value", this.currentFocus);
break;
default:
return true;
}
if(interval){
newValue = this.dateModule.add(newValue, interval, increment);
}
this._setCurrentFocusAttr(newValue);
return false;
},
_onKeyDown: function(/*Event*/ evt){
// summary:
// For handling keypress events on a stand alone calendar
if(!this.handleKey(evt)){
event.stop(evt);
}
},
onValueSelected: function(/*Date*/ /*===== date =====*/){
// summary:
// Deprecated. Notification that a date cell was selected. It may be the same as the previous value.
// description:
// Formerly used by `dijit/form/_DateTimeTextBox` (and thus `dijit/form/DateTextBox`)
// to get notification when the user has clicked a date. Now onExecute() (above) is used.
// tags:
// protected
},
onChange: function(value){
this.onValueSelected(value); // remove in 2.0
},
getClassForDate: function(/*===== dateObject, locale =====*/){
// summary:
// May be overridden to return CSS classes to associate with the date entry for the given dateObject,
// for example to indicate a holiday in specified locale.
// dateObject: Date
// locale: String?
// tags:
// extension
/*=====
return ""; // String
=====*/
}
});
Calendar._MonthDropDownButton = declare("dijit.Calendar._MonthDropDownButton", DropDownButton, {
// summary:
// DropDownButton for the current month. Displays name of current month
// and a list of month names in the drop down
onMonthSelect: function(){ },
postCreate: function(){
this.inherited(arguments);
this.dropDown = new Calendar._MonthDropDown({
id: this.id + "_mdd", //do not change this id because it is referenced in the template
onChange: this.onMonthSelect
});
},
_setMonthAttr: function(month){
// summary:
// Set the current month to display as a label
var monthNames = this.dateLocaleModule.getNames('months', 'wide', 'standAlone', this.lang, month);
this.dropDown.set("months", monthNames);
// Set name of current month and also fill in spacer element with all the month names
// (invisible) so that the maximum width will affect layout. But not on IE6 because then
// the center <TH> overlaps the right <TH> (due to a browser bug).
this.containerNode.innerHTML =
(has("ie") == 6 ? "" : "<div class='dijitSpacer'>" + this.dropDown.domNode.innerHTML + "</div>") +
"<div class='dijitCalendarMonthLabel dijitCalendarCurrentMonthLabel'>" + monthNames[month.getMonth()] + "</div>";
}
});
Calendar._MonthDropDown = declare("dijit.Calendar._MonthDropDown", [_Widget, _TemplatedMixin], {
// summary:
// The list-of-months drop down from the MonthDropDownButton
// months: String[]
// List of names of months, possibly w/some undefined entries for Hebrew leap months
// (ex: ["January", "February", undefined, "April", ...])
months: [],
templateString: "<div class='dijitCalendarMonthMenu dijitMenu' " +
"data-dojo-attach-event='onclick:_onClick,onmouseover:_onMenuHover,onmouseout:_onMenuHover'></div>",
_setMonthsAttr: function(/*String[]*/ months){
this.domNode.innerHTML = array.map(months, function(month, idx){
return month ? "<div class='dijitCalendarMonthLabel' month='" + idx +"'>" + month + "</div>" : "";
}).join("");
},
_onClick: function(/*Event*/ evt){
this.onChange(domAttr.get(evt.target, "month"));
},
onChange: function(/*Number*/ /*===== month =====*/){
// summary:
// Callback when month is selected from drop down
},
_onMenuHover: function(evt){
domClass.toggle(evt.target, "dijitCalendarMonthLabelHover", evt.type == "mouseover");
}
});
return Calendar;
});

View File

@ -0,0 +1,193 @@
//>>built
require({cache:{"url:dijit/templates/Calendar.html":"<table cellspacing=\"0\" cellpadding=\"0\" class=\"dijitCalendarContainer\" role=\"grid\" aria-labelledby=\"${id}_mddb ${id}_year\">\n\t<thead>\n\t\t<tr class=\"dijitReset dijitCalendarMonthContainer\" valign=\"top\">\n\t\t\t<th class='dijitReset dijitCalendarArrow' data-dojo-attach-point=\"decrementMonth\">\n\t\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitCalendarIncrementControl dijitCalendarDecrease\" role=\"presentation\"/>\n\t\t\t\t<span data-dojo-attach-point=\"decreaseArrowNode\" class=\"dijitA11ySideArrow\">-</span>\n\t\t\t</th>\n\t\t\t<th class='dijitReset' colspan=\"5\">\n\t\t\t\t<div data-dojo-attach-point=\"monthNode\">\n\t\t\t\t</div>\n\t\t\t</th>\n\t\t\t<th class='dijitReset dijitCalendarArrow' data-dojo-attach-point=\"incrementMonth\">\n\t\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitCalendarIncrementControl dijitCalendarIncrease\" role=\"presentation\"/>\n\t\t\t\t<span data-dojo-attach-point=\"increaseArrowNode\" class=\"dijitA11ySideArrow\">+</span>\n\t\t\t</th>\n\t\t</tr>\n\t\t<tr role=\"row\">\n\t\t\t${!dayCellsHtml}\n\t\t</tr>\n\t</thead>\n\t<tbody data-dojo-attach-point=\"dateRowsNode\" data-dojo-attach-event=\"onclick: _onDayClick\" class=\"dijitReset dijitCalendarBodyContainer\">\n\t\t\t${!dateRowsHtml}\n\t</tbody>\n\t<tfoot class=\"dijitReset dijitCalendarYearContainer\">\n\t\t<tr>\n\t\t\t<td class='dijitReset' valign=\"top\" colspan=\"7\" role=\"presentation\">\n\t\t\t\t<div class=\"dijitCalendarYearLabel\">\n\t\t\t\t\t<span data-dojo-attach-point=\"previousYearLabelNode\" class=\"dijitInline dijitCalendarPreviousYear\" role=\"button\"></span>\n\t\t\t\t\t<span data-dojo-attach-point=\"currentYearLabelNode\" class=\"dijitInline dijitCalendarSelectedYear\" role=\"button\" id=\"${id}_year\"></span>\n\t\t\t\t\t<span data-dojo-attach-point=\"nextYearLabelNode\" class=\"dijitInline dijitCalendarNextYear\" role=\"button\"></span>\n\t\t\t\t</div>\n\t\t\t</td>\n\t\t</tr>\n\t</tfoot>\n</table>\n"}});
define("dijit/CalendarLite",["dojo/_base/array","dojo/_base/declare","dojo/cldr/supplemental","dojo/date","dojo/date/locale","dojo/date/stamp","dojo/dom","dojo/dom-class","dojo/_base/event","dojo/_base/lang","dojo/sniff","dojo/string","./_WidgetBase","./_TemplatedMixin","dojo/text!./templates/Calendar.html","./hccss"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c,_d,_e,_f){
var _10=_2("dijit.CalendarLite",[_d,_e],{templateString:_f,dowTemplateString:"<th class=\"dijitReset dijitCalendarDayLabelTemplate\" role=\"columnheader\"><span class=\"dijitCalendarDayLabel\">${d}</span></th>",dateTemplateString:"<td class=\"dijitReset\" role=\"gridcell\" data-dojo-attach-point=\"dateCells\"><span class=\"dijitCalendarDateLabel\" data-dojo-attach-point=\"dateLabels\"></span></td>",weekTemplateString:"<tr class=\"dijitReset dijitCalendarWeekTemplate\" role=\"row\">${d}${d}${d}${d}${d}${d}${d}</tr>",value:new Date(""),datePackage:"",dayWidth:"narrow",tabIndex:"0",currentFocus:new Date(),baseClass:"dijitCalendar",_isValidDate:function(_11){
return _11&&!isNaN(_11)&&typeof _11=="object"&&_11.toString()!=this.constructor.prototype.value.toString();
},_getValueAttr:function(){
if(this.value&&!isNaN(this.value)){
var _12=new this.dateClassObj(this.value);
_12.setHours(0,0,0,0);
if(_12.getDate()<this.value.getDate()){
_12=this.dateModule.add(_12,"hour",1);
}
return _12;
}else{
return null;
}
},_setValueAttr:function(_13,_14){
if(typeof _13=="string"){
_13=_6.fromISOString(_13);
}
_13=this._patchDate(_13);
if(this._isValidDate(_13)&&!this.isDisabledDate(_13,this.lang)){
this._set("value",_13);
this.set("currentFocus",_13);
this._markSelectedDates([_13]);
if(this._created&&(_14||typeof _14=="undefined")){
this.onChange(this.get("value"));
}
}else{
this._set("value",null);
this._markSelectedDates([]);
}
},_patchDate:function(_15){
if(_15){
_15=new this.dateClassObj(_15);
_15.setHours(1,0,0,0);
}
return _15;
},_setText:function(_16,_17){
while(_16.firstChild){
_16.removeChild(_16.firstChild);
}
_16.appendChild(_16.ownerDocument.createTextNode(_17));
},_populateGrid:function(){
var _18=new this.dateClassObj(this.currentFocus);
_18.setDate(1);
var _19=_18.getDay(),_1a=this.dateModule.getDaysInMonth(_18),_1b=this.dateModule.getDaysInMonth(this.dateModule.add(_18,"month",-1)),_1c=new this.dateClassObj(),_1d=_3.getFirstDayOfWeek(this.lang);
if(_1d>_19){
_1d-=7;
}
this._date2cell={};
_1.forEach(this.dateCells,function(_1e,idx){
var i=idx+_1d;
var _1f=new this.dateClassObj(_18),_20,_21="dijitCalendar",adj=0;
if(i<_19){
_20=_1b-_19+i+1;
adj=-1;
_21+="Previous";
}else{
if(i>=(_19+_1a)){
_20=i-_19-_1a+1;
adj=1;
_21+="Next";
}else{
_20=i-_19+1;
_21+="Current";
}
}
if(adj){
_1f=this.dateModule.add(_1f,"month",adj);
}
_1f.setDate(_20);
if(!this.dateModule.compare(_1f,_1c,"date")){
_21="dijitCalendarCurrentDate "+_21;
}
if(this.isDisabledDate(_1f,this.lang)){
_21="dijitCalendarDisabledDate "+_21;
_1e.setAttribute("aria-disabled","true");
}else{
_21="dijitCalendarEnabledDate "+_21;
_1e.removeAttribute("aria-disabled");
_1e.setAttribute("aria-selected","false");
}
var _22=this.getClassForDate(_1f,this.lang);
if(_22){
_21=_22+" "+_21;
}
_1e.className=_21+"Month dijitCalendarDateTemplate";
var _23=_1f.valueOf();
this._date2cell[_23]=_1e;
_1e.dijitDateValue=_23;
this._setText(this.dateLabels[idx],_1f.getDateLocalized?_1f.getDateLocalized(this.lang):_1f.getDate());
},this);
},_populateControls:function(){
var _24=new this.dateClassObj(this.currentFocus);
_24.setDate(1);
this.monthWidget.set("month",_24);
var y=_24.getFullYear()-1;
var d=new this.dateClassObj();
_1.forEach(["previous","current","next"],function(_25){
d.setFullYear(y++);
this._setText(this[_25+"YearLabelNode"],this.dateLocaleModule.format(d,{selector:"year",locale:this.lang}));
},this);
},goToToday:function(){
this.set("value",new this.dateClassObj());
},constructor:function(_26){
this.dateModule=_26.datePackage?_a.getObject(_26.datePackage,false):_4;
this.dateClassObj=this.dateModule.Date||Date;
this.dateLocaleModule=_26.datePackage?_a.getObject(_26.datePackage+".locale",false):_5;
},_createMonthWidget:function(){
return _10._MonthWidget({id:this.id+"_mw",lang:this.lang,dateLocaleModule:this.dateLocaleModule},this.monthNode);
},buildRendering:function(){
var d=this.dowTemplateString,_27=this.dateLocaleModule.getNames("days",this.dayWidth,"standAlone",this.lang),_28=_3.getFirstDayOfWeek(this.lang);
this.dayCellsHtml=_c.substitute([d,d,d,d,d,d,d].join(""),{d:""},function(){
return _27[_28++%7];
});
var r=_c.substitute(this.weekTemplateString,{d:this.dateTemplateString});
this.dateRowsHtml=[r,r,r,r,r,r].join("");
this.dateCells=[];
this.dateLabels=[];
this.inherited(arguments);
_7.setSelectable(this.domNode,false);
var _29=new this.dateClassObj(this.currentFocus);
this.monthWidget=this._createMonthWidget();
this.set("currentFocus",_29,false);
},postCreate:function(){
this.inherited(arguments);
this._connectControls();
},_connectControls:function(){
var _2a=_a.hitch(this,function(_2b,_2c,_2d){
this.connect(this[_2b],"onclick",function(){
this._setCurrentFocusAttr(this.dateModule.add(this.currentFocus,_2c,_2d));
});
});
_2a("incrementMonth","month",1);
_2a("decrementMonth","month",-1);
_2a("nextYearLabelNode","year",1);
_2a("previousYearLabelNode","year",-1);
},_setCurrentFocusAttr:function(_2e,_2f){
var _30=this.currentFocus,_31=this._getNodeByDate(_30);
_2e=this._patchDate(_2e);
this._set("currentFocus",_2e);
if(!this._date2cell||this.dateModule.difference(_30,_2e,"month")!=0){
this._populateGrid();
this._populateControls();
this._markSelectedDates([this.value]);
}
var _32=this._getNodeByDate(_2e);
_32.setAttribute("tabIndex",this.tabIndex);
if(this.focused||_2f){
_32.focus();
}
if(_31&&_31!=_32){
if(_b("webkit")){
_31.setAttribute("tabIndex","-1");
}else{
_31.removeAttribute("tabIndex");
}
}
},focus:function(){
this._setCurrentFocusAttr(this.currentFocus,true);
},_onDayClick:function(evt){
_9.stop(evt);
for(var _33=evt.target;_33&&!_33.dijitDateValue;_33=_33.parentNode){
}
if(_33&&!_8.contains(_33,"dijitCalendarDisabledDate")){
this.set("value",_33.dijitDateValue);
}
},_getNodeByDate:function(_34){
_34=this._patchDate(_34);
return _34&&this._date2cell?this._date2cell[_34.valueOf()]:null;
},_markSelectedDates:function(_35){
function _36(_37,_38){
_8.toggle(_38,"dijitCalendarSelectedDate",_37);
_38.setAttribute("aria-selected",_37?"true":"false");
};
_1.forEach(this._selectedCells||[],_a.partial(_36,false));
this._selectedCells=_1.filter(_1.map(_35,this._getNodeByDate,this),function(n){
return n;
});
_1.forEach(this._selectedCells,_a.partial(_36,true));
},onChange:function(){
},isDisabledDate:function(){
},getClassForDate:function(){
}});
_10._MonthWidget=_2("dijit.CalendarLite._MonthWidget",_d,{_setMonthAttr:function(_39){
var _3a=this.dateLocaleModule.getNames("months","wide","standAlone",this.lang,_39),_3b=(_b("ie")==6?"":"<div class='dijitSpacer'>"+_1.map(_3a,function(s){
return "<div>"+s+"</div>";
}).join("")+"</div>");
this.domNode.innerHTML=_3b+"<div class='dijitCalendarMonthLabel dijitCalendarCurrentMonthLabel'>"+_3a[_39.getMonth()]+"</div>";
}});
return _10;
});

View File

@ -0,0 +1,501 @@
require({cache:{
'url:dijit/templates/Calendar.html':"<table cellspacing=\"0\" cellpadding=\"0\" class=\"dijitCalendarContainer\" role=\"grid\" aria-labelledby=\"${id}_mddb ${id}_year\">\n\t<thead>\n\t\t<tr class=\"dijitReset dijitCalendarMonthContainer\" valign=\"top\">\n\t\t\t<th class='dijitReset dijitCalendarArrow' data-dojo-attach-point=\"decrementMonth\">\n\t\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitCalendarIncrementControl dijitCalendarDecrease\" role=\"presentation\"/>\n\t\t\t\t<span data-dojo-attach-point=\"decreaseArrowNode\" class=\"dijitA11ySideArrow\">-</span>\n\t\t\t</th>\n\t\t\t<th class='dijitReset' colspan=\"5\">\n\t\t\t\t<div data-dojo-attach-point=\"monthNode\">\n\t\t\t\t</div>\n\t\t\t</th>\n\t\t\t<th class='dijitReset dijitCalendarArrow' data-dojo-attach-point=\"incrementMonth\">\n\t\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitCalendarIncrementControl dijitCalendarIncrease\" role=\"presentation\"/>\n\t\t\t\t<span data-dojo-attach-point=\"increaseArrowNode\" class=\"dijitA11ySideArrow\">+</span>\n\t\t\t</th>\n\t\t</tr>\n\t\t<tr role=\"row\">\n\t\t\t${!dayCellsHtml}\n\t\t</tr>\n\t</thead>\n\t<tbody data-dojo-attach-point=\"dateRowsNode\" data-dojo-attach-event=\"onclick: _onDayClick\" class=\"dijitReset dijitCalendarBodyContainer\">\n\t\t\t${!dateRowsHtml}\n\t</tbody>\n\t<tfoot class=\"dijitReset dijitCalendarYearContainer\">\n\t\t<tr>\n\t\t\t<td class='dijitReset' valign=\"top\" colspan=\"7\" role=\"presentation\">\n\t\t\t\t<div class=\"dijitCalendarYearLabel\">\n\t\t\t\t\t<span data-dojo-attach-point=\"previousYearLabelNode\" class=\"dijitInline dijitCalendarPreviousYear\" role=\"button\"></span>\n\t\t\t\t\t<span data-dojo-attach-point=\"currentYearLabelNode\" class=\"dijitInline dijitCalendarSelectedYear\" role=\"button\" id=\"${id}_year\"></span>\n\t\t\t\t\t<span data-dojo-attach-point=\"nextYearLabelNode\" class=\"dijitInline dijitCalendarNextYear\" role=\"button\"></span>\n\t\t\t\t</div>\n\t\t\t</td>\n\t\t</tr>\n\t</tfoot>\n</table>\n"}});
define("dijit/CalendarLite", [
"dojo/_base/array", // array.forEach array.map
"dojo/_base/declare", // declare
"dojo/cldr/supplemental", // cldrSupplemental.getFirstDayOfWeek
"dojo/date", // date
"dojo/date/locale",
"dojo/date/stamp", // stamp.fromISOString
"dojo/dom", // dom.setSelectable
"dojo/dom-class", // domClass.contains
"dojo/_base/event", // event.stop
"dojo/_base/lang", // lang.getObject, lang.hitch
"dojo/sniff", // has("ie") has("webkit")
"dojo/string", // string.substitute
"./_WidgetBase",
"./_TemplatedMixin",
"dojo/text!./templates/Calendar.html",
"./hccss" // not used directly, but sets CSS class on <body>
], function(array, declare, cldrSupplemental, date, locale, stamp, dom, domClass, event, lang, has, string,
_WidgetBase, _TemplatedMixin, template){
// module:
// dijit/CalendarLite
var CalendarLite = declare("dijit.CalendarLite", [_WidgetBase, _TemplatedMixin], {
// summary:
// Lightweight version of Calendar widget aimed towards mobile use
//
// description:
// A simple GUI for choosing a date in the context of a monthly calendar.
// This widget can't be used in a form because it doesn't serialize the date to an
// `<input>` field. For a form element, use dijit/form/DateTextBox instead.
//
// Note that the parser takes all dates attributes passed in the
// [RFC 3339 format](http://www.faqs.org/rfcs/rfc3339.html), e.g. `2005-06-30T08:05:00-07:00`
// so that they are serializable and locale-independent.
//
// Also note that this widget isn't keyboard accessible; use dijit.Calendar for that
// example:
// | var calendar = new dijit.CalendarLite({}, dojo.byId("calendarNode"));
//
// example:
// | <div data-dojo-type="dijit/CalendarLite"></div>
// Template for main calendar
templateString: template,
// Template for cell for a day of the week (ex: M)
dowTemplateString: '<th class="dijitReset dijitCalendarDayLabelTemplate" role="columnheader"><span class="dijitCalendarDayLabel">${d}</span></th>',
// Templates for a single date (ex: 13), and for a row for a week (ex: 20 21 22 23 24 25 26)
dateTemplateString: '<td class="dijitReset" role="gridcell" data-dojo-attach-point="dateCells"><span class="dijitCalendarDateLabel" data-dojo-attach-point="dateLabels"></span></td>',
weekTemplateString: '<tr class="dijitReset dijitCalendarWeekTemplate" role="row">${d}${d}${d}${d}${d}${d}${d}</tr>',
// value: Date
// The currently selected Date, initially set to invalid date to indicate no selection.
value: new Date(""),
// TODO: for 2.0 make this a string (ISO format) rather than a Date
// datePackage: String
// JavaScript namespace to find calendar routines. If unspecified, uses Gregorian calendar routines
// at dojo/date and dojo/date/locale.
datePackage: "",
// TODO: for 2.0, replace datePackage with dateModule and dateLocalModule attributes specifying MIDs,
// or alternately just get rid of this completely and tell user to use module ID remapping
// via require
// dayWidth: String
// How to represent the days of the week in the calendar header. See locale
dayWidth: "narrow",
// tabIndex: String
// Order fields are traversed when user hits the tab key
tabIndex: "0",
// currentFocus: Date
// Date object containing the currently focused date, or the date which would be focused
// if the calendar itself was focused. Also indicates which year and month to display,
// i.e. the current "page" the calendar is on.
currentFocus: new Date(),
baseClass:"dijitCalendar",
_isValidDate: function(/*Date*/ value){
// summary:
// Runs various tests on the value, checking that it's a valid date, rather
// than blank or NaN.
// tags:
// private
return value && !isNaN(value) && typeof value == "object" &&
value.toString() != this.constructor.prototype.value.toString();
},
_getValueAttr: function(){
// summary:
// Support get('value')
// this.value is set to 1AM, but return midnight, local time for back-compat
if(this.value && !isNaN(this.value)){
var value = new this.dateClassObj(this.value);
value.setHours(0, 0, 0, 0);
// If daylight savings pushes midnight to the previous date, fix the Date
// object to point at 1am so it will represent the correct day. See #9366
if(value.getDate() < this.value.getDate()){
value = this.dateModule.add(value, "hour", 1);
}
return value;
}else{
return null;
}
},
_setValueAttr: function(/*Date|Number*/ value, /*Boolean*/ priorityChange){
// summary:
// Support set("value", ...)
// description:
// Set the current date and update the UI. If the date is disabled, the value will
// not change, but the display will change to the corresponding month.
// value:
// Either a Date or the number of seconds since 1970.
// tags:
// protected
if(typeof value == "string"){
value = stamp.fromISOString(value);
}
value = this._patchDate(value);
if(this._isValidDate(value) && !this.isDisabledDate(value, this.lang)){
this._set("value", value);
// Set focus cell to the new value. Arguably this should only happen when there isn't a current
// focus point. This will also repopulate the grid to new month/year if necessary.
this.set("currentFocus", value);
// Mark the selected date
this._markSelectedDates([value]);
if(this._created && (priorityChange || typeof priorityChange == "undefined")){
this.onChange(this.get('value'));
}
}else{
// clear value, and mark all dates as unselected
this._set("value", null);
this._markSelectedDates([]);
}
},
_patchDate: function(/*Date|Number*/ value){
// summary:
// Convert Number into Date, or copy Date object. Then, round to nearest day,
// setting to 1am to avoid issues when DST shift occurs at midnight, see #8521, #9366)
if(value){
value = new this.dateClassObj(value);
value.setHours(1, 0, 0, 0);
}
return value;
},
_setText: function(node, text){
// summary:
// This just sets the content of node to the specified text.
// Can't do "node.innerHTML=text" because of an IE bug w/tables, see #3434.
// tags:
// private
while(node.firstChild){
node.removeChild(node.firstChild);
}
node.appendChild(node.ownerDocument.createTextNode(text));
},
_populateGrid: function(){
// summary:
// Fills in the calendar grid with each day (1-31).
// Call this on creation, when moving to a new month.
// tags:
// private
var month = new this.dateClassObj(this.currentFocus);
month.setDate(1);
var firstDay = month.getDay(),
daysInMonth = this.dateModule.getDaysInMonth(month),
daysInPreviousMonth = this.dateModule.getDaysInMonth(this.dateModule.add(month, "month", -1)),
today = new this.dateClassObj(),
dayOffset = cldrSupplemental.getFirstDayOfWeek(this.lang);
if(dayOffset > firstDay){ dayOffset -= 7; }
// Mapping from date (as specified by number returned from Date.valueOf()) to corresponding <td>
this._date2cell = {};
// Iterate through dates in the calendar and fill in date numbers and style info
array.forEach(this.dateCells, function(template, idx){
var i = idx + dayOffset;
var date = new this.dateClassObj(month),
number, clazz = "dijitCalendar", adj = 0;
if(i < firstDay){
number = daysInPreviousMonth - firstDay + i + 1;
adj = -1;
clazz += "Previous";
}else if(i >= (firstDay + daysInMonth)){
number = i - firstDay - daysInMonth + 1;
adj = 1;
clazz += "Next";
}else{
number = i - firstDay + 1;
clazz += "Current";
}
if(adj){
date = this.dateModule.add(date, "month", adj);
}
date.setDate(number);
if(!this.dateModule.compare(date, today, "date")){
clazz = "dijitCalendarCurrentDate " + clazz;
}
if(this.isDisabledDate(date, this.lang)){
clazz = "dijitCalendarDisabledDate " + clazz;
template.setAttribute("aria-disabled", "true");
}else{
clazz = "dijitCalendarEnabledDate " + clazz;
template.removeAttribute("aria-disabled");
template.setAttribute("aria-selected", "false");
}
var clazz2 = this.getClassForDate(date, this.lang);
if(clazz2){
clazz = clazz2 + " " + clazz;
}
template.className = clazz + "Month dijitCalendarDateTemplate";
// Each cell has an associated integer value representing it's date
var dateVal = date.valueOf();
this._date2cell[dateVal] = template;
template.dijitDateValue = dateVal;
// Set Date string (ex: "13").
this._setText(this.dateLabels[idx], date.getDateLocalized ? date.getDateLocalized(this.lang) : date.getDate());
}, this);
},
_populateControls: function(){
// summary:
// Fill in localized month, and prev/current/next years
// tags:
// protected
var month = new this.dateClassObj(this.currentFocus);
month.setDate(1);
// set name of this month
this.monthWidget.set("month", month);
var y = month.getFullYear() - 1;
var d = new this.dateClassObj();
array.forEach(["previous", "current", "next"], function(name){
d.setFullYear(y++);
this._setText(this[name+"YearLabelNode"],
this.dateLocaleModule.format(d, {selector:'year', locale:this.lang}));
}, this);
},
goToToday: function(){
// summary:
// Sets calendar's value to today's date
this.set('value', new this.dateClassObj());
},
constructor: function(params /*===== , srcNodeRef =====*/){
// summary:
// Create the widget.
// params: Object|null
// Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
// and functions, typically callbacks like onClick.
// The hash can contain any of the widget's properties, excluding read-only properties.
// srcNodeRef: DOMNode|String?
// If a srcNodeRef (DOM node) is specified, replace srcNodeRef with my generated DOM tree
this.dateModule = params.datePackage ? lang.getObject(params.datePackage, false) : date;
this.dateClassObj = this.dateModule.Date || Date;
this.dateLocaleModule = params.datePackage ? lang.getObject(params.datePackage+".locale", false) : locale;
},
_createMonthWidget: function(){
// summary:
// Creates the drop down button that displays the current month and lets user pick a new one
return CalendarLite._MonthWidget({
id: this.id + "_mw",
lang: this.lang,
dateLocaleModule: this.dateLocaleModule
}, this.monthNode);
},
buildRendering: function(){
// Markup for days of the week (referenced from template)
var d = this.dowTemplateString,
dayNames = this.dateLocaleModule.getNames('days', this.dayWidth, 'standAlone', this.lang),
dayOffset = cldrSupplemental.getFirstDayOfWeek(this.lang);
this.dayCellsHtml = string.substitute([d,d,d,d,d,d,d].join(""), {d: ""}, function(){
return dayNames[dayOffset++ % 7];
});
// Markup for dates of the month (referenced from template), but without numbers filled in
var r = string.substitute(this.weekTemplateString, {d: this.dateTemplateString});
this.dateRowsHtml = [r,r,r,r,r,r].join("");
// Instantiate from template.
// dateCells and dateLabels arrays filled when _Templated parses my template.
this.dateCells = [];
this.dateLabels = [];
this.inherited(arguments);
dom.setSelectable(this.domNode, false);
var dateObj = new this.dateClassObj(this.currentFocus);
this.monthWidget = this._createMonthWidget();
this.set('currentFocus', dateObj, false); // draw the grid to the month specified by currentFocus
},
postCreate: function(){
this.inherited(arguments);
this._connectControls();
},
_connectControls: function(){
// summary:
// Set up connects for increment/decrement of months/years
// tags:
// protected
var connect = lang.hitch(this, function(nodeProp, part, amount){
this.connect(this[nodeProp], "onclick", function(){
this._setCurrentFocusAttr(this.dateModule.add(this.currentFocus, part, amount));
});
});
connect("incrementMonth", "month", 1);
connect("decrementMonth", "month", -1);
connect("nextYearLabelNode", "year", 1);
connect("previousYearLabelNode", "year", -1);
},
_setCurrentFocusAttr: function(/*Date*/ date, /*Boolean*/ forceFocus){
// summary:
// If the calendar currently has focus, then focuses specified date,
// changing the currently displayed month/year if necessary.
// If the calendar doesn't have focus, updates currently
// displayed month/year, and sets the cell that will get focus
// when Calendar is focused.
// forceFocus:
// If true, will focus() the cell even if calendar itself doesn't have focus
var oldFocus = this.currentFocus,
oldCell = this._getNodeByDate(oldFocus);
date = this._patchDate(date);
this._set("currentFocus", date);
// If the focus is on a different month than the current calendar month, switch the displayed month.
// Also will populate the grid initially, on Calendar creation.
if(!this._date2cell || this.dateModule.difference(oldFocus, date, "month") != 0){
this._populateGrid();
this._populateControls();
this._markSelectedDates([this.value]);
}
// set tabIndex=0 on new cell, and focus it (but only if Calendar itself is focused)
var newCell = this._getNodeByDate(date);
newCell.setAttribute("tabIndex", this.tabIndex);
if(this.focused || forceFocus){
newCell.focus();
}
// set tabIndex=-1 on old focusable cell
if(oldCell && oldCell != newCell){
if(has("webkit")){ // see #11064 about webkit bug
oldCell.setAttribute("tabIndex", "-1");
}else{
oldCell.removeAttribute("tabIndex");
}
}
},
focus: function(){
// summary:
// Focus the calendar by focusing one of the calendar cells
this._setCurrentFocusAttr(this.currentFocus, true);
},
_onDayClick: function(/*Event*/ evt){
// summary:
// Handler for day clicks, selects the date if appropriate
// tags:
// protected
event.stop(evt);
for(var node = evt.target; node && !node.dijitDateValue; node = node.parentNode);
if(node && !domClass.contains(node, "dijitCalendarDisabledDate")){
this.set('value', node.dijitDateValue);
}
},
_getNodeByDate : function(/*Date*/ value){
// summary:
// Returns the cell corresponding to the date, or null if the date is not within the currently
// displayed month.
value = this._patchDate(value);
return value && this._date2cell ? this._date2cell[value.valueOf()] : null;
},
_markSelectedDates: function(/*Date[]*/ dates){
// summary:
// Marks the specified cells as selected, and clears cells previously marked as selected.
// For CalendarLite at most one cell is selected at any point, but this allows an array
// for easy subclassing.
// Function to mark a cell as selected or unselected
function mark(/*Boolean*/ selected, /*DomNode*/ cell){
domClass.toggle(cell, "dijitCalendarSelectedDate", selected);
cell.setAttribute("aria-selected", selected ? "true" : "false");
}
// Clear previously selected cells.
array.forEach(this._selectedCells || [], lang.partial(mark, false));
// Mark newly selected cells. Ignore dates outside the currently displayed month.
this._selectedCells = array.filter(array.map(dates, this._getNodeByDate, this), function(n){ return n;});
array.forEach(this._selectedCells, lang.partial(mark, true));
},
onChange: function(/*Date*/ /*===== date =====*/){
// summary:
// Called only when the selected date has changed
},
isDisabledDate: function(/*===== dateObject, locale =====*/){
// summary:
// May be overridden to disable certain dates in the calendar e.g. `isDisabledDate=dojo.date.locale.isWeekend`
// dateObject: Date
// locale: String?
// tags:
// extension
/*=====
return false; // Boolean
=====*/
},
getClassForDate: function(/*===== dateObject, locale =====*/){
// summary:
// May be overridden to return CSS classes to associate with the date entry for the given dateObject,
// for example to indicate a holiday in specified locale.
// dateObject: Date
// locale: String?
// tags:
// extension
/*=====
return ""; // String
=====*/
}
});
CalendarLite._MonthWidget = declare("dijit.CalendarLite._MonthWidget", _WidgetBase, {
// summary:
// Displays name of current month padded to the width of the month
// w/the longest name, so that changing months doesn't change width.
//
// Create as:
// | new Calendar._MonthWidget({
// | lang: ...,
// | dateLocaleModule: ...
// | })
_setMonthAttr: function(month){
// summary:
// Set the current month to display as a label
var monthNames = this.dateLocaleModule.getNames('months', 'wide', 'standAlone', this.lang, month),
spacer =
(has("ie") == 6 ? "" : "<div class='dijitSpacer'>" +
array.map(monthNames, function(s){ return "<div>" + s + "</div>"; }).join("") + "</div>");
// Set name of current month and also fill in spacer element with all the month names
// (invisible) so that the maximum width will affect layout. But not on IE6 because then
// the center <TH> overlaps the right <TH> (due to a browser bug).
this.domNode.innerHTML =
spacer +
"<div class='dijitCalendarMonthLabel dijitCalendarCurrentMonthLabel'>" +
monthNames[month.getMonth()] + "</div>";
}
});
return CalendarLite;
});

View File

@ -0,0 +1,16 @@
//>>built
require({cache:{"url:dijit/templates/CheckedMenuItem.html":"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitemcheckbox\" tabIndex=\"-1\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">&#10003;</span>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode,labelNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">&#160;</td>\n</tr>\n"}});
define("dijit/CheckedMenuItem",["dojo/_base/declare","dojo/dom-class","./MenuItem","dojo/text!./templates/CheckedMenuItem.html","./hccss"],function(_1,_2,_3,_4){
return _1("dijit.CheckedMenuItem",_3,{templateString:_4,checked:false,_setCheckedAttr:function(_5){
_2.toggle(this.domNode,"dijitCheckedMenuItemChecked",_5);
this.domNode.setAttribute("aria-checked",_5?"true":"false");
this._set("checked",_5);
},iconClass:"",onChange:function(){
},_onClick:function(_6){
if(!this.disabled){
this.set("checked",!this.checked);
this.onChange(this.checked);
}
this.onClick(_6);
}});
});

View File

@ -0,0 +1,53 @@
require({cache:{
'url:dijit/templates/CheckedMenuItem.html':"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitemcheckbox\" tabIndex=\"-1\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">&#10003;</span>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode,labelNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">&#160;</td>\n</tr>\n"}});
define("dijit/CheckedMenuItem", [
"dojo/_base/declare", // declare
"dojo/dom-class", // domClass.toggle
"./MenuItem",
"dojo/text!./templates/CheckedMenuItem.html",
"./hccss"
], function(declare, domClass, MenuItem, template){
// module:
// dijit/CheckedMenuItem
return declare("dijit.CheckedMenuItem", MenuItem, {
// summary:
// A checkbox-like menu item for toggling on and off
templateString: template,
// checked: Boolean
// Our checked state
checked: false,
_setCheckedAttr: function(/*Boolean*/ checked){
// summary:
// Hook so attr('checked', bool) works.
// Sets the class and state for the check box.
domClass.toggle(this.domNode, "dijitCheckedMenuItemChecked", checked);
this.domNode.setAttribute("aria-checked", checked ? "true" : "false");
this._set("checked", checked);
},
iconClass: "", // override dijitNoIcon
onChange: function(/*Boolean*/ /*===== checked =====*/){
// summary:
// User defined function to handle check/uncheck events
// tags:
// callback
},
_onClick: function(evt){
// summary:
// Clicking this item just toggles its state
// tags:
// private
if(!this.disabled){
this.set("checked", !this.checked);
this.onChange(this.checked);
}
this.onClick(evt);
}
});
});

View File

@ -0,0 +1,23 @@
//>>built
require({cache:{"url:dijit/templates/ColorPalette.html":"<div class=\"dijitInline dijitColorPalette\">\n\t<table dojoAttachPoint=\"paletteTableNode\" class=\"dijitPaletteTable\" cellSpacing=\"0\" cellPadding=\"0\" role=\"grid\">\n\t\t<tbody data-dojo-attach-point=\"gridNode\"></tbody>\n\t</table>\n</div>\n"}});
define("dijit/ColorPalette",["require","dojo/text!./templates/ColorPalette.html","./_Widget","./_TemplatedMixin","./_PaletteMixin","./hccss","dojo/i18n","dojo/_base/Color","dojo/_base/declare","dojo/dom-construct","dojo/string","dojo/i18n!dojo/nls/colors","dojo/colors"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b){
var _c=_9("dijit.ColorPalette",[_3,_4,_5],{palette:"7x10",_palettes:{"7x10":[["white","seashell","cornsilk","lemonchiffon","lightyellow","palegreen","paleturquoise","lightcyan","lavender","plum"],["lightgray","pink","bisque","moccasin","khaki","lightgreen","lightseagreen","lightskyblue","cornflowerblue","violet"],["silver","lightcoral","sandybrown","orange","palegoldenrod","chartreuse","mediumturquoise","skyblue","mediumslateblue","orchid"],["gray","red","orangered","darkorange","yellow","limegreen","darkseagreen","royalblue","slateblue","mediumorchid"],["dimgray","crimson","chocolate","coral","gold","forestgreen","seagreen","blue","blueviolet","darkorchid"],["darkslategray","firebrick","saddlebrown","sienna","olive","green","darkcyan","mediumblue","darkslateblue","darkmagenta"],["black","darkred","maroon","brown","darkolivegreen","darkgreen","midnightblue","navy","indigo","purple"]],"3x4":[["white","lime","green","blue"],["silver","yellow","fuchsia","navy"],["gray","red","purple","black"]]},templateString:_2,baseClass:"dijitColorPalette",_dyeFactory:function(_d,_e,_f,_10){
return new this._dyeClass(_d,_e,_f,_10);
},buildRendering:function(){
this.inherited(arguments);
this._dyeClass=_9(_c._Color,{palette:this.palette});
this._preparePalette(this._palettes[this.palette],_7.getLocalization("dojo","colors",this.lang));
}});
_c._Color=_9("dijit._Color",_8,{template:"<span class='dijitInline dijitPaletteImg'>"+"<img src='${blankGif}' alt='${alt}' title='${title}' class='dijitColorPaletteSwatch' style='background-color: ${color}'/>"+"</span>",hcTemplate:"<span class='dijitInline dijitPaletteImg' style='position: relative; overflow: hidden; height: 12px; width: 14px;'>"+"<img src='${image}' alt='${alt}' title='${title}' style='position: absolute; left: ${left}px; top: ${top}px; ${size}'/>"+"</span>",_imagePaths:{"7x10":_1.toUrl("./themes/a11y/colors7x10.png"),"3x4":_1.toUrl("./themes/a11y/colors3x4.png")},constructor:function(_11,row,col,_12){
this._title=_12;
this._row=row;
this._col=col;
this.setColor(_8.named[_11]);
},getValue:function(){
return this.toHex();
},fillCell:function(_13,_14){
var _15=_b.substitute(_6("highcontrast")?this.hcTemplate:this.template,{color:this.toHex(),blankGif:_14,alt:this._title,title:this._title,image:this._imagePaths[this.palette].toString(),left:this._col*-20-5,top:this._row*-20-5,size:this.palette=="7x10"?"height: 145px; width: 206px":"height: 64px; width: 86px"});
_a.place(_15,_13);
}});
return _c;
});

View File

@ -0,0 +1,161 @@
require({cache:{
'url:dijit/templates/ColorPalette.html':"<div class=\"dijitInline dijitColorPalette\">\n\t<table dojoAttachPoint=\"paletteTableNode\" class=\"dijitPaletteTable\" cellSpacing=\"0\" cellPadding=\"0\" role=\"grid\">\n\t\t<tbody data-dojo-attach-point=\"gridNode\"></tbody>\n\t</table>\n</div>\n"}});
define("dijit/ColorPalette", [
"require", // require.toUrl
"dojo/text!./templates/ColorPalette.html",
"./_Widget", // used also to load dijit/hccss for setting has("highcontrast")
"./_TemplatedMixin",
"./_PaletteMixin",
"./hccss", // has("highcontrast")
"dojo/i18n", // i18n.getLocalization
"dojo/_base/Color", // dojo.Color dojo.Color.named
"dojo/_base/declare", // declare
"dojo/dom-construct", // domConstruct.place
"dojo/string", // string.substitute
"dojo/i18n!dojo/nls/colors", // translations
"dojo/colors" // extend dojo.Color w/names of other colors
], function(require, template, _Widget, _TemplatedMixin, _PaletteMixin, has, i18n, Color,
declare, domConstruct, string){
// module:
// dijit/ColorPalette
var ColorPalette = declare("dijit.ColorPalette", [_Widget, _TemplatedMixin, _PaletteMixin], {
// summary:
// A keyboard accessible color-picking widget
// description:
// Grid showing various colors, so the user can pick a certain color.
// Can be used standalone, or as a popup.
//
// example:
// | <div data-dojo-type="dijit/ColorPalette"></div>
//
// example:
// | var picker = new dijit.ColorPalette({ },srcNode);
// | picker.startup();
// palette: [const] String
// Size of grid, either "7x10" or "3x4".
palette: "7x10",
// _palettes: [protected] Map
// This represents the value of the colors.
// The first level is a hashmap of the different palettes available.
// The next two dimensions represent the columns and rows of colors.
_palettes: {
"7x10": [["white", "seashell", "cornsilk", "lemonchiffon","lightyellow", "palegreen", "paleturquoise", "lightcyan", "lavender", "plum"],
["lightgray", "pink", "bisque", "moccasin", "khaki", "lightgreen", "lightseagreen", "lightskyblue", "cornflowerblue", "violet"],
["silver", "lightcoral", "sandybrown", "orange", "palegoldenrod", "chartreuse", "mediumturquoise", "skyblue", "mediumslateblue","orchid"],
["gray", "red", "orangered", "darkorange", "yellow", "limegreen", "darkseagreen", "royalblue", "slateblue", "mediumorchid"],
["dimgray", "crimson", "chocolate", "coral", "gold", "forestgreen", "seagreen", "blue", "blueviolet", "darkorchid"],
["darkslategray","firebrick","saddlebrown", "sienna", "olive", "green", "darkcyan", "mediumblue","darkslateblue", "darkmagenta" ],
["black", "darkred", "maroon", "brown", "darkolivegreen", "darkgreen", "midnightblue", "navy", "indigo", "purple"]],
"3x4": [["white", "lime", "green", "blue"],
["silver", "yellow", "fuchsia", "navy"],
["gray", "red", "purple", "black"]]
},
// templateString: String
// The template of this widget.
templateString: template,
baseClass: "dijitColorPalette",
_dyeFactory: function(value, row, col, title){
// Overrides _PaletteMixin._dyeFactory().
return new this._dyeClass(value, row, col, title);
},
buildRendering: function(){
// Instantiate the template, which makes a skeleton into which we'll insert a bunch of
// <img> nodes
this.inherited(arguments);
// Creates customized constructor for dye class (color of a single cell) for
// specified palette and high-contrast vs. normal mode. Used in _getDye().
this._dyeClass = declare(ColorPalette._Color, {
palette: this.palette
});
// Creates <img> nodes in each cell of the template.
this._preparePalette(
this._palettes[this.palette],
i18n.getLocalization("dojo", "colors", this.lang));
}
});
ColorPalette._Color = declare("dijit._Color", Color, {
// summary:
// Object associated with each cell in a ColorPalette palette.
// Implements dijit/Dye.
// Template for each cell in normal (non-high-contrast mode). Each cell contains a wrapper
// node for showing the border (called dijitPaletteImg for back-compat), and dijitColorPaletteSwatch
// for showing the color.
template:
"<span class='dijitInline dijitPaletteImg'>" +
"<img src='${blankGif}' alt='${alt}' title='${title}' class='dijitColorPaletteSwatch' style='background-color: ${color}'/>" +
"</span>",
// Template for each cell in high contrast mode. Each cell contains an image with the whole palette,
// but scrolled and clipped to show the correct color only
hcTemplate:
"<span class='dijitInline dijitPaletteImg' style='position: relative; overflow: hidden; height: 12px; width: 14px;'>" +
"<img src='${image}' alt='${alt}' title='${title}' style='position: absolute; left: ${left}px; top: ${top}px; ${size}'/>" +
"</span>",
// _imagePaths: [protected] Map
// This is stores the path to the palette images used for high-contrast mode display
_imagePaths: {
"7x10": require.toUrl("./themes/a11y/colors7x10.png"),
"3x4": require.toUrl("./themes/a11y/colors3x4.png")
},
constructor: function(alias, row, col, title){
// summary:
// Constructor for ColorPalette._Color
// alias: String
// English name of the color.
// row: Number
// Vertical position in grid.
// column: Number
// Horizontal position in grid.
// title: String
// Localized name of the color.
this._title = title;
this._row = row;
this._col = col;
this.setColor(Color.named[alias]);
},
getValue: function(){
// summary:
// Note that although dijit._Color is initialized with a value like "white" getValue() always
// returns a hex value
return this.toHex();
},
fillCell: function(/*DOMNode*/ cell, /*String*/ blankGif){
var html = string.substitute(has("highcontrast") ? this.hcTemplate : this.template, {
// substitution variables for normal mode
color: this.toHex(),
blankGif: blankGif,
alt: this._title,
title: this._title,
// variables used for high contrast mode
image: this._imagePaths[this.palette].toString(),
left: this._col * -20 - 5,
top: this._row * -20 - 5,
size: this.palette == "7x10" ? "height: 145px; width: 206px" : "height: 64px; width: 86px"
});
domConstruct.place(html, cell);
}
});
return ColorPalette;
});

View File

@ -0,0 +1,29 @@
//>>built
define("dijit/Declaration",["dojo/_base/array","dojo/_base/connect","dojo/_base/declare","dojo/_base/lang","dojo/parser","dojo/query","./_Widget","./_TemplatedMixin","./_WidgetsInTemplateMixin","dojo/NodeList-dom"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9){
return _3("dijit.Declaration",_7,{_noScript:true,stopParser:true,widgetClass:"",defaults:null,mixins:[],buildRendering:function(){
var _a=this.srcNodeRef.parentNode.removeChild(this.srcNodeRef),_b=_6("> script[type^='dojo/method']",_a).orphan(),_c=_6("> script[type^='dojo/connect']",_a).orphan(),_d=_a.nodeName;
var _e=this.defaults||{};
_1.forEach(_b,function(s){
var _f=s.getAttribute("event")||s.getAttribute("data-dojo-event"),_10=_5._functionFromScript(s);
if(_f){
_e[_f]=_10;
}else{
_c.push(s);
}
});
if(this.mixins.length){
this.mixins=_1.map(this.mixins,function(_11){
return _4.getObject(_11);
});
}else{
this.mixins=[_7,_8,_9];
}
_e._skipNodeCache=true;
_e.templateString="<"+_d+" class='"+_a.className+"'"+" data-dojo-attach-point='"+(_a.getAttribute("data-dojo-attach-point")||_a.getAttribute("dojoAttachPoint")||"")+"' data-dojo-attach-event='"+(_a.getAttribute("data-dojo-attach-event")||_a.getAttribute("dojoAttachEvent")||"")+"' >"+_a.innerHTML.replace(/\%7B/g,"{").replace(/\%7D/g,"}")+"</"+_d+">";
var wc=_3(this.widgetClass,this.mixins,_e);
_1.forEach(_c,function(s){
var evt=s.getAttribute("event")||s.getAttribute("data-dojo-event")||"postscript",_12=_5._functionFromScript(s);
_2.connect(wc.prototype,evt,_12);
});
}});
});

View File

@ -0,0 +1,105 @@
define("dijit/Declaration", [
"dojo/_base/array", // array.forEach array.map
"dojo/_base/connect", // connect.connect
"dojo/_base/declare", // declare
"dojo/_base/lang", // lang.getObject
"dojo/parser", // parser._functionFromScript
"dojo/query", // query
"./_Widget",
"./_TemplatedMixin",
"./_WidgetsInTemplateMixin",
"dojo/NodeList-dom"
], function(array, connect, declare, lang, parser, query, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin){
// module:
// dijit/Declaration
return declare("dijit.Declaration", _Widget, {
// summary:
// The Declaration widget allows a developer to declare new widget
// classes directly from a snippet of markup.
// _noScript: [private] Boolean
// Flag to parser to leave alone the script tags contained inside of me
_noScript: true,
// stopParser: [private] Boolean
// Flag to parser to not try and parse widgets declared inside of me
stopParser: true,
// widgetClass: [const] String
// Name of class being declared, ex: "acme.myWidget"
widgetClass: "",
// propList: [const] Object
// Set of attributes for this widget along with default values, ex:
// {delay: 100, title: "hello world"}
defaults: null,
// mixins: [const] String[]
// List containing the prototype for this widget, and also any mixins,
// ex: ["dijit._Widget", "dijit._Container"]
mixins: [],
buildRendering: function(){
var src = this.srcNodeRef.parentNode.removeChild(this.srcNodeRef),
methods = query("> script[type^='dojo/method']", src).orphan(),
connects = query("> script[type^='dojo/connect']", src).orphan(),
srcType = src.nodeName;
var propList = this.defaults || {};
// For all methods defined like <script type="dojo/method" data-dojo-event="foo">,
// add that method to prototype.
// If there's no "event" specified then it's code to run on instantiation,
// so it becomes a connection to "postscript" (handled below).
array.forEach(methods, function(s){
var evt = s.getAttribute("event") || s.getAttribute("data-dojo-event"),
func = parser._functionFromScript(s);
if(evt){
propList[evt] = func;
}else{
connects.push(s);
}
});
// map array of strings like [ "dijit.form.Button" ] to array of mixin objects
// (note that array.map(this.mixins, lang.getObject) doesn't work because it passes
// a bogus third argument to getObject(), confusing it)
if(this.mixins.length){
this.mixins = array.map(this.mixins, function(name){ return lang.getObject(name); } );
}else{
this.mixins = [ _Widget, _TemplatedMixin, _WidgetsInTemplateMixin ];
}
propList._skipNodeCache = true;
propList.templateString =
"<"+srcType+" class='"+src.className+"'" +
" data-dojo-attach-point='"+
(src.getAttribute("data-dojo-attach-point") || src.getAttribute("dojoAttachPoint") || '')+
"' data-dojo-attach-event='"+
(src.getAttribute("data-dojo-attach-event") || src.getAttribute("dojoAttachEvent") || '')+
"' >"+src.innerHTML.replace(/\%7B/g,"{").replace(/\%7D/g,"}")+"</"+srcType+">";
// create the new widget class
var wc = declare(
this.widgetClass,
this.mixins,
propList
);
// Handle <script> blocks of form:
// <script type="dojo/connect" data-dojo-event="foo">
// and
// <script type="dojo/method">
// (Note that the second one is just shorthand for a dojo/connect to postscript)
// Since this is a connect in the declaration, we are actually connection to the method
// in the _prototype_.
array.forEach(connects, function(s){
var evt = s.getAttribute("event") || s.getAttribute("data-dojo-event") || "postscript",
func = parser._functionFromScript(s);
connect.connect(wc.prototype, evt, func);
});
}
});
});

View File

@ -0,0 +1,18 @@
//>>built
define("dijit/Destroyable",["dojo/_base/array","dojo/aspect","dojo/_base/declare"],function(_1,_2,_3){
return _3("dijit.Destroyable",null,{destroy:function(_4){
this._destroyed=true;
},own:function(){
_1.forEach(arguments,function(_5){
var _6="destroyRecursive" in _5?"destroyRecursive":"destroy" in _5?"destroy":"remove";
var _7=_2.before(this,"destroy",function(_8){
_5[_6](_8);
});
var _9=_2.after(_5,_6,function(){
_7.remove();
_9.remove();
},true);
},this);
return arguments;
}});
});

View File

@ -0,0 +1,59 @@
define("dijit/Destroyable", [
"dojo/_base/array", // array.forEach array.map
"dojo/aspect",
"dojo/_base/declare"
], function(array, aspect, declare){
// module:
// dijit/Destroyable
return declare("dijit.Destroyable", null, {
// summary:
// Mixin to track handles and release them when instance is destroyed.
// description:
// Call this.own(...) on list of handles (returned from dojo/aspect, dojo/on,
// dojo/Stateful::watch, or any class (including widgets) with a destroyRecursive() or destroy() method.
// Then call destroy() later to destroy this instance and release the resources.
destroy: function(/*Boolean*/ preserveDom){
// summary:
// Destroy this class, releasing any resources registered via own().
this._destroyed = true;
},
own: function(){
// summary:
// Track specified handles and remove/destroy them when this instance is destroyed, unless they were
// already removed/destroyed manually.
// tags:
// protected
// returns:
// The array of specified handles, so you can do for example:
// | var handle = this.own(on(...))[0];
array.forEach(arguments, function(handle){
var destroyMethodName =
"destroyRecursive" in handle ? "destroyRecursive" : // remove "destroyRecursive" for 2.0
"destroy" in handle ? "destroy" :
"remove";
// When this.destroy() is called, destroy handle. Since I'm using aspect.before(),
// the handle will be destroyed before a subclass's destroy() method starts running, before it calls
// this.inherited() or even if it doesn't call this.inherited() at all. If that's an issue, make an
// onDestroy() method and connect to that instead.
var odh = aspect.before(this, "destroy", function(preserveDom){
handle[destroyMethodName](preserveDom);
});
// If handle is destroyed manually before this.destroy() is called, remove the listener set directly above.
var hdh = aspect.after(handle, destroyMethodName, function(){
odh.remove();
hdh.remove();
}, true);
}, this);
return arguments; // handle
}
});
});

View File

@ -0,0 +1,287 @@
//>>built
require({cache:{"url:dijit/templates/Dialog.html":"<div class=\"dijitDialog\" role=\"dialog\" aria-labelledby=\"${id}_title\">\n\t<div data-dojo-attach-point=\"titleBar\" class=\"dijitDialogTitleBar\">\n\t\t<span data-dojo-attach-point=\"titleNode\" class=\"dijitDialogTitle\" id=\"${id}_title\"\n\t\t\t\trole=\"heading\" level=\"1\"></span>\n\t\t<span data-dojo-attach-point=\"closeButtonNode\" class=\"dijitDialogCloseIcon\" data-dojo-attach-event=\"ondijitclick: onCancel\" title=\"${buttonCancel}\" role=\"button\" tabIndex=\"-1\">\n\t\t\t<span data-dojo-attach-point=\"closeText\" class=\"closeText\" title=\"${buttonCancel}\">x</span>\n\t\t</span>\n\t</div>\n\t<div data-dojo-attach-point=\"containerNode\" class=\"dijitDialogPaneContent\"></div>\n</div>\n"}});
define("dijit/Dialog",["require","dojo/_base/array","dojo/_base/connect","dojo/_base/declare","dojo/_base/Deferred","dojo/dom","dojo/dom-class","dojo/dom-geometry","dojo/dom-style","dojo/_base/event","dojo/_base/fx","dojo/i18n","dojo/keys","dojo/_base/lang","dojo/on","dojo/ready","dojo/sniff","dojo/window","dojo/dnd/Moveable","dojo/dnd/TimedMoveable","./focus","./_base/manager","./_Widget","./_TemplatedMixin","./_CssStateMixin","./form/_FormMixin","./_DialogMixin","./DialogUnderlay","./layout/ContentPane","dojo/text!./templates/Dialog.html","./main","dojo/i18n!./nls/common"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,fx,_b,_c,_d,on,_e,_f,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_1a,_1b,_1c,_1d){
var _1e=_4("dijit._DialogBase",[_16,_18,_19,_17],{templateString:_1c,baseClass:"dijitDialog",cssStateNodes:{closeButtonNode:"dijitDialogCloseIcon"},_setTitleAttr:[{node:"titleNode",type:"innerHTML"},{node:"titleBar",type:"attribute"}],open:false,duration:_14.defaultDuration,refocus:true,autofocus:true,_firstFocusItem:null,_lastFocusItem:null,doLayout:false,draggable:true,_setDraggableAttr:function(val){
this._set("draggable",val);
},"aria-describedby":"",maxRatio:0.9,postMixInProperties:function(){
var _1f=_b.getLocalization("dijit","common");
_d.mixin(this,_1f);
this.inherited(arguments);
},postCreate:function(){
_9.set(this.domNode,{display:"none",position:"absolute"});
this.ownerDocumentBody.appendChild(this.domNode);
this.inherited(arguments);
this.connect(this,"onExecute","hide");
this.connect(this,"onCancel","hide");
this._modalconnects=[];
},onLoad:function(){
this._position();
if(this.autofocus&&_20.isTop(this)){
this._getFocusItems(this.domNode);
_13.focus(this._firstFocusItem);
}
this.inherited(arguments);
},_onBlur:function(by){
this.inherited(arguments);
var _21=_d.hitch(this,function(){
if(this.open&&!this._destroyed&&_20.isTop(this)){
this._getFocusItems(this.domNode);
_13.focus(this._firstFocusItem);
}
});
if(by=="mouse"){
on.once(this.ownerDocument,"mouseup",_21);
}else{
_21();
}
},_endDrag:function(){
var _22=_8.position(this.domNode),_23=_10.getBox(this.ownerDocument);
_22.y=Math.min(Math.max(_22.y,0),(_23.h-_22.h));
_22.x=Math.min(Math.max(_22.x,0),(_23.w-_22.w));
this._relativePosition=_22;
this._position();
},_setup:function(){
var _24=this.domNode;
if(this.titleBar&&this.draggable){
this._moveable=new ((_f("ie")==6)?_12:_11)(_24,{handle:this.titleBar});
this.connect(this._moveable,"onMoveStop","_endDrag");
}else{
_7.add(_24,"dijitDialogFixed");
}
this.underlayAttrs={dialogId:this.id,"class":_2.map(this["class"].split(/\s/),function(s){
return s+"_underlay";
}).join(" "),ownerDocument:this.ownerDocument};
},_size:function(){
this._checkIfSingleChild();
if(this._singleChild){
if(typeof this._singleChildOriginalStyle!="undefined"){
this._singleChild.domNode.style.cssText=this._singleChildOriginalStyle;
delete this._singleChildOriginalStyle;
}
}else{
_9.set(this.containerNode,{width:"auto",height:"auto"});
}
var bb=_8.position(this.domNode);
var _25=_10.getBox(this.ownerDocument);
_25.w*=this.maxRatio;
_25.h*=this.maxRatio;
if(bb.w>=_25.w||bb.h>=_25.h){
var _26=_8.position(this.containerNode),w=Math.min(bb.w,_25.w)-(bb.w-_26.w),h=Math.min(bb.h,_25.h)-(bb.h-_26.h);
if(this._singleChild&&this._singleChild.resize){
if(typeof this._singleChildOriginalStyle=="undefined"){
this._singleChildOriginalStyle=this._singleChild.domNode.style.cssText;
}
this._singleChild.resize({w:w,h:h});
}else{
_9.set(this.containerNode,{width:w+"px",height:h+"px",overflow:"auto",position:"relative"});
}
}else{
if(this._singleChild&&this._singleChild.resize){
this._singleChild.resize();
}
}
},_position:function(){
if(!_7.contains(this.ownerDocumentBody,"dojoMove")){
var _27=this.domNode,_28=_10.getBox(this.ownerDocument),p=this._relativePosition,bb=p?null:_8.position(_27),l=Math.floor(_28.l+(p?p.x:(_28.w-bb.w)/2)),t=Math.floor(_28.t+(p?p.y:(_28.h-bb.h)/2));
_9.set(_27,{left:l+"px",top:t+"px"});
}
},_onKey:function(evt){
if(evt.charOrCode){
var _29=evt.target;
if(evt.charOrCode===_c.TAB){
this._getFocusItems(this.domNode);
}
var _2a=(this._firstFocusItem==this._lastFocusItem);
if(_29==this._firstFocusItem&&evt.shiftKey&&evt.charOrCode===_c.TAB){
if(!_2a){
_13.focus(this._lastFocusItem);
}
_a.stop(evt);
}else{
if(_29==this._lastFocusItem&&evt.charOrCode===_c.TAB&&!evt.shiftKey){
if(!_2a){
_13.focus(this._firstFocusItem);
}
_a.stop(evt);
}else{
while(_29){
if(_29==this.domNode||_7.contains(_29,"dijitPopup")){
if(evt.charOrCode==_c.ESCAPE){
this.onCancel();
}else{
return;
}
}
_29=_29.parentNode;
}
if(evt.charOrCode!==_c.TAB){
_a.stop(evt);
}else{
if(!_f("opera")){
try{
this._firstFocusItem.focus();
}
catch(e){
}
}
}
}
}
}
},show:function(){
if(this.open){
return;
}
if(!this._started){
this.startup();
}
if(!this._alreadyInitialized){
this._setup();
this._alreadyInitialized=true;
}
if(this._fadeOutDeferred){
this._fadeOutDeferred.cancel();
}
var win=_10.get(this.ownerDocument);
this._modalconnects.push(on(win,"scroll",_d.hitch(this,"resize")));
this._modalconnects.push(on(this.domNode,_3._keypress,_d.hitch(this,"_onKey")));
_9.set(this.domNode,{opacity:0,display:""});
this._set("open",true);
this._onShow();
this._size();
this._position();
var _2b;
this._fadeInDeferred=new _5(_d.hitch(this,function(){
_2b.stop();
delete this._fadeInDeferred;
}));
_2b=fx.fadeIn({node:this.domNode,duration:this.duration,beforeBegin:_d.hitch(this,function(){
_20.show(this,this.underlayAttrs);
}),onEnd:_d.hitch(this,function(){
if(this.autofocus&&_20.isTop(this)){
this._getFocusItems(this.domNode);
_13.focus(this._firstFocusItem);
}
this._fadeInDeferred.resolve(true);
delete this._fadeInDeferred;
})}).play();
return this._fadeInDeferred;
},hide:function(){
if(!this._alreadyInitialized||!this.open){
return;
}
if(this._fadeInDeferred){
this._fadeInDeferred.cancel();
}
var _2c;
this._fadeOutDeferred=new _5(_d.hitch(this,function(){
_2c.stop();
delete this._fadeOutDeferred;
}));
this._fadeOutDeferred.then(_d.hitch(this,"onHide"));
_2c=fx.fadeOut({node:this.domNode,duration:this.duration,onEnd:_d.hitch(this,function(){
this.domNode.style.display="none";
_20.hide(this);
this._fadeOutDeferred.resolve(true);
delete this._fadeOutDeferred;
})}).play();
if(this._scrollConnected){
this._scrollConnected=false;
}
var h;
while(h=this._modalconnects.pop()){
h.remove();
}
if(this._relativePosition){
delete this._relativePosition;
}
this._set("open",false);
return this._fadeOutDeferred;
},resize:function(){
if(this.domNode.style.display!="none"){
if(_1a._singleton){
_1a._singleton.layout();
}
this._position();
this._size();
}
},destroy:function(){
if(this._fadeInDeferred){
this._fadeInDeferred.cancel();
}
if(this._fadeOutDeferred){
this._fadeOutDeferred.cancel();
}
if(this._moveable){
this._moveable.destroy();
}
var h;
while(h=this._modalconnects.pop()){
h.remove();
}
_20.hide(this);
this.inherited(arguments);
}});
var _2d=_4("dijit.Dialog",[_1b,_1e],{});
_2d._DialogBase=_1e;
var _20=_2d._DialogLevelManager={_beginZIndex:950,show:function(_2e,_2f){
ds[ds.length-1].focus=_13.curNode;
var _30=_1a._singleton;
if(!_30||_30._destroyed){
_30=_1d._underlay=_1a._singleton=new _1a(_2f);
}else{
_30.set(_2e.underlayAttrs);
}
var _31=ds[ds.length-1].dialog?ds[ds.length-1].zIndex+2:_2d._DialogLevelManager._beginZIndex;
if(ds.length==1){
_30.show();
}
_9.set(_1a._singleton.domNode,"zIndex",_31-1);
_9.set(_2e.domNode,"zIndex",_31);
ds.push({dialog:_2e,underlayAttrs:_2f,zIndex:_31});
},hide:function(_32){
if(ds[ds.length-1].dialog==_32){
ds.pop();
var pd=ds[ds.length-1];
if(!_1a._singleton._destroyed){
if(ds.length==1){
_1a._singleton.hide();
}else{
_9.set(_1a._singleton.domNode,"zIndex",pd.zIndex-1);
_1a._singleton.set(pd.underlayAttrs);
}
}
if(_32.refocus){
var _33=pd.focus;
if(pd.dialog&&(!_33||!_6.isDescendant(_33,pd.dialog.domNode))){
pd.dialog._getFocusItems(pd.dialog.domNode);
_33=pd.dialog._firstFocusItem;
}
if(_33){
try{
_33.focus();
}
catch(e){
}
}
}
}else{
var idx=_2.indexOf(_2.map(ds,function(_34){
return _34.dialog;
}),_32);
if(idx!=-1){
ds.splice(idx,1);
}
}
},isTop:function(_35){
return ds[ds.length-1].dialog==_35;
}};
var ds=_2d._dialogStack=[{dialog:null,focus:null,underlayAttrs:null}];
if(_f("dijit-legacy-requires")){
_e(0,function(){
var _36=["dijit/TooltipDialog"];
_1(_36);
});
}
return _2d;
});

View File

@ -0,0 +1,661 @@
require({cache:{
'url:dijit/templates/Dialog.html':"<div class=\"dijitDialog\" role=\"dialog\" aria-labelledby=\"${id}_title\">\n\t<div data-dojo-attach-point=\"titleBar\" class=\"dijitDialogTitleBar\">\n\t\t<span data-dojo-attach-point=\"titleNode\" class=\"dijitDialogTitle\" id=\"${id}_title\"\n\t\t\t\trole=\"heading\" level=\"1\"></span>\n\t\t<span data-dojo-attach-point=\"closeButtonNode\" class=\"dijitDialogCloseIcon\" data-dojo-attach-event=\"ondijitclick: onCancel\" title=\"${buttonCancel}\" role=\"button\" tabIndex=\"-1\">\n\t\t\t<span data-dojo-attach-point=\"closeText\" class=\"closeText\" title=\"${buttonCancel}\">x</span>\n\t\t</span>\n\t</div>\n\t<div data-dojo-attach-point=\"containerNode\" class=\"dijitDialogPaneContent\"></div>\n</div>\n"}});
define("dijit/Dialog", [
"require",
"dojo/_base/array", // array.forEach array.indexOf array.map
"dojo/_base/connect", // connect._keypress
"dojo/_base/declare", // declare
"dojo/_base/Deferred", // Deferred
"dojo/dom", // dom.isDescendant
"dojo/dom-class", // domClass.add domClass.contains
"dojo/dom-geometry", // domGeometry.position
"dojo/dom-style", // domStyle.set
"dojo/_base/event", // event.stop
"dojo/_base/fx", // fx.fadeIn fx.fadeOut
"dojo/i18n", // i18n.getLocalization
"dojo/keys",
"dojo/_base/lang", // lang.mixin lang.hitch
"dojo/on",
"dojo/ready",
"dojo/sniff", // has("ie") has("opera") has("dijit-legacy-requires")
"dojo/window", // winUtils.getBox, winUtils.get
"dojo/dnd/Moveable", // Moveable
"dojo/dnd/TimedMoveable", // TimedMoveable
"./focus",
"./_base/manager", // manager.defaultDuration
"./_Widget",
"./_TemplatedMixin",
"./_CssStateMixin",
"./form/_FormMixin",
"./_DialogMixin",
"./DialogUnderlay",
"./layout/ContentPane",
"dojo/text!./templates/Dialog.html",
"./main", // for back-compat, exporting dijit._underlay (remove in 2.0)
"dojo/i18n!./nls/common"
], function(require, array, connect, declare, Deferred,
dom, domClass, domGeometry, domStyle, event, fx, i18n, keys, lang, on, ready, has, winUtils,
Moveable, TimedMoveable, focus, manager, _Widget, _TemplatedMixin, _CssStateMixin, _FormMixin, _DialogMixin,
DialogUnderlay, ContentPane, template, dijit){
// module:
// dijit/Dialog
/*=====
dijit._underlay = function(kwArgs){
// summary:
// A shared instance of a `dijit.DialogUnderlay`
//
// description:
// A shared instance of a `dijit.DialogUnderlay` created and
// used by `dijit.Dialog`, though never created until some Dialog
// or subclass thereof is shown.
};
=====*/
var _DialogBase = declare("dijit._DialogBase", [_TemplatedMixin, _FormMixin, _DialogMixin, _CssStateMixin], {
templateString: template,
baseClass: "dijitDialog",
cssStateNodes: {
closeButtonNode: "dijitDialogCloseIcon"
},
// Map widget attributes to DOMNode attributes.
_setTitleAttr: [
{ node: "titleNode", type: "innerHTML" },
{ node: "titleBar", type: "attribute" }
],
// open: [readonly] Boolean
// True if Dialog is currently displayed on screen.
open: false,
// duration: Integer
// The time in milliseconds it takes the dialog to fade in and out
duration: manager.defaultDuration,
// refocus: Boolean
// A Toggle to modify the default focus behavior of a Dialog, which
// is to re-focus the element which had focus before being opened.
// False will disable refocusing. Default: true
refocus: true,
// autofocus: Boolean
// A Toggle to modify the default focus behavior of a Dialog, which
// is to focus on the first dialog element after opening the dialog.
// False will disable autofocusing. Default: true
autofocus: true,
// _firstFocusItem: [private readonly] DomNode
// The pointer to the first focusable node in the dialog.
// Set by `dijit/_DialogMixin._getFocusItems()`.
_firstFocusItem: null,
// _lastFocusItem: [private readonly] DomNode
// The pointer to which node has focus prior to our dialog.
// Set by `dijit/_DialogMixin._getFocusItems()`.
_lastFocusItem: null,
// doLayout: [protected] Boolean
// Don't change this parameter from the default value.
// This ContentPane parameter doesn't make sense for Dialog, since Dialog
// is never a child of a layout container, nor can you specify the size of
// Dialog in order to control the size of an inner widget.
doLayout: false,
// draggable: Boolean
// Toggles the moveable aspect of the Dialog. If true, Dialog
// can be dragged by it's title. If false it will remain centered
// in the viewport.
draggable: true,
_setDraggableAttr: function(/*Boolean*/ val){
// Avoid _WidgetBase behavior of copying draggable attribute to this.domNode,
// as that prevents text select on modern browsers (#14452)
this._set("draggable", val);
},
// aria-describedby: String
// Allows the user to add an aria-describedby attribute onto the dialog. The value should
// be the id of the container element of text that describes the dialog purpose (usually
// the first text in the dialog).
// | <div data-dojo-type="dijit/Dialog" aria-describedby="intro" .....>
// | <div id="intro">Introductory text</div>
// | <div>rest of dialog contents</div>
// | </div>
"aria-describedby": "",
// maxRatio: Number
// Maximum size to allow the dialog to expand to, relative to viewport size
maxRatio: 0.9,
postMixInProperties: function(){
var _nlsResources = i18n.getLocalization("dijit", "common");
lang.mixin(this, _nlsResources);
this.inherited(arguments);
},
postCreate: function(){
domStyle.set(this.domNode, {
display: "none",
position:"absolute"
});
this.ownerDocumentBody.appendChild(this.domNode);
this.inherited(arguments);
this.connect(this, "onExecute", "hide");
this.connect(this, "onCancel", "hide");
this._modalconnects = [];
},
onLoad: function(){
// summary:
// Called when data has been loaded from an href.
// Unlike most other callbacks, this function can be connected to (via `dojo.connect`)
// but should *not* be overridden.
// tags:
// callback
// when href is specified we need to reposition the dialog after the data is loaded
// and find the focusable elements
this._position();
if(this.autofocus && DialogLevelManager.isTop(this)){
this._getFocusItems(this.domNode);
focus.focus(this._firstFocusItem);
}
this.inherited(arguments);
},
_onBlur: function(by){
this.inherited(arguments);
// If focus was accidentally removed from the dialog, such as if the user clicked a blank
// area of the screen, or clicked the browser's address bar and then tabbed into the page,
// then refocus. Won't do anything if focus was removed because the Dialog was closed, or
// because a new Dialog popped up on top of the old one.
var refocus = lang.hitch(this, function(){
if(this.open && !this._destroyed && DialogLevelManager.isTop(this)){
this._getFocusItems(this.domNode);
focus.focus(this._firstFocusItem);
}
});
if(by == "mouse"){
// wait for mouse up, and then refocus dialog; otherwise doesn't work
on.once(this.ownerDocument, "mouseup", refocus);
}else{
refocus();
}
},
_endDrag: function(){
// summary:
// Called after dragging the Dialog. Saves the position of the dialog in the viewport,
// and also adjust position to be fully within the viewport, so user doesn't lose access to handle
var nodePosition = domGeometry.position(this.domNode),
viewport = winUtils.getBox(this.ownerDocument);
nodePosition.y = Math.min(Math.max(nodePosition.y, 0), (viewport.h - nodePosition.h));
nodePosition.x = Math.min(Math.max(nodePosition.x, 0), (viewport.w - nodePosition.w));
this._relativePosition = nodePosition;
this._position();
},
_setup: function(){
// summary:
// Stuff we need to do before showing the Dialog for the first
// time (but we defer it until right beforehand, for
// performance reasons).
// tags:
// private
var node = this.domNode;
if(this.titleBar && this.draggable){
this._moveable = new ((has("ie") == 6) ? TimedMoveable // prevent overload, see #5285
: Moveable)(node, { handle: this.titleBar });
this.connect(this._moveable, "onMoveStop", "_endDrag");
}else{
domClass.add(node,"dijitDialogFixed");
}
this.underlayAttrs = {
dialogId: this.id,
"class": array.map(this["class"].split(/\s/), function(s){ return s+"_underlay"; }).join(" "),
ownerDocument: this.ownerDocument
};
},
_size: function(){
// summary:
// If necessary, shrink dialog contents so dialog fits in viewport
// tags:
// private
this._checkIfSingleChild();
// If we resized the dialog contents earlier, reset them back to original size, so
// that if the user later increases the viewport size, the dialog can display w/out a scrollbar.
// Need to do this before the domGeometry.position(this.domNode) call below.
if(this._singleChild){
if(typeof this._singleChildOriginalStyle != "undefined"){
this._singleChild.domNode.style.cssText = this._singleChildOriginalStyle;
delete this._singleChildOriginalStyle;
}
}else{
domStyle.set(this.containerNode, {
width:"auto",
height:"auto"
});
}
var bb = domGeometry.position(this.domNode);
// Get viewport size but then reduce it by a bit; Dialog should always have some space around it
// to indicate that it's a popup. This will also compensate for possible scrollbars on viewport.
var viewport = winUtils.getBox(this.ownerDocument);
viewport.w *= this.maxRatio;
viewport.h *= this.maxRatio;
if(bb.w >= viewport.w || bb.h >= viewport.h){
// Reduce size of dialog contents so that dialog fits in viewport
var containerSize = domGeometry.position(this.containerNode),
w = Math.min(bb.w, viewport.w) - (bb.w - containerSize.w),
h = Math.min(bb.h, viewport.h) - (bb.h - containerSize.h);
if(this._singleChild && this._singleChild.resize){
if(typeof this._singleChildOriginalStyle == "undefined"){
this._singleChildOriginalStyle = this._singleChild.domNode.style.cssText;
}
this._singleChild.resize({w: w, h: h});
}else{
domStyle.set(this.containerNode, {
width: w + "px",
height: h + "px",
overflow: "auto",
position: "relative" // workaround IE bug moving scrollbar or dragging dialog
});
}
}else{
if(this._singleChild && this._singleChild.resize){
this._singleChild.resize();
}
}
},
_position: function(){
// summary:
// Position modal dialog in the viewport. If no relative offset
// in the viewport has been determined (by dragging, for instance),
// center the node. Otherwise, use the Dialog's stored relative offset,
// and position the node to top: left: values based on the viewport.
if(!domClass.contains(this.ownerDocumentBody, "dojoMove")){ // don't do anything if called during auto-scroll
var node = this.domNode,
viewport = winUtils.getBox(this.ownerDocument),
p = this._relativePosition,
bb = p ? null : domGeometry.position(node),
l = Math.floor(viewport.l + (p ? p.x : (viewport.w - bb.w) / 2)),
t = Math.floor(viewport.t + (p ? p.y : (viewport.h - bb.h) / 2))
;
domStyle.set(node,{
left: l + "px",
top: t + "px"
});
}
},
_onKey: function(/*Event*/ evt){
// summary:
// Handles the keyboard events for accessibility reasons
// tags:
// private
if(evt.charOrCode){
var node = evt.target;
if(evt.charOrCode === keys.TAB){
this._getFocusItems(this.domNode);
}
var singleFocusItem = (this._firstFocusItem == this._lastFocusItem);
// see if we are shift-tabbing from first focusable item on dialog
if(node == this._firstFocusItem && evt.shiftKey && evt.charOrCode === keys.TAB){
if(!singleFocusItem){
focus.focus(this._lastFocusItem); // send focus to last item in dialog
}
event.stop(evt);
}else if(node == this._lastFocusItem && evt.charOrCode === keys.TAB && !evt.shiftKey){
if(!singleFocusItem){
focus.focus(this._firstFocusItem); // send focus to first item in dialog
}
event.stop(evt);
}else{
// see if the key is for the dialog
while(node){
if(node == this.domNode || domClass.contains(node, "dijitPopup")){
if(evt.charOrCode == keys.ESCAPE){
this.onCancel();
}else{
return; // just let it go
}
}
node = node.parentNode;
}
// this key is for the disabled document window
if(evt.charOrCode !== keys.TAB){ // allow tabbing into the dialog for a11y
event.stop(evt);
// opera won't tab to a div
}else if(!has("opera")){
try{
this._firstFocusItem.focus();
}catch(e){ /*squelch*/ }
}
}
}
},
show: function(){
// summary:
// Display the dialog
// returns: dojo/_base/Deferred
// Deferred object that resolves when the display animation is complete
if(this.open){ return; }
if(!this._started){
this.startup();
}
// first time we show the dialog, there's some initialization stuff to do
if(!this._alreadyInitialized){
this._setup();
this._alreadyInitialized=true;
}
if(this._fadeOutDeferred){
this._fadeOutDeferred.cancel();
}
// Recenter Dialog if user scrolls browser. Connecting to document doesn't work on IE, need to use window.
var win = winUtils.get(this.ownerDocument);
this._modalconnects.push(on(win, "scroll", lang.hitch(this, "resize")));
this._modalconnects.push(on(this.domNode, connect._keypress, lang.hitch(this, "_onKey")));
domStyle.set(this.domNode, {
opacity:0,
display:""
});
this._set("open", true);
this._onShow(); // lazy load trigger
this._size();
this._position();
// fade-in Animation object, setup below
var fadeIn;
this._fadeInDeferred = new Deferred(lang.hitch(this, function(){
fadeIn.stop();
delete this._fadeInDeferred;
}));
fadeIn = fx.fadeIn({
node: this.domNode,
duration: this.duration,
beforeBegin: lang.hitch(this, function(){
DialogLevelManager.show(this, this.underlayAttrs);
}),
onEnd: lang.hitch(this, function(){
if(this.autofocus && DialogLevelManager.isTop(this)){
// find focusable items each time dialog is shown since if dialog contains a widget the
// first focusable items can change
this._getFocusItems(this.domNode);
focus.focus(this._firstFocusItem);
}
this._fadeInDeferred.resolve(true);
delete this._fadeInDeferred;
})
}).play();
return this._fadeInDeferred;
},
hide: function(){
// summary:
// Hide the dialog
// returns: dojo/_base/Deferred
// Deferred object that resolves when the hide animation is complete
// If we haven't been initialized yet then we aren't showing and we can just return.
// Likewise if we are already hidden, or are currently fading out.
if(!this._alreadyInitialized || !this.open){
return;
}
if(this._fadeInDeferred){
this._fadeInDeferred.cancel();
}
// fade-in Animation object, setup below
var fadeOut;
this._fadeOutDeferred = new Deferred(lang.hitch(this, function(){
fadeOut.stop();
delete this._fadeOutDeferred;
}));
// fire onHide when the promise resolves.
this._fadeOutDeferred.then(lang.hitch(this, 'onHide'));
fadeOut = fx.fadeOut({
node: this.domNode,
duration: this.duration,
onEnd: lang.hitch(this, function(){
this.domNode.style.display = "none";
DialogLevelManager.hide(this);
this._fadeOutDeferred.resolve(true);
delete this._fadeOutDeferred;
})
}).play();
if(this._scrollConnected){
this._scrollConnected = false;
}
var h;
while(h = this._modalconnects.pop()){
h.remove();
}
if(this._relativePosition){
delete this._relativePosition;
}
this._set("open", false);
return this._fadeOutDeferred;
},
resize: function(){
// summary:
// Called when viewport scrolled or size changed. Position the Dialog and the underlay.
// tags:
// private
if(this.domNode.style.display != "none"){
if(DialogUnderlay._singleton){ // avoid race condition during show()
DialogUnderlay._singleton.layout();
}
this._position();
this._size();
}
},
destroy: function(){
if(this._fadeInDeferred){
this._fadeInDeferred.cancel();
}
if(this._fadeOutDeferred){
this._fadeOutDeferred.cancel();
}
if(this._moveable){
this._moveable.destroy();
}
var h;
while(h = this._modalconnects.pop()){
h.remove();
}
DialogLevelManager.hide(this);
this.inherited(arguments);
}
});
var Dialog = declare("dijit.Dialog", [ContentPane, _DialogBase], {
// summary:
// A modal dialog Widget.
// description:
// Pops up a modal dialog window, blocking access to the screen
// and also graying out the screen Dialog is extended from
// ContentPane so it supports all the same parameters (href, etc.).
// example:
// | <div data-dojo-type="dijit/Dialog" data-dojo-props="href: 'test.html'"></div>
// example:
// | var foo = new Dialog({ title: "test dialog", content: "test content" };
// | foo.placeAt(win.body());
// | foo.startup();
});
Dialog._DialogBase = _DialogBase; // for monkey patching and dojox/widget/DialogSimple
var DialogLevelManager = Dialog._DialogLevelManager = {
// summary:
// Controls the various active "levels" on the page, starting with the
// stuff initially visible on the page (at z-index 0), and then having an entry for
// each Dialog shown.
_beginZIndex: 950,
show: function(/*dijit/_WidgetBase*/ dialog, /*Object*/ underlayAttrs){
// summary:
// Call right before fade-in animation for new dialog.
// Saves current focus, displays/adjusts underlay for new dialog,
// and sets the z-index of the dialog itself.
//
// New dialog will be displayed on top of all currently displayed dialogs.
//
// Caller is responsible for setting focus in new dialog after the fade-in
// animation completes.
// Save current focus
ds[ds.length-1].focus = focus.curNode;
// Display the underlay, or if already displayed then adjust for this new dialog
// TODO: one underlay per document (based on dialog.ownerDocument)
var underlay = DialogUnderlay._singleton;
if(!underlay || underlay._destroyed){
underlay = dijit._underlay = DialogUnderlay._singleton = new DialogUnderlay(underlayAttrs);
}else{
underlay.set(dialog.underlayAttrs);
}
// Set z-index a bit above previous dialog
var zIndex = ds[ds.length-1].dialog ? ds[ds.length-1].zIndex + 2 : Dialog._DialogLevelManager._beginZIndex;
if(ds.length == 1){ // first dialog
underlay.show();
}
domStyle.set(DialogUnderlay._singleton.domNode, 'zIndex', zIndex - 1);
// Dialog
domStyle.set(dialog.domNode, 'zIndex', zIndex);
ds.push({dialog: dialog, underlayAttrs: underlayAttrs, zIndex: zIndex});
},
hide: function(/*dijit/_WidgetBase*/ dialog){
// summary:
// Called when the specified dialog is hidden/destroyed, after the fade-out
// animation ends, in order to reset page focus, fix the underlay, etc.
// If the specified dialog isn't open then does nothing.
//
// Caller is responsible for either setting display:none on the dialog domNode,
// or calling dijit/popup.hide(), or removing it from the page DOM.
if(ds[ds.length-1].dialog == dialog){
// Removing the top (or only) dialog in the stack, return focus
// to previous dialog
ds.pop();
var pd = ds[ds.length-1]; // the new active dialog (or the base page itself)
// Adjust underlay, unless the underlay widget has already been destroyed
// because we are being called during page unload (when all widgets are destroyed)
if(!DialogUnderlay._singleton._destroyed){
if(ds.length == 1){
// Returning to original page. Hide the underlay.
DialogUnderlay._singleton.hide();
}else{
// Popping back to previous dialog, adjust underlay.
domStyle.set(DialogUnderlay._singleton.domNode, 'zIndex', pd.zIndex - 1);
DialogUnderlay._singleton.set(pd.underlayAttrs);
}
}
// Adjust focus
if(dialog.refocus){
// If we are returning control to a previous dialog but for some reason
// that dialog didn't have a focused field, set focus to first focusable item.
// This situation could happen if two dialogs appeared at nearly the same time,
// since a dialog doesn't set it's focus until the fade-in is finished.
var focus = pd.focus;
if(pd.dialog && (!focus || !dom.isDescendant(focus, pd.dialog.domNode))){
pd.dialog._getFocusItems(pd.dialog.domNode);
focus = pd.dialog._firstFocusItem;
}
if(focus){
// Refocus the button that spawned the Dialog. This will fail in corner cases including
// page unload on IE, because the dijit/form/Button that launched the Dialog may get destroyed
// before this code runs. (#15058)
try{
focus.focus();
}catch(e){}
}
}
}else{
// Removing a dialog out of order (#9944, #10705).
// Don't need to mess with underlay or z-index or anything.
var idx = array.indexOf(array.map(ds, function(elem){return elem.dialog}), dialog);
if(idx != -1){
ds.splice(idx, 1);
}
}
},
isTop: function(/*dijit/_WidgetBase*/ dialog){
// summary:
// Returns true if specified Dialog is the top in the task
return ds[ds.length-1].dialog == dialog;
}
};
// Stack representing the various active "levels" on the page, starting with the
// stuff initially visible on the page (at z-index 0), and then having an entry for
// each Dialog shown.
// Each element in stack has form {
// dialog: dialogWidget,
// focus: returnFromGetFocus(),
// underlayAttrs: attributes to set on underlay (when this widget is active)
// }
var ds = Dialog._dialogStack = [
{dialog: null, focus: null, underlayAttrs: null} // entry for stuff at z-index: 0
];
// Back compat w/1.6, remove for 2.0
if(has("dijit-legacy-requires")){
ready(0, function(){
var requires = ["dijit/TooltipDialog"];
require(requires); // use indirection so modules not rolled into a build
});
}
return Dialog;
});

View File

@ -0,0 +1,29 @@
//>>built
define("dijit/DialogUnderlay",["dojo/_base/declare","dojo/dom-attr","dojo/window","./_Widget","./_TemplatedMixin","./BackgroundIframe"],function(_1,_2,_3,_4,_5,_6){
return _1("dijit.DialogUnderlay",[_4,_5],{templateString:"<div class='dijitDialogUnderlayWrapper'><div class='dijitDialogUnderlay' data-dojo-attach-point='node'></div></div>",dialogId:"","class":"",_setDialogIdAttr:function(id){
_2.set(this.node,"id",id+"_underlay");
this._set("dialogId",id);
},_setClassAttr:function(_7){
this.node.className="dijitDialogUnderlay "+_7;
this._set("class",_7);
},postCreate:function(){
this.ownerDocumentBody.appendChild(this.domNode);
},layout:function(){
var is=this.node.style,os=this.domNode.style;
os.display="none";
var _8=_3.getBox(this.ownerDocument);
os.top=_8.t+"px";
os.left=_8.l+"px";
is.width=_8.w+"px";
is.height=_8.h+"px";
os.display="block";
},show:function(){
this.domNode.style.display="block";
this.layout();
this.bgIframe=new _6(this.domNode);
},hide:function(){
this.bgIframe.destroy();
delete this.bgIframe;
this.domNode.style.display="none";
}});
});

View File

@ -0,0 +1,102 @@
define("dijit/DialogUnderlay", [
"dojo/_base/declare", // declare
"dojo/dom-attr", // domAttr.set
"dojo/window", // winUtils.getBox
"./_Widget",
"./_TemplatedMixin",
"./BackgroundIframe"
], function(declare, domAttr, winUtils, _Widget, _TemplatedMixin, BackgroundIframe){
// module:
// dijit/DialogUnderlay
return declare("dijit.DialogUnderlay", [_Widget, _TemplatedMixin], {
// summary:
// The component that blocks the screen behind a `dijit.Dialog`
//
// description:
// A component used to block input behind a `dijit.Dialog`. Only a single
// instance of this widget is created by `dijit.Dialog`, and saved as
// a reference to be shared between all Dialogs as `dijit._underlay`
//
// The underlay itself can be styled based on and id:
// | #myDialog_underlay { background-color:red; }
//
// In the case of `dijit.Dialog`, this id is based on the id of the Dialog,
// suffixed with _underlay.
// Template has two divs; outer div is used for fade-in/fade-out, and also to hold background iframe.
// Inner div has opacity specified in CSS file.
templateString: "<div class='dijitDialogUnderlayWrapper'><div class='dijitDialogUnderlay' data-dojo-attach-point='node'></div></div>",
// Parameters on creation or updatable later
// dialogId: String
// Id of the dialog.... DialogUnderlay's id is based on this id
dialogId: "",
// class: String
// This class name is used on the DialogUnderlay node, in addition to dijitDialogUnderlay
"class": "",
_setDialogIdAttr: function(id){
domAttr.set(this.node, "id", id + "_underlay");
this._set("dialogId", id);
},
_setClassAttr: function(clazz){
this.node.className = "dijitDialogUnderlay " + clazz;
this._set("class", clazz);
},
postCreate: function(){
// summary:
// Append the underlay to the body
this.ownerDocumentBody.appendChild(this.domNode);
},
layout: function(){
// summary:
// Sets the background to the size of the viewport
//
// description:
// Sets the background to the size of the viewport (rather than the size
// of the document) since we need to cover the whole browser window, even
// if the document is only a few lines long.
// tags:
// private
var is = this.node.style,
os = this.domNode.style;
// hide the background temporarily, so that the background itself isn't
// causing scrollbars to appear (might happen when user shrinks browser
// window and then we are called to resize)
os.display = "none";
// then resize and show
var viewport = winUtils.getBox(this.ownerDocument);
os.top = viewport.t + "px";
os.left = viewport.l + "px";
is.width = viewport.w + "px";
is.height = viewport.h + "px";
os.display = "block";
},
show: function(){
// summary:
// Show the dialog underlay
this.domNode.style.display = "block";
this.layout();
this.bgIframe = new BackgroundIframe(this.domNode);
},
hide: function(){
// summary:
// Hides the dialog underlay
this.bgIframe.destroy();
delete this.bgIframe;
this.domNode.style.display = "none";
}
});
});

View File

@ -0,0 +1,32 @@
//>>built
require({cache:{"url:dijit/templates/Menu.html":"<table class=\"dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable\" role=\"menu\" tabIndex=\"${tabIndex}\"\n\t data-dojo-attach-event=\"onkeypress:_onKeyPress\" cellspacing=\"0\">\n\t<tbody class=\"dijitReset\" data-dojo-attach-point=\"containerNode\"></tbody>\n</table>\n"}});
define("dijit/DropDownMenu",["dojo/_base/declare","dojo/_base/event","dojo/keys","dojo/text!./templates/Menu.html","./_OnDijitClickMixin","./_MenuBase"],function(_1,_2,_3,_4,_5,_6){
return _1("dijit.DropDownMenu",[_6,_5],{templateString:_4,baseClass:"dijitMenu",postCreate:function(){
this.inherited(arguments);
var l=this.isLeftToRight();
this._openSubMenuKey=l?_3.RIGHT_ARROW:_3.LEFT_ARROW;
this._closeSubMenuKey=l?_3.LEFT_ARROW:_3.RIGHT_ARROW;
this.connectKeyNavHandlers([_3.UP_ARROW],[_3.DOWN_ARROW]);
},_onKeyPress:function(_7){
if(_7.ctrlKey||_7.altKey){
return;
}
switch(_7.charOrCode){
case this._openSubMenuKey:
this._moveToPopup(_7);
_2.stop(_7);
break;
case this._closeSubMenuKey:
if(this.parentMenu){
if(this.parentMenu._isMenuBar){
this.parentMenu.focusPrev();
}else{
this.onCancel(false);
}
}else{
_2.stop(_7);
}
break;
}
}});
});

View File

@ -0,0 +1,58 @@
require({cache:{
'url:dijit/templates/Menu.html':"<table class=\"dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable\" role=\"menu\" tabIndex=\"${tabIndex}\"\n\t data-dojo-attach-event=\"onkeypress:_onKeyPress\" cellspacing=\"0\">\n\t<tbody class=\"dijitReset\" data-dojo-attach-point=\"containerNode\"></tbody>\n</table>\n"}});
define("dijit/DropDownMenu", [
"dojo/_base/declare", // declare
"dojo/_base/event", // event.stop
"dojo/keys", // keys
"dojo/text!./templates/Menu.html",
"./_OnDijitClickMixin",
"./_MenuBase"
], function(declare, event, keys, template, _OnDijitClickMixin, _MenuBase){
// module:
// dijit/DropDownMenu
return declare("dijit.DropDownMenu", [_MenuBase, _OnDijitClickMixin], {
// summary:
// A menu, without features for context menu (Meaning, drop down menu)
templateString: template,
baseClass: "dijitMenu",
postCreate: function(){
this.inherited(arguments);
var l = this.isLeftToRight();
this._openSubMenuKey = l ? keys.RIGHT_ARROW : keys.LEFT_ARROW;
this._closeSubMenuKey = l ? keys.LEFT_ARROW : keys.RIGHT_ARROW;
this.connectKeyNavHandlers([keys.UP_ARROW], [keys.DOWN_ARROW]);
},
_onKeyPress: function(/*Event*/ evt){
// summary:
// Handle keyboard based menu navigation.
// tags:
// protected
if(evt.ctrlKey || evt.altKey){ return; }
switch(evt.charOrCode){
case this._openSubMenuKey:
this._moveToPopup(evt);
event.stop(evt);
break;
case this._closeSubMenuKey:
if(this.parentMenu){
if(this.parentMenu._isMenuBar){
this.parentMenu.focusPrev();
}else{
this.onCancel(false);
}
}else{
event.stop(evt);
}
break;
}
}
});
});

View File

@ -0,0 +1,462 @@
//>>built
define("dijit/Editor",["require","dojo/_base/array","dojo/_base/declare","dojo/_base/Deferred","dojo/i18n","dojo/dom-attr","dojo/dom-class","dojo/dom-geometry","dojo/dom-style","dojo/_base/event","dojo/keys","dojo/_base/lang","dojo/sniff","dojo/string","dojo/topic","dojo/_base/window","./_base/focus","./_Container","./Toolbar","./ToolbarSeparator","./layout/_LayoutWidget","./form/ToggleButton","./_editor/_Plugin","./_editor/plugins/EnterKeyHandling","./_editor/html","./_editor/range","./_editor/RichText","./main","dojo/i18n!./_editor/nls/commands"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c,_d,_e,_f,win,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_1a,_1b){
var _1c=_3("dijit.Editor",_1a,{plugins:null,extraPlugins:null,constructor:function(){
if(!_c.isArray(this.plugins)){
this.plugins=["undo","redo","|","cut","copy","paste","|","bold","italic","underline","strikethrough","|","insertOrderedList","insertUnorderedList","indent","outdent","|","justifyLeft","justifyRight","justifyCenter","justifyFull",_17];
}
this._plugins=[];
this._editInterval=this.editActionInterval*1000;
if(_d("ie")){
this.events.push("onBeforeDeactivate");
this.events.push("onBeforeActivate");
}
},postMixInProperties:function(){
this.setValueDeferred=new _4();
this.inherited(arguments);
},postCreate:function(){
this._steps=this._steps.slice(0);
this._undoedSteps=this._undoedSteps.slice(0);
if(_c.isArray(this.extraPlugins)){
this.plugins=this.plugins.concat(this.extraPlugins);
}
this.inherited(arguments);
this.commands=_5.getLocalization("dijit._editor","commands",this.lang);
if(!this.toolbar){
this.toolbar=new _12({ownerDocument:this.ownerDocument,dir:this.dir,lang:this.lang});
this.header.appendChild(this.toolbar.domNode);
}
_2.forEach(this.plugins,this.addPlugin,this);
this.setValueDeferred.resolve(true);
_7.add(this.iframe.parentNode,"dijitEditorIFrameContainer");
_7.add(this.iframe,"dijitEditorIFrame");
_6.set(this.iframe,"allowTransparency",true);
if(_d("webkit")){
_9.set(this.domNode,"KhtmlUserSelect","none");
}
this.toolbar.startup();
this.onNormalizedDisplayChanged();
},destroy:function(){
_2.forEach(this._plugins,function(p){
if(p&&p.destroy){
p.destroy();
}
});
this._plugins=[];
this.toolbar.destroyRecursive();
delete this.toolbar;
this.inherited(arguments);
},addPlugin:function(_1d,_1e){
var _1f=_c.isString(_1d)?{name:_1d}:_c.isFunction(_1d)?{ctor:_1d}:_1d;
if(!_1f.setEditor){
var o={"args":_1f,"plugin":null,"editor":this};
if(_1f.name){
if(_16.registry[_1f.name]){
o.plugin=_16.registry[_1f.name](_1f);
}else{
_f.publish(_1b._scopeName+".Editor.getPlugin",o);
}
}
if(!o.plugin){
try{
var pc=_1f.ctor||_c.getObject(_1f.name)||_1(_1f.name);
if(pc){
o.plugin=new pc(_1f);
}
}
catch(e){
throw new Error(this.id+": cannot find plugin ["+_1f.name+"]");
}
}
if(!o.plugin){
throw new Error(this.id+": cannot find plugin ["+_1f.name+"]");
}
_1d=o.plugin;
}
if(arguments.length>1){
this._plugins[_1e]=_1d;
}else{
this._plugins.push(_1d);
}
_1d.setEditor(this);
if(_c.isFunction(_1d.setToolbar)){
_1d.setToolbar(this.toolbar);
}
},resize:function(_20){
if(_20){
_14.prototype.resize.apply(this,arguments);
}
},layout:function(){
var _21=(this._contentBox.h-(this.getHeaderHeight()+this.getFooterHeight()+_8.getPadBorderExtents(this.iframe.parentNode).h+_8.getMarginExtents(this.iframe.parentNode).h));
this.editingArea.style.height=_21+"px";
if(this.iframe){
this.iframe.style.height="100%";
}
this._layoutMode=true;
},_onIEMouseDown:function(e){
var _22;
var b=this.document.body;
var _23=b.clientWidth;
var _24=b.clientHeight;
var _25=b.clientLeft;
var _26=b.offsetWidth;
var _27=b.offsetHeight;
var _28=b.offsetLeft;
if(/^rtl$/i.test(b.dir||"")){
if(_23<_26&&e.x>_23&&e.x<_26){
_22=true;
}
}else{
if(e.x<_25&&e.x>_28){
_22=true;
}
}
if(!_22){
if(_24<_27&&e.y>_24&&e.y<_27){
_22=true;
}
}
if(!_22){
delete this._cursorToStart;
delete this._savedSelection;
if(e.target.tagName=="BODY"){
this.defer("placeCursorAtEnd");
}
this.inherited(arguments);
}
},onBeforeActivate:function(){
this._restoreSelection();
},onBeforeDeactivate:function(e){
if(this.customUndo){
this.endEditing(true);
}
if(e.target.tagName!="BODY"){
this._saveSelection();
}
},customUndo:true,editActionInterval:3,beginEditing:function(cmd){
if(!this._inEditing){
this._inEditing=true;
this._beginEditing(cmd);
}
if(this.editActionInterval>0){
if(this._editTimer){
this._editTimer.remove();
}
this._editTimer=this.defer("endEditing",this._editInterval);
}
},_steps:[],_undoedSteps:[],execCommand:function(cmd){
if(this.customUndo&&(cmd=="undo"||cmd=="redo")){
return this[cmd]();
}else{
if(this.customUndo){
this.endEditing();
this._beginEditing();
}
var r=this.inherited(arguments);
if(this.customUndo){
this._endEditing();
}
return r;
}
},_pasteImpl:function(){
return this._clipboardCommand("paste");
},_cutImpl:function(){
return this._clipboardCommand("cut");
},_copyImpl:function(){
return this._clipboardCommand("copy");
},_clipboardCommand:function(cmd){
var r;
try{
r=this.document.execCommand(cmd,false,null);
if(_d("webkit")&&!r){
throw {code:1011};
}
}
catch(e){
if(e.code==1011||(e.code==9&&_d("opera"))){
var sub=_e.substitute,_29={cut:"X",copy:"C",paste:"V"};
alert(sub(this.commands.systemShortcut,[this.commands[cmd],sub(this.commands[_d("mac")?"appleKey":"ctrlKey"],[_29[cmd]])]));
}
r=false;
}
return r;
},queryCommandEnabled:function(cmd){
if(this.customUndo&&(cmd=="undo"||cmd=="redo")){
return cmd=="undo"?(this._steps.length>1):(this._undoedSteps.length>0);
}else{
return this.inherited(arguments);
}
},_moveToBookmark:function(b){
var _2a=b.mark;
var _2b=b.mark;
var col=b.isCollapsed;
var r,_2c,_2d,sel;
if(_2b){
if(_d("ie")<9){
if(_c.isArray(_2b)){
_2a=[];
_2.forEach(_2b,function(n){
_2a.push(_19.getNode(n,this.editNode));
},this);
win.withGlobal(this.window,"moveToBookmark",_10,[{mark:_2a,isCollapsed:col}]);
}else{
if(_2b.startContainer&&_2b.endContainer){
sel=_19.getSelection(this.window);
if(sel&&sel.removeAllRanges){
sel.removeAllRanges();
r=_19.create(this.window);
_2c=_19.getNode(_2b.startContainer,this.editNode);
_2d=_19.getNode(_2b.endContainer,this.editNode);
if(_2c&&_2d){
r.setStart(_2c,_2b.startOffset);
r.setEnd(_2d,_2b.endOffset);
sel.addRange(r);
}
}
}
}
}else{
sel=_19.getSelection(this.window);
if(sel&&sel.removeAllRanges){
sel.removeAllRanges();
r=_19.create(this.window);
_2c=_19.getNode(_2b.startContainer,this.editNode);
_2d=_19.getNode(_2b.endContainer,this.editNode);
if(_2c&&_2d){
r.setStart(_2c,_2b.startOffset);
r.setEnd(_2d,_2b.endOffset);
sel.addRange(r);
}
}
}
}
},_changeToStep:function(_2e,to){
this.setValue(to.text);
var b=to.bookmark;
if(!b){
return;
}
this._moveToBookmark(b);
},undo:function(){
var ret=false;
if(!this._undoRedoActive){
this._undoRedoActive=true;
this.endEditing(true);
var s=this._steps.pop();
if(s&&this._steps.length>0){
this.focus();
this._changeToStep(s,this._steps[this._steps.length-1]);
this._undoedSteps.push(s);
this.onDisplayChanged();
delete this._undoRedoActive;
ret=true;
}
delete this._undoRedoActive;
}
return ret;
},redo:function(){
var ret=false;
if(!this._undoRedoActive){
this._undoRedoActive=true;
this.endEditing(true);
var s=this._undoedSteps.pop();
if(s&&this._steps.length>0){
this.focus();
this._changeToStep(this._steps[this._steps.length-1],s);
this._steps.push(s);
this.onDisplayChanged();
ret=true;
}
delete this._undoRedoActive;
}
return ret;
},endEditing:function(_2f){
if(this._editTimer){
this._editTimer=this._editTimer.remove();
}
if(this._inEditing){
this._endEditing(_2f);
this._inEditing=false;
}
},_getBookmark:function(){
var b=win.withGlobal(this.window,_10.getBookmark);
var tmp=[];
if(b&&b.mark){
var _30=b.mark;
if(_d("ie")<9){
var sel=_19.getSelection(this.window);
if(!_c.isArray(_30)){
if(sel){
var _31;
if(sel.rangeCount){
_31=sel.getRangeAt(0);
}
if(_31){
b.mark=_31.cloneRange();
}else{
b.mark=win.withGlobal(this.window,_10.getBookmark);
}
}
}else{
_2.forEach(b.mark,function(n){
tmp.push(_19.getIndex(n,this.editNode).o);
},this);
b.mark=tmp;
}
}
try{
if(b.mark&&b.mark.startContainer){
tmp=_19.getIndex(b.mark.startContainer,this.editNode).o;
b.mark={startContainer:tmp,startOffset:b.mark.startOffset,endContainer:b.mark.endContainer===b.mark.startContainer?tmp:_19.getIndex(b.mark.endContainer,this.editNode).o,endOffset:b.mark.endOffset};
}
}
catch(e){
b.mark=null;
}
}
return b;
},_beginEditing:function(){
if(this._steps.length===0){
this._steps.push({"text":_18.getChildrenHtml(this.editNode),"bookmark":this._getBookmark()});
}
},_endEditing:function(){
var v=_18.getChildrenHtml(this.editNode);
this._undoedSteps=[];
this._steps.push({text:v,bookmark:this._getBookmark()});
},onKeyDown:function(e){
if(!_d("ie")&&!this.iframe&&e.keyCode==_b.TAB&&!this.tabIndent){
this._saveSelection();
}
if(!this.customUndo){
this.inherited(arguments);
return;
}
var k=e.keyCode;
if(e.ctrlKey&&!e.altKey){
if(k==90||k==122){
_a.stop(e);
this.undo();
return;
}else{
if(k==89||k==121){
_a.stop(e);
this.redo();
return;
}
}
}
this.inherited(arguments);
switch(k){
case _b.ENTER:
case _b.BACKSPACE:
case _b.DELETE:
this.beginEditing();
break;
case 88:
case 86:
if(e.ctrlKey&&!e.altKey&&!e.metaKey){
this.endEditing();
if(e.keyCode==88){
this.beginEditing("cut");
}else{
this.beginEditing("paste");
}
this.defer("endEditing",1);
break;
}
default:
if(!e.ctrlKey&&!e.altKey&&!e.metaKey&&(e.keyCode<_b.F1||e.keyCode>_b.F15)){
this.beginEditing();
break;
}
case _b.ALT:
this.endEditing();
break;
case _b.UP_ARROW:
case _b.DOWN_ARROW:
case _b.LEFT_ARROW:
case _b.RIGHT_ARROW:
case _b.HOME:
case _b.END:
case _b.PAGE_UP:
case _b.PAGE_DOWN:
this.endEditing(true);
break;
case _b.CTRL:
case _b.SHIFT:
case _b.TAB:
break;
}
},_onBlur:function(){
this.inherited(arguments);
this.endEditing(true);
},_saveSelection:function(){
try{
this._savedSelection=this._getBookmark();
}
catch(e){
}
},_restoreSelection:function(){
if(this._savedSelection){
delete this._cursorToStart;
if(win.withGlobal(this.window,"isCollapsed",_10)){
this._moveToBookmark(this._savedSelection);
}
delete this._savedSelection;
}
},onClick:function(){
this.endEditing(true);
this.inherited(arguments);
},replaceValue:function(_32){
if(!this.customUndo){
this.inherited(arguments);
}else{
if(this.isClosed){
this.setValue(_32);
}else{
this.beginEditing();
if(!_32){
_32="&#160;";
}
this.setValue(_32);
this.endEditing();
}
}
},_setDisabledAttr:function(_33){
this.setValueDeferred.then(_c.hitch(this,function(){
if((!this.disabled&&_33)||(!this._buttonEnabledPlugins&&_33)){
_2.forEach(this._plugins,function(p){
p.set("disabled",true);
});
}else{
if(this.disabled&&!_33){
_2.forEach(this._plugins,function(p){
p.set("disabled",false);
});
}
}
}));
this.inherited(arguments);
},_setStateClass:function(){
try{
this.inherited(arguments);
if(this.document&&this.document.body){
_9.set(this.document.body,"color",_9.get(this.iframe,"color"));
}
}
catch(e){
}
}});
function _34(_35){
return new _16({command:_35.name});
};
function _36(_37){
return new _16({buttonClass:_15,command:_37.name});
};
_c.mixin(_16.registry,{"undo":_34,"redo":_34,"cut":_34,"copy":_34,"paste":_34,"insertOrderedList":_34,"insertUnorderedList":_34,"indent":_34,"outdent":_34,"justifyCenter":_34,"justifyFull":_34,"justifyLeft":_34,"justifyRight":_34,"delete":_34,"selectAll":_34,"removeFormat":_34,"unlink":_34,"insertHorizontalRule":_34,"bold":_36,"italic":_36,"underline":_36,"strikethrough":_36,"subscript":_36,"superscript":_36,"|":function(){
return new _16({setEditor:function(_38){
this.editor=_38;
this.button=new _13({ownerDocument:_38.ownerDocument});
}});
}});
return _1c;
});

View File

@ -0,0 +1,865 @@
define("dijit/Editor", [
"require",
"dojo/_base/array", // array.forEach
"dojo/_base/declare", // declare
"dojo/_base/Deferred", // Deferred
"dojo/i18n", // i18n.getLocalization
"dojo/dom-attr", // domAttr.set
"dojo/dom-class", // domClass.add
"dojo/dom-geometry",
"dojo/dom-style", // domStyle.set, get
"dojo/_base/event", // event.stop
"dojo/keys", // keys.F1 keys.F15 keys.TAB
"dojo/_base/lang", // lang.getObject lang.hitch
"dojo/sniff", // has("ie") has("mac") has("webkit")
"dojo/string", // string.substitute
"dojo/topic", // topic.publish()
"dojo/_base/window", // win.withGlobal
"./_base/focus", // dijit.getBookmark()
"./_Container",
"./Toolbar",
"./ToolbarSeparator",
"./layout/_LayoutWidget",
"./form/ToggleButton",
"./_editor/_Plugin",
"./_editor/plugins/EnterKeyHandling",
"./_editor/html",
"./_editor/range",
"./_editor/RichText",
"./main", // dijit._scopeName
"dojo/i18n!./_editor/nls/commands"
], function(require, array, declare, Deferred, i18n, domAttr, domClass, domGeometry, domStyle,
event, keys, lang, has, string, topic, win,
focusBase, _Container, Toolbar, ToolbarSeparator, _LayoutWidget, ToggleButton,
_Plugin, EnterKeyHandling, html, rangeapi, RichText, dijit){
// module:
// dijit/Editor
var Editor = declare("dijit.Editor", RichText, {
// summary:
// A rich text Editing widget
//
// description:
// This widget provides basic WYSIWYG editing features, based on the browser's
// underlying rich text editing capability, accompanied by a toolbar (`dijit.Toolbar`).
// A plugin model is available to extend the editor's capabilities as well as the
// the options available in the toolbar. Content generation may vary across
// browsers, and clipboard operations may have different results, to name
// a few limitations. Note: this widget should not be used with the HTML
// &lt;TEXTAREA&gt; tag -- see dijit/_editor/RichText for details.
// plugins: [const] Object[]
// A list of plugin names (as strings) or instances (as objects)
// for this widget.
//
// When declared in markup, it might look like:
// | plugins="['bold',{name:'dijit._editor.plugins.FontChoice', command:'fontName', generic:true}]"
plugins: null,
// extraPlugins: [const] Object[]
// A list of extra plugin names which will be appended to plugins array
extraPlugins: null,
constructor: function(/*===== params, srcNodeRef =====*/){
// summary:
// Create the widget.
// params: Object|null
// Initial settings for any of the attributes, except readonly attributes.
// srcNodeRef: DOMNode
// The editor replaces the specified DOMNode.
if(!lang.isArray(this.plugins)){
this.plugins=["undo","redo","|","cut","copy","paste","|","bold","italic","underline","strikethrough","|",
"insertOrderedList","insertUnorderedList","indent","outdent","|","justifyLeft","justifyRight","justifyCenter","justifyFull",
EnterKeyHandling /*, "createLink"*/];
}
this._plugins=[];
this._editInterval = this.editActionInterval * 1000;
//IE will always lose focus when other element gets focus, while for FF and safari,
//when no iframe is used, focus will be lost whenever another element gets focus.
//For IE, we can connect to onBeforeDeactivate, which will be called right before
//the focus is lost, so we can obtain the selected range. For other browsers,
//no equivalent of onBeforeDeactivate, so we need to do two things to make sure
//selection is properly saved before focus is lost: 1) when user clicks another
//element in the page, in which case we listen to mousedown on the entire page and
//see whether user clicks out of a focus editor, if so, save selection (focus will
//only lost after onmousedown event is fired, so we can obtain correct caret pos.)
//2) when user tabs away from the editor, which is handled in onKeyDown below.
if(has("ie")){
this.events.push("onBeforeDeactivate");
this.events.push("onBeforeActivate");
}
},
postMixInProperties: function(){
// summary:
// Extension to make sure a deferred is in place before certain functions
// execute, like making sure all the plugins are properly inserted.
// Set up a deferred so that the value isn't applied to the editor
// until all the plugins load, needed to avoid timing condition
// reported in #10537.
this.setValueDeferred = new Deferred();
this.inherited(arguments);
},
postCreate: function(){
//for custom undo/redo, if enabled.
this._steps=this._steps.slice(0);
this._undoedSteps=this._undoedSteps.slice(0);
if(lang.isArray(this.extraPlugins)){
this.plugins=this.plugins.concat(this.extraPlugins);
}
this.inherited(arguments);
this.commands = i18n.getLocalization("dijit._editor", "commands", this.lang);
if(!this.toolbar){
// if we haven't been assigned a toolbar, create one
this.toolbar = new Toolbar({
ownerDocument: this.ownerDocument,
dir: this.dir,
lang: this.lang
});
this.header.appendChild(this.toolbar.domNode);
}
array.forEach(this.plugins, this.addPlugin, this);
// Okay, denote the value can now be set.
this.setValueDeferred.resolve(true);
domClass.add(this.iframe.parentNode, "dijitEditorIFrameContainer");
domClass.add(this.iframe, "dijitEditorIFrame");
domAttr.set(this.iframe, "allowTransparency", true);
if(has("webkit")){
// Disable selecting the entire editor by inadvertent double-clicks.
// on buttons, title bar, etc. Otherwise clicking too fast on
// a button such as undo/redo selects the entire editor.
domStyle.set(this.domNode, "KhtmlUserSelect", "none");
}
this.toolbar.startup();
this.onNormalizedDisplayChanged(); //update toolbar button status
},
destroy: function(){
array.forEach(this._plugins, function(p){
if(p && p.destroy){
p.destroy();
}
});
this._plugins=[];
this.toolbar.destroyRecursive();
delete this.toolbar;
this.inherited(arguments);
},
addPlugin: function(/*String||Object||Function*/ plugin, /*Integer?*/ index){
// summary:
// takes a plugin name as a string or a plugin instance and
// adds it to the toolbar and associates it with this editor
// instance. The resulting plugin is added to the Editor's
// plugins array. If index is passed, it's placed in the plugins
// array at that index. No big magic, but a nice helper for
// passing in plugin names via markup.
// plugin:
// String, args object, plugin instance, or plugin constructor
// args:
// This object will be passed to the plugin constructor
// index:
// Used when creating an instance from
// something already in this.plugins. Ensures that the new
// instance is assigned to this.plugins at that index.
var args=lang.isString(plugin)?{name:plugin}:lang.isFunction(plugin)?{ctor:plugin}:plugin;
if(!args.setEditor){
var o={"args":args,"plugin":null,"editor":this};
if(args.name){
// search registry for a plugin factory matching args.name, if it's not there then
// fallback to 1.0 API:
// ask all loaded plugin modules to fill in o.plugin if they can (ie, if they implement args.name)
// remove fallback for 2.0.
if(_Plugin.registry[args.name]){
o.plugin = _Plugin.registry[args.name](args);
}else{
topic.publish(dijit._scopeName + ".Editor.getPlugin", o); // publish
}
}
if(!o.plugin){
try{
// TODO: remove lang.getObject() call in 2.0
var pc = args.ctor || lang.getObject(args.name) || require(args.name);
if(pc){
o.plugin = new pc(args);
}
}catch(e){
throw new Error(this.id + ": cannot find plugin [" + args.name + "]");
}
}
if(!o.plugin){
throw new Error(this.id + ": cannot find plugin [" + args.name + "]");
}
plugin=o.plugin;
}
if(arguments.length > 1){
this._plugins[index] = plugin;
}else{
this._plugins.push(plugin);
}
plugin.setEditor(this);
if(lang.isFunction(plugin.setToolbar)){
plugin.setToolbar(this.toolbar);
}
},
//the following 2 functions are required to make the editor play nice under a layout widget, see #4070
resize: function(size){
// summary:
// Resize the editor to the specified size, see `dijit/layout/_LayoutWidget.resize()`
if(size){
// we've been given a height/width for the entire editor (toolbar + contents), calls layout()
// to split the allocated size between the toolbar and the contents
_LayoutWidget.prototype.resize.apply(this, arguments);
}
/*
else{
// do nothing, the editor is already laid out correctly. The user has probably specified
// the height parameter, which was used to set a size on the iframe
}
*/
},
layout: function(){
// summary:
// Called from `dijit/layout/_LayoutWidget.resize()`. This shouldn't be called directly
// tags:
// protected
// Converts the iframe (or rather the <div> surrounding it) to take all the available space
// except what's needed for the header (toolbars) and footer (breadcrumbs, etc).
// A class was added to the iframe container and some themes style it, so we have to
// calc off the added margins and padding too. See tracker: #10662
var areaHeight = (this._contentBox.h -
(this.getHeaderHeight() + this.getFooterHeight() +
domGeometry.getPadBorderExtents(this.iframe.parentNode).h +
domGeometry.getMarginExtents(this.iframe.parentNode).h));
this.editingArea.style.height = areaHeight + "px";
if(this.iframe){
this.iframe.style.height="100%";
}
this._layoutMode = true;
},
_onIEMouseDown: function(/*Event*/ e){
// summary:
// IE only to prevent 2 clicks to focus
// tags:
// private
var outsideClientArea;
// IE 8's componentFromPoint is broken, which is a shame since it
// was smaller code, but oh well. We have to do this brute force
// to detect if the click was scroller or not.
var b = this.document.body;
var clientWidth = b.clientWidth;
var clientHeight = b.clientHeight;
var clientLeft = b.clientLeft;
var offsetWidth = b.offsetWidth;
var offsetHeight = b.offsetHeight;
var offsetLeft = b.offsetLeft;
//Check for vertical scroller click.
if(/^rtl$/i.test(b.dir || "")){
if(clientWidth < offsetWidth && e.x > clientWidth && e.x < offsetWidth){
// Check the click was between width and offset width, if so, scroller
outsideClientArea = true;
}
}else{
// RTL mode, we have to go by the left offsets.
if(e.x < clientLeft && e.x > offsetLeft){
// Check the click was between width and offset width, if so, scroller
outsideClientArea = true;
}
}
if(!outsideClientArea){
// Okay, might be horiz scroller, check that.
if(clientHeight < offsetHeight && e.y > clientHeight && e.y < offsetHeight){
// Horizontal scroller.
outsideClientArea = true;
}
}
if(!outsideClientArea){
delete this._cursorToStart; // Remove the force to cursor to start position.
delete this._savedSelection; // new mouse position overrides old selection
if(e.target.tagName == "BODY"){
this.defer("placeCursorAtEnd");
}
this.inherited(arguments);
}
},
onBeforeActivate: function(){
this._restoreSelection();
},
onBeforeDeactivate: function(e){
// summary:
// Called on IE right before focus is lost. Saves the selected range.
// tags:
// private
if(this.customUndo){
this.endEditing(true);
}
//in IE, the selection will be lost when other elements get focus,
//let's save focus before the editor is deactivated
if(e.target.tagName != "BODY"){
this._saveSelection();
}
//console.log('onBeforeDeactivate',this);
},
/* beginning of custom undo/redo support */
// customUndo: Boolean
// Whether we shall use custom undo/redo support instead of the native
// browser support. By default, we now use custom undo. It works better
// than native browser support and provides a consistent behavior across
// browsers with a minimal performance hit. We already had the hit on
// the slowest browser, IE, anyway.
customUndo: true,
// editActionInterval: Integer
// When using customUndo, not every keystroke will be saved as a step.
// Instead typing (including delete) will be grouped together: after
// a user stops typing for editActionInterval seconds, a step will be
// saved; if a user resume typing within editActionInterval seconds,
// the timeout will be restarted. By default, editActionInterval is 3
// seconds.
editActionInterval: 3,
beginEditing: function(cmd){
// summary:
// Called to note that the user has started typing alphanumeric characters, if it's not already noted.
// Deals with saving undo; see editActionInterval parameter.
// tags:
// private
if(!this._inEditing){
this._inEditing=true;
this._beginEditing(cmd);
}
if(this.editActionInterval>0){
if(this._editTimer){
this._editTimer.remove();
}
this._editTimer = this.defer("endEditing", this._editInterval);
}
},
// TODO: declaring these in the prototype is meaningless, just create in the constructor/postCreate
_steps:[],
_undoedSteps:[],
execCommand: function(cmd){
// summary:
// Main handler for executing any commands to the editor, like paste, bold, etc.
// Called by plugins, but not meant to be called by end users.
// tags:
// protected
if(this.customUndo && (cmd == 'undo' || cmd == 'redo')){
return this[cmd]();
}else{
if(this.customUndo){
this.endEditing();
this._beginEditing();
}
var r = this.inherited(arguments);
if(this.customUndo){
this._endEditing();
}
return r;
}
},
_pasteImpl: function(){
// summary:
// Over-ride of paste command control to make execCommand cleaner
// tags:
// Protected
return this._clipboardCommand("paste");
},
_cutImpl: function(){
// summary:
// Over-ride of cut command control to make execCommand cleaner
// tags:
// Protected
return this._clipboardCommand("cut");
},
_copyImpl: function(){
// summary:
// Over-ride of copy command control to make execCommand cleaner
// tags:
// Protected
return this._clipboardCommand("copy");
},
_clipboardCommand: function(cmd){
// summary:
// Function to handle processing clipboard commands (or at least try to).
// tags:
// Private
var r;
try{
// Try to exec the superclass exec-command and see if it works.
r = this.document.execCommand(cmd, false, null);
if(has("webkit") && !r){ //see #4598: webkit does not guarantee clipboard support from js
throw { code: 1011 }; // throw an object like Mozilla's error
}
}catch(e){
//TODO: when else might we get an exception? Do we need the Mozilla test below?
if(e.code == 1011 /* Mozilla: service denied */ ||
(e.code == 9 && has("opera") /* Opera not supported */)){
// Warn user of platform limitation. Cannot programmatically access clipboard. See ticket #4136
var sub = string.substitute,
accel = {cut:'X', copy:'C', paste:'V'};
alert(sub(this.commands.systemShortcut,
[this.commands[cmd], sub(this.commands[has("mac") ? 'appleKey' : 'ctrlKey'], [accel[cmd]])]));
}
r = false;
}
return r;
},
queryCommandEnabled: function(cmd){
// summary:
// Returns true if specified editor command is enabled.
// Used by the plugins to know when to highlight/not highlight buttons.
// tags:
// protected
if(this.customUndo && (cmd == 'undo' || cmd == 'redo')){
return cmd == 'undo' ? (this._steps.length > 1) : (this._undoedSteps.length > 0);
}else{
return this.inherited(arguments);
}
},
_moveToBookmark: function(b){
// summary:
// Selects the text specified in bookmark b
// tags:
// private
var bookmark = b.mark;
var mark = b.mark;
var col = b.isCollapsed;
var r, sNode, eNode, sel;
if(mark){
if(has("ie") < 9){
if(lang.isArray(mark)){
//IE CONTROL, have to use the native bookmark.
bookmark = [];
array.forEach(mark,function(n){
bookmark.push(rangeapi.getNode(n,this.editNode));
},this);
win.withGlobal(this.window,'moveToBookmark',focusBase,[{mark: bookmark, isCollapsed: col}]);
}else{
if(mark.startContainer && mark.endContainer){
// Use the pseudo WC3 range API. This works better for positions
// than the IE native bookmark code.
sel = rangeapi.getSelection(this.window);
if(sel && sel.removeAllRanges){
sel.removeAllRanges();
r = rangeapi.create(this.window);
sNode = rangeapi.getNode(mark.startContainer,this.editNode);
eNode = rangeapi.getNode(mark.endContainer,this.editNode);
if(sNode && eNode){
// Okay, we believe we found the position, so add it into the selection
// There are cases where it may not be found, particularly in undo/redo, when
// IE changes the underlying DOM on us (wraps text in a <p> tag or similar.
// So, in those cases, don't bother restoring selection.
r.setStart(sNode,mark.startOffset);
r.setEnd(eNode,mark.endOffset);
sel.addRange(r);
}
}
}
}
}else{//w3c range
sel = rangeapi.getSelection(this.window);
if(sel && sel.removeAllRanges){
sel.removeAllRanges();
r = rangeapi.create(this.window);
sNode = rangeapi.getNode(mark.startContainer,this.editNode);
eNode = rangeapi.getNode(mark.endContainer,this.editNode);
if(sNode && eNode){
// Okay, we believe we found the position, so add it into the selection
// There are cases where it may not be found, particularly in undo/redo, when
// formatting as been done and so on, so don't restore selection then.
r.setStart(sNode,mark.startOffset);
r.setEnd(eNode,mark.endOffset);
sel.addRange(r);
}
}
}
}
},
_changeToStep: function(from, to){
// summary:
// Reverts editor to "to" setting, from the undo stack.
// tags:
// private
this.setValue(to.text);
var b=to.bookmark;
if(!b){ return; }
this._moveToBookmark(b);
},
undo: function(){
// summary:
// Handler for editor undo (ex: ctrl-z) operation
// tags:
// private
var ret = false;
if(!this._undoRedoActive){
this._undoRedoActive = true;
this.endEditing(true);
var s=this._steps.pop();
if(s && this._steps.length>0){
this.focus();
this._changeToStep(s,this._steps[this._steps.length-1]);
this._undoedSteps.push(s);
this.onDisplayChanged();
delete this._undoRedoActive;
ret = true;
}
delete this._undoRedoActive;
}
return ret;
},
redo: function(){
// summary:
// Handler for editor redo (ex: ctrl-y) operation
// tags:
// private
var ret = false;
if(!this._undoRedoActive){
this._undoRedoActive = true;
this.endEditing(true);
var s=this._undoedSteps.pop();
if(s && this._steps.length>0){
this.focus();
this._changeToStep(this._steps[this._steps.length-1],s);
this._steps.push(s);
this.onDisplayChanged();
ret = true;
}
delete this._undoRedoActive;
}
return ret;
},
endEditing: function(ignore_caret){
// summary:
// Called to note that the user has stopped typing alphanumeric characters, if it's not already noted.
// Deals with saving undo; see editActionInterval parameter.
// tags:
// private
if(this._editTimer){
this._editTimer = this._editTimer.remove();
}
if(this._inEditing){
this._endEditing(ignore_caret);
this._inEditing=false;
}
},
_getBookmark: function(){
// summary:
// Get the currently selected text
// tags:
// protected
var b=win.withGlobal(this.window,focusBase.getBookmark);
var tmp=[];
if(b && b.mark){
var mark = b.mark;
if(has("ie") < 9){
// Try to use the pseudo range API on IE for better accuracy.
var sel = rangeapi.getSelection(this.window);
if(!lang.isArray(mark)){
if(sel){
var range;
if(sel.rangeCount){
range = sel.getRangeAt(0);
}
if(range){
b.mark = range.cloneRange();
}else{
b.mark = win.withGlobal(this.window,focusBase.getBookmark);
}
}
}else{
// Control ranges (img, table, etc), handle differently.
array.forEach(b.mark,function(n){
tmp.push(rangeapi.getIndex(n,this.editNode).o);
},this);
b.mark = tmp;
}
}
try{
if(b.mark && b.mark.startContainer){
tmp=rangeapi.getIndex(b.mark.startContainer,this.editNode).o;
b.mark={startContainer:tmp,
startOffset:b.mark.startOffset,
endContainer:b.mark.endContainer===b.mark.startContainer?tmp:rangeapi.getIndex(b.mark.endContainer,this.editNode).o,
endOffset:b.mark.endOffset};
}
}catch(e){
b.mark = null;
}
}
return b;
},
_beginEditing: function(){
// summary:
// Called when the user starts typing alphanumeric characters.
// Deals with saving undo; see editActionInterval parameter.
// tags:
// private
if(this._steps.length === 0){
// You want to use the editor content without post filtering
// to make sure selection restores right for the 'initial' state.
// and undo is called. So not using this.value, as it was 'processed'
// and the line-up for selections may have been altered.
this._steps.push({'text':html.getChildrenHtml(this.editNode),'bookmark':this._getBookmark()});
}
},
_endEditing: function(){
// summary:
// Called when the user stops typing alphanumeric characters.
// Deals with saving undo; see editActionInterval parameter.
// tags:
// private
// Avoid filtering to make sure selections restore.
var v = html.getChildrenHtml(this.editNode);
this._undoedSteps=[];//clear undoed steps
this._steps.push({text: v, bookmark: this._getBookmark()});
},
onKeyDown: function(e){
// summary:
// Handler for onkeydown event.
// tags:
// private
//We need to save selection if the user TAB away from this editor
//no need to call _saveSelection for IE, as that will be taken care of in onBeforeDeactivate
if(!has("ie") && !this.iframe && e.keyCode == keys.TAB && !this.tabIndent){
this._saveSelection();
}
if(!this.customUndo){
this.inherited(arguments);
return;
}
var k = e.keyCode;
if(e.ctrlKey && !e.altKey){//undo and redo only if the special right Alt + z/y are not pressed #5892
if(k == 90 || k == 122){ //z
event.stop(e);
this.undo();
return;
}else if(k == 89 || k == 121){ //y
event.stop(e);
this.redo();
return;
}
}
this.inherited(arguments);
switch(k){
case keys.ENTER:
case keys.BACKSPACE:
case keys.DELETE:
this.beginEditing();
break;
case 88: //x
case 86: //v
if(e.ctrlKey && !e.altKey && !e.metaKey){
this.endEditing();//end current typing step if any
if(e.keyCode == 88){
this.beginEditing('cut');
}else{
this.beginEditing('paste');
}
//use timeout to trigger after the paste is complete
this.defer("endEditing", 1);
break;
}
//pass through
default:
if(!e.ctrlKey && !e.altKey && !e.metaKey && (e.keyCode<keys.F1 || e.keyCode>keys.F15)){
this.beginEditing();
break;
}
//pass through
case keys.ALT:
this.endEditing();
break;
case keys.UP_ARROW:
case keys.DOWN_ARROW:
case keys.LEFT_ARROW:
case keys.RIGHT_ARROW:
case keys.HOME:
case keys.END:
case keys.PAGE_UP:
case keys.PAGE_DOWN:
this.endEditing(true);
break;
//maybe ctrl+backspace/delete, so don't endEditing when ctrl is pressed
case keys.CTRL:
case keys.SHIFT:
case keys.TAB:
break;
}
},
_onBlur: function(){
// summary:
// Called from focus manager when focus has moved away from this editor
// tags:
// protected
//this._saveSelection();
this.inherited(arguments);
this.endEditing(true);
},
_saveSelection: function(){
// summary:
// Save the currently selected text in _savedSelection attribute
// tags:
// private
try{
this._savedSelection=this._getBookmark();
}catch(e){ /* Squelch any errors that occur if selection save occurs due to being hidden simultaneously. */}
},
_restoreSelection: function(){
// summary:
// Re-select the text specified in _savedSelection attribute;
// see _saveSelection().
// tags:
// private
if(this._savedSelection){
// Clear off cursor to start, we're deliberately going to a selection.
delete this._cursorToStart;
// only restore the selection if the current range is collapsed
// if not collapsed, then it means the editor does not lose
// selection and there is no need to restore it
if(win.withGlobal(this.window,'isCollapsed',focusBase)){
this._moveToBookmark(this._savedSelection);
}
delete this._savedSelection;
}
},
onClick: function(){
// summary:
// Handler for when editor is clicked
// tags:
// protected
this.endEditing(true);
this.inherited(arguments);
},
replaceValue: function(/*String*/ html){
// summary:
// over-ride of replaceValue to support custom undo and stack maintenance.
// tags:
// protected
if(!this.customUndo){
this.inherited(arguments);
}else{
if(this.isClosed){
this.setValue(html);
}else{
this.beginEditing();
if(!html){
html = "&#160;"; // &nbsp;
}
this.setValue(html);
this.endEditing();
}
}
},
_setDisabledAttr: function(/*Boolean*/ value){
this.setValueDeferred.then(lang.hitch(this, function(){
if((!this.disabled && value) || (!this._buttonEnabledPlugins && value)){
// Disable editor: disable all enabled buttons and remember that list
array.forEach(this._plugins, function(p){
p.set("disabled", true);
});
}else if(this.disabled && !value){
// Restore plugins to being active.
array.forEach(this._plugins, function(p){
p.set("disabled", false);
});
}
}));
this.inherited(arguments);
},
_setStateClass: function(){
try{
this.inherited(arguments);
// Let theme set the editor's text color based on editor enabled/disabled state.
// We need to jump through hoops because the main document (where the theme CSS is)
// is separate from the iframe's document.
if(this.document && this.document.body){
domStyle.set(this.document.body, "color", domStyle.get(this.iframe, "color"));
}
}catch(e){ /* Squelch any errors caused by focus change if hidden during a state change */}
}
});
// Register the "default plugins", ie, the built-in editor commands
function simplePluginFactory(args){
return new _Plugin({ command: args.name });
}
function togglePluginFactory(args){
return new _Plugin({ buttonClass: ToggleButton, command: args.name });
}
lang.mixin(_Plugin.registry, {
"undo": simplePluginFactory,
"redo": simplePluginFactory,
"cut": simplePluginFactory,
"copy": simplePluginFactory,
"paste": simplePluginFactory,
"insertOrderedList": simplePluginFactory,
"insertUnorderedList": simplePluginFactory,
"indent": simplePluginFactory,
"outdent": simplePluginFactory,
"justifyCenter": simplePluginFactory,
"justifyFull": simplePluginFactory,
"justifyLeft": simplePluginFactory,
"justifyRight": simplePluginFactory,
"delete": simplePluginFactory,
"selectAll": simplePluginFactory,
"removeFormat": simplePluginFactory,
"unlink": simplePluginFactory,
"insertHorizontalRule": simplePluginFactory,
"bold": togglePluginFactory,
"italic": togglePluginFactory,
"underline": togglePluginFactory,
"strikethrough": togglePluginFactory,
"subscript": togglePluginFactory,
"superscript": togglePluginFactory,
"|": function(){
return new _Plugin({
setEditor: function(editor){
this.editor = editor;
this.button = new ToolbarSeparator({ownerDocument: editor.ownerDocument});
}
});
}
});
return Editor;
});

View File

@ -0,0 +1,248 @@
//>>built
require({cache:{"url:dijit/templates/InlineEditBox.html":"<span data-dojo-attach-point=\"editNode\" role=\"presentation\" class=\"dijitReset dijitInline dijitOffScreen\"\n\tdata-dojo-attach-event=\"onkeypress: _onKeyPress\"\n\t><span data-dojo-attach-point=\"editorPlaceholder\"></span\n\t><span data-dojo-attach-point=\"buttonContainer\"\n\t\t><button data-dojo-type=\"dijit/form/Button\" data-dojo-props=\"label: '${buttonSave}', 'class': 'saveButton'\"\n\t\t\tdata-dojo-attach-point=\"saveButton\" data-dojo-attach-event=\"onClick:save\"></button\n\t\t><button data-dojo-type=\"dijit/form/Button\" data-dojo-props=\"label: '${buttonCancel}', 'class': 'cancelButton'\"\n\t\t\tdata-dojo-attach-point=\"cancelButton\" data-dojo-attach-event=\"onClick:cancel\"></button\n\t></span\n></span>\n"}});
define("dijit/InlineEditBox",["require","dojo/_base/array","dojo/_base/declare","dojo/dom-attr","dojo/dom-class","dojo/dom-construct","dojo/dom-style","dojo/_base/event","dojo/i18n","dojo/_base/kernel","dojo/keys","dojo/_base/lang","dojo/sniff","dojo/when","./focus","./_Widget","./_TemplatedMixin","./_WidgetsInTemplateMixin","./_Container","./form/Button","./form/_TextBoxMixin","./form/TextBox","dojo/text!./templates/InlineEditBox.html","dojo/i18n!./nls/common"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c,_d,_e,fm,_f,_10,_11,_12,_13,_14,_15,_16){
var _17=_3("dijit._InlineEditor",[_f,_10,_11],{templateString:_16,postMixInProperties:function(){
this.inherited(arguments);
this.messages=_9.getLocalization("dijit","common",this.lang);
_2.forEach(["buttonSave","buttonCancel"],function(_18){
if(!this[_18]){
this[_18]=this.messages[_18];
}
},this);
},buildRendering:function(){
this.inherited(arguments);
var Cls=typeof this.editor=="string"?(_c.getObject(this.editor)||_1(this.editor)):this.editor;
var _19=this.sourceStyle,_1a="line-height:"+_19.lineHeight+";",_1b=_7.getComputedStyle(this.domNode);
_2.forEach(["Weight","Family","Size","Style"],function(_1c){
var _1d=_19["font"+_1c],_1e=_1b["font"+_1c];
if(_1e!=_1d){
_1a+="font-"+_1c+":"+_19["font"+_1c]+";";
}
},this);
_2.forEach(["marginTop","marginBottom","marginLeft","marginRight","position","left","top","right","bottom","float","clear","display"],function(_1f){
this.domNode.style[_1f]=_19[_1f];
},this);
var _20=this.inlineEditBox.width;
if(_20=="100%"){
_1a+="width:100%;";
this.domNode.style.display="block";
}else{
_1a+="width:"+(_20+(Number(_20)==_20?"px":""))+";";
}
var _21=_c.delegate(this.inlineEditBox.editorParams,{style:_1a,dir:this.dir,lang:this.lang,textDir:this.textDir});
_21["displayedValue" in Cls.prototype?"displayedValue":"value"]=this.value;
this.editWidget=new Cls(_21,this.editorPlaceholder);
if(this.inlineEditBox.autoSave){
_6.destroy(this.buttonContainer);
}
},postCreate:function(){
this.inherited(arguments);
var ew=this.editWidget;
if(this.inlineEditBox.autoSave){
this.connect(ew,"onChange","_onChange");
this.connect(ew,"onKeyPress","_onKeyPress");
}else{
if("intermediateChanges" in ew){
ew.set("intermediateChanges",true);
this.connect(ew,"onChange","_onIntermediateChange");
this.saveButton.set("disabled",true);
}
}
},startup:function(){
this.editWidget.startup();
this.inherited(arguments);
},_onIntermediateChange:function(){
this.saveButton.set("disabled",(this.getValue()==this._resetValue)||!this.enableSave());
},destroy:function(){
this.editWidget.destroy(true);
this.inherited(arguments);
},getValue:function(){
var ew=this.editWidget;
return String(ew.get("displayedValue" in ew?"displayedValue":"value"));
},_onKeyPress:function(e){
if(this.inlineEditBox.autoSave&&this.inlineEditBox.editing){
if(e.altKey||e.ctrlKey){
return;
}
if(e.charOrCode==_b.ESCAPE){
_8.stop(e);
this.cancel(true);
}else{
if(e.charOrCode==_b.ENTER&&e.target.tagName=="INPUT"){
_8.stop(e);
this._onChange();
}
}
}
},_onBlur:function(){
this.inherited(arguments);
if(this.inlineEditBox.autoSave&&this.inlineEditBox.editing){
if(this.getValue()==this._resetValue){
this.cancel(false);
}else{
if(this.enableSave()){
this.save(false);
}
}
}
},_onChange:function(){
if(this.inlineEditBox.autoSave&&this.inlineEditBox.editing&&this.enableSave()){
fm.focus(this.inlineEditBox.displayNode);
}
},enableSave:function(){
return this.editWidget.isValid?this.editWidget.isValid():true;
},focus:function(){
this.editWidget.focus();
if(this.editWidget.focusNode){
fm._onFocusNode(this.editWidget.focusNode);
if(this.editWidget.focusNode.tagName=="INPUT"){
this.defer(function(){
_14.selectInputText(this.editWidget.focusNode);
});
}
}
}});
var _22=_3("dijit.InlineEditBox",_f,{editing:false,autoSave:true,buttonSave:"",buttonCancel:"",renderAsHtml:false,editor:_15,editorWrapper:_17,editorParams:{},disabled:false,onChange:function(){
},onCancel:function(){
},width:"100%",value:"",noValueIndicator:_d("ie")<=6?"<span style='font-family: wingdings; text-decoration: underline;'>&#160;&#160;&#160;&#160;&#x270d;&#160;&#160;&#160;&#160;</span>":"<span style='text-decoration: underline;'>&#160;&#160;&#160;&#160;&#x270d;&#160;&#160;&#160;&#160;</span>",constructor:function(){
this.editorParams={};
},postMixInProperties:function(){
this.inherited(arguments);
this.displayNode=this.srcNodeRef;
var _23={ondijitclick:"_onClick",onmouseover:"_onMouseOver",onmouseout:"_onMouseOut",onfocus:"_onMouseOver",onblur:"_onMouseOut"};
for(var _24 in _23){
this.connect(this.displayNode,_24,_23[_24]);
}
this.displayNode.setAttribute("role","button");
if(!this.displayNode.getAttribute("tabIndex")){
this.displayNode.setAttribute("tabIndex",0);
}
if(!this.value&&!("value" in this.params)){
this.value=_c.trim(this.renderAsHtml?this.displayNode.innerHTML:(this.displayNode.innerText||this.displayNode.textContent||""));
}
if(!this.value){
this.displayNode.innerHTML=this.noValueIndicator;
}
_5.add(this.displayNode,"dijitInlineEditBoxDisplayMode");
},setDisabled:function(_25){
_a.deprecated("dijit.InlineEditBox.setDisabled() is deprecated. Use set('disabled', bool) instead.","","2.0");
this.set("disabled",_25);
},_setDisabledAttr:function(_26){
this.domNode.setAttribute("aria-disabled",_26?"true":"false");
if(_26){
this.displayNode.removeAttribute("tabIndex");
}else{
this.displayNode.setAttribute("tabIndex",0);
}
_5.toggle(this.displayNode,"dijitInlineEditBoxDisplayModeDisabled",_26);
this._set("disabled",_26);
},_onMouseOver:function(){
if(!this.disabled){
_5.add(this.displayNode,"dijitInlineEditBoxDisplayModeHover");
}
},_onMouseOut:function(){
_5.remove(this.displayNode,"dijitInlineEditBoxDisplayModeHover");
},_onClick:function(e){
if(this.disabled){
return;
}
if(e){
_8.stop(e);
}
this._onMouseOut();
this.defer("edit");
},edit:function(){
if(this.disabled||this.editing){
return;
}
this._set("editing",true);
this._savedTabIndex=_4.get(this.displayNode,"tabIndex")||"0";
if(this.wrapperWidget){
var ew=this.wrapperWidget.editWidget;
ew.set("displayedValue" in ew?"displayedValue":"value",this.value);
}else{
var _27=_6.create("span",null,this.domNode,"before");
var Ewc=typeof this.editorWrapper=="string"?_c.getObject(this.editorWrapper):this.editorWrapper;
this.wrapperWidget=new Ewc({value:this.value,buttonSave:this.buttonSave,buttonCancel:this.buttonCancel,dir:this.dir,lang:this.lang,tabIndex:this._savedTabIndex,editor:this.editor,inlineEditBox:this,sourceStyle:_7.getComputedStyle(this.displayNode),save:_c.hitch(this,"save"),cancel:_c.hitch(this,"cancel"),textDir:this.textDir},_27);
if(!this.wrapperWidget._started){
this.wrapperWidget.startup();
}
if(!this._started){
this.startup();
}
}
var ww=this.wrapperWidget;
_5.add(this.displayNode,"dijitOffScreen");
_5.remove(ww.domNode,"dijitOffScreen");
_7.set(ww.domNode,{visibility:"visible"});
_4.set(this.displayNode,"tabIndex","-1");
_e(ww.editWidget.onLoadDeferred,_c.hitch(ww,function(){
this.defer(function(){
this.focus();
this._resetValue=this.getValue();
});
}));
},_onBlur:function(){
this.inherited(arguments);
if(!this.editing){
}
},destroy:function(){
if(this.wrapperWidget&&!this.wrapperWidget._destroyed){
this.wrapperWidget.destroy();
delete this.wrapperWidget;
}
this.inherited(arguments);
},_showText:function(_28){
var ww=this.wrapperWidget;
_7.set(ww.domNode,{visibility:"hidden"});
_5.add(ww.domNode,"dijitOffScreen");
_5.remove(this.displayNode,"dijitOffScreen");
_4.set(this.displayNode,"tabIndex",this._savedTabIndex);
if(_28){
fm.focus(this.displayNode);
}
},save:function(_29){
if(this.disabled||!this.editing){
return;
}
this._set("editing",false);
var ww=this.wrapperWidget;
var _2a=ww.getValue();
this.set("value",_2a);
this._showText(_29);
},setValue:function(val){
_a.deprecated("dijit.InlineEditBox.setValue() is deprecated. Use set('value', ...) instead.","","2.0");
return this.set("value",val);
},_setValueAttr:function(val){
val=_c.trim(val);
var _2b=this.renderAsHtml?val:val.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;").replace(/"/gm,"&quot;").replace(/\n/g,"<br>");
this.displayNode.innerHTML=_2b||this.noValueIndicator;
this._set("value",val);
if(this._started){
this.defer(function(){
this.onChange(val);
});
}
if(this.textDir=="auto"){
this.applyTextDir(this.displayNode,this.displayNode.innerText);
}
},getValue:function(){
_a.deprecated("dijit.InlineEditBox.getValue() is deprecated. Use get('value') instead.","","2.0");
return this.get("value");
},cancel:function(_2c){
if(this.disabled||!this.editing){
return;
}
this._set("editing",false);
this.defer("onCancel");
this._showText(_2c);
},_setTextDirAttr:function(_2d){
if(!this._created||this.textDir!=_2d){
this._set("textDir",_2d);
this.applyTextDir(this.displayNode,this.displayNode.innerText);
this.displayNode.align=this.dir=="rtl"?"right":"left";
}
}});
_22._InlineEditor=_17;
return _22;
});

View File

@ -0,0 +1,659 @@
require({cache:{
'url:dijit/templates/InlineEditBox.html':"<span data-dojo-attach-point=\"editNode\" role=\"presentation\" class=\"dijitReset dijitInline dijitOffScreen\"\n\tdata-dojo-attach-event=\"onkeypress: _onKeyPress\"\n\t><span data-dojo-attach-point=\"editorPlaceholder\"></span\n\t><span data-dojo-attach-point=\"buttonContainer\"\n\t\t><button data-dojo-type=\"dijit/form/Button\" data-dojo-props=\"label: '${buttonSave}', 'class': 'saveButton'\"\n\t\t\tdata-dojo-attach-point=\"saveButton\" data-dojo-attach-event=\"onClick:save\"></button\n\t\t><button data-dojo-type=\"dijit/form/Button\" data-dojo-props=\"label: '${buttonCancel}', 'class': 'cancelButton'\"\n\t\t\tdata-dojo-attach-point=\"cancelButton\" data-dojo-attach-event=\"onClick:cancel\"></button\n\t></span\n></span>\n"}});
define("dijit/InlineEditBox", [
"require",
"dojo/_base/array", // array.forEach
"dojo/_base/declare", // declare
"dojo/dom-attr", // domAttr.set domAttr.get
"dojo/dom-class", // domClass.add domClass.remove domClass.toggle
"dojo/dom-construct", // domConstruct.create domConstruct.destroy
"dojo/dom-style", // domStyle.getComputedStyle domStyle.set domStyle.get
"dojo/_base/event", // event.stop
"dojo/i18n", // i18n.getLocalization
"dojo/_base/kernel", // kernel.deprecated
"dojo/keys", // keys.ENTER keys.ESCAPE
"dojo/_base/lang", // lang.getObject
"dojo/sniff", // has("ie")
"dojo/when",
"./focus",
"./_Widget",
"./_TemplatedMixin",
"./_WidgetsInTemplateMixin",
"./_Container",
"./form/Button",
"./form/_TextBoxMixin",
"./form/TextBox",
"dojo/text!./templates/InlineEditBox.html",
"dojo/i18n!./nls/common"
], function(require, array, declare, domAttr, domClass, domConstruct, domStyle, event, i18n, kernel, keys, lang, has, when,
fm, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _Container, Button, _TextBoxMixin, TextBox, template){
// module:
// dijit/InlineEditBox
var InlineEditor = declare("dijit._InlineEditor", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
// summary:
// Internal widget used by InlineEditBox, displayed when in editing mode
// to display the editor and maybe save/cancel buttons. Calling code should
// connect to save/cancel methods to detect when editing is finished
//
// Has mainly the same parameters as InlineEditBox, plus these values:
//
// style: Object
// Set of CSS attributes of display node, to replicate in editor
//
// value: String
// Value as an HTML string or plain text string, depending on renderAsHTML flag
templateString: template,
postMixInProperties: function(){
this.inherited(arguments);
this.messages = i18n.getLocalization("dijit", "common", this.lang);
array.forEach(["buttonSave", "buttonCancel"], function(prop){
if(!this[prop]){
this[prop] = this.messages[prop];
}
}, this);
},
buildRendering: function(){
this.inherited(arguments);
// Create edit widget in place in the template
// TODO: remove getObject() for 2.0
var Cls = typeof this.editor == "string" ? (lang.getObject(this.editor) || require(this.editor)) : this.editor;
// Copy the style from the source
// Don't copy ALL properties though, just the necessary/applicable ones.
// wrapperStyle/destStyle code is to workaround IE bug where getComputedStyle().fontSize
// is a relative value like 200%, rather than an absolute value like 24px, and
// the 200% can refer *either* to a setting on the node or it's ancestor (see #11175)
var srcStyle = this.sourceStyle,
editStyle = "line-height:" + srcStyle.lineHeight + ";",
destStyle = domStyle.getComputedStyle(this.domNode);
array.forEach(["Weight", "Family", "Size", "Style"], function(prop){
var textStyle = srcStyle["font" + prop],
wrapperStyle = destStyle["font" + prop];
if(wrapperStyle != textStyle){
editStyle += "font-" + prop + ":" + srcStyle["font" + prop] + ";";
}
}, this);
array.forEach(["marginTop", "marginBottom", "marginLeft", "marginRight", "position", "left", "top", "right", "bottom", "float", "clear", "display"], function(prop){
this.domNode.style[prop] = srcStyle[prop];
}, this);
var width = this.inlineEditBox.width;
if(width == "100%"){
// block mode
editStyle += "width:100%;";
this.domNode.style.display = "block";
}else{
// inline-block mode
editStyle += "width:" + (width + (Number(width) == width ? "px" : "")) + ";";
}
var editorParams = lang.delegate(this.inlineEditBox.editorParams, {
style: editStyle,
dir: this.dir,
lang: this.lang,
textDir: this.textDir
});
editorParams[ "displayedValue" in Cls.prototype ? "displayedValue" : "value"] = this.value;
this.editWidget = new Cls(editorParams, this.editorPlaceholder);
if(this.inlineEditBox.autoSave){
// Remove the save/cancel buttons since saving is done by simply tabbing away or
// selecting a value from the drop down list
domConstruct.destroy(this.buttonContainer);
}
},
postCreate: function(){
this.inherited(arguments);
var ew = this.editWidget;
if(this.inlineEditBox.autoSave){
// Selecting a value from a drop down list causes an onChange event and then we save
this.connect(ew, "onChange", "_onChange");
// ESC and TAB should cancel and save. Note that edit widgets do a stopEvent() on ESC key (to
// prevent Dialog from closing when the user just wants to revert the value in the edit widget),
// so this is the only way we can see the key press event.
this.connect(ew, "onKeyPress", "_onKeyPress");
}else{
// If possible, enable/disable save button based on whether the user has changed the value
if("intermediateChanges" in ew){
ew.set("intermediateChanges", true);
this.connect(ew, "onChange", "_onIntermediateChange");
this.saveButton.set("disabled", true);
}
}
},
startup: function(){
this.editWidget.startup();
this.inherited(arguments);
},
_onIntermediateChange: function(/*===== val =====*/){
// summary:
// Called for editor widgets that support the intermediateChanges=true flag as a way
// to detect when to enable/disabled the save button
this.saveButton.set("disabled", (this.getValue() == this._resetValue) || !this.enableSave());
},
destroy: function(){
this.editWidget.destroy(true); // let the parent wrapper widget clean up the DOM
this.inherited(arguments);
},
getValue: function(){
// summary:
// Return the [display] value of the edit widget
var ew = this.editWidget;
return String(ew.get("displayedValue" in ew ? "displayedValue" : "value"));
},
_onKeyPress: function(e){
// summary:
// Handler for keypress in the edit box in autoSave mode.
// description:
// For autoSave widgets, if Esc/Enter, call cancel/save.
// tags:
// private
if(this.inlineEditBox.autoSave && this.inlineEditBox.editing){
if(e.altKey || e.ctrlKey){
return;
}
// If Enter/Esc pressed, treat as save/cancel.
if(e.charOrCode == keys.ESCAPE){
event.stop(e);
this.cancel(true); // sets editing=false which short-circuits _onBlur processing
}else if(e.charOrCode == keys.ENTER && e.target.tagName == "INPUT"){
event.stop(e);
this._onChange(); // fire _onBlur and then save
}
// _onBlur will handle TAB automatically by allowing
// the TAB to change focus before we mess with the DOM: #6227
// Expounding by request:
// The current focus is on the edit widget input field.
// save() will hide and destroy this widget.
// We want the focus to jump from the currently hidden
// displayNode, but since it's hidden, it's impossible to
// unhide it, focus it, and then have the browser focus
// away from it to the next focusable element since each
// of these events is asynchronous and the focus-to-next-element
// is already queued.
// So we allow the browser time to unqueue the move-focus event
// before we do all the hide/show stuff.
}
},
_onBlur: function(){
// summary:
// Called when focus moves outside the editor
// tags:
// private
this.inherited(arguments);
if(this.inlineEditBox.autoSave && this.inlineEditBox.editing){
if(this.getValue() == this._resetValue){
this.cancel(false);
}else if(this.enableSave()){
this.save(false);
}
}
},
_onChange: function(){
// summary:
// Called when the underlying widget fires an onChange event,
// such as when the user selects a value from the drop down list of a ComboBox,
// which means that the user has finished entering the value and we should save.
// tags:
// private
if(this.inlineEditBox.autoSave && this.inlineEditBox.editing && this.enableSave()){
fm.focus(this.inlineEditBox.displayNode); // fires _onBlur which will save the formatted value
}
},
enableSave: function(){
// summary:
// User overridable function returning a Boolean to indicate
// if the Save button should be enabled or not - usually due to invalid conditions
// tags:
// extension
return this.editWidget.isValid ? this.editWidget.isValid() : true;
},
focus: function(){
// summary:
// Focus the edit widget.
// tags:
// protected
this.editWidget.focus();
if(this.editWidget.focusNode){
// IE can take 30ms to report the focus event, but focus manager needs to know before a 0ms timeout.
fm._onFocusNode(this.editWidget.focusNode);
if(this.editWidget.focusNode.tagName == "INPUT"){
this.defer(function(){
_TextBoxMixin.selectInputText(this.editWidget.focusNode);
});
}
}
}
});
var InlineEditBox = declare("dijit.InlineEditBox", _Widget, {
// summary:
// An element with in-line edit capabilities
//
// description:
// Behavior for an existing node (`<p>`, `<div>`, `<span>`, etc.) so that
// when you click it, an editor shows up in place of the original
// text. Optionally, Save and Cancel button are displayed below the edit widget.
// When Save is clicked, the text is pulled from the edit
// widget and redisplayed and the edit widget is again hidden.
// By default a plain Textarea widget is used as the editor (or for
// inline values a TextBox), but you can specify an editor such as
// dijit.Editor (for editing HTML) or a Slider (for adjusting a number).
// An edit widget must support the following API to be used:
//
// - displayedValue or value as initialization parameter,
// and available through set('displayedValue') / set('value')
// - void focus()
// - DOM-node focusNode = node containing editable text
// editing: [readonly] Boolean
// Is the node currently in edit mode?
editing: false,
// autoSave: Boolean
// Changing the value automatically saves it; don't have to push save button
// (and save button isn't even displayed)
autoSave: true,
// buttonSave: String
// Save button label
buttonSave: "",
// buttonCancel: String
// Cancel button label
buttonCancel: "",
// renderAsHtml: Boolean
// Set this to true if the specified Editor's value should be interpreted as HTML
// rather than plain text (ex: `dijit.Editor`)
renderAsHtml: false,
// editor: String|Function
// MID (ex: "dijit/form/TextBox") or constructor for editor widget
editor: TextBox,
// editorWrapper: String|Function
// Class name (or reference to the Class) for widget that wraps the editor widget, displaying save/cancel
// buttons.
editorWrapper: InlineEditor,
// editorParams: Object
// Set of parameters for editor, like {required: true}
editorParams: {},
// disabled: Boolean
// If true, clicking the InlineEditBox to edit it will have no effect.
disabled: false,
onChange: function(/*===== value =====*/){
// summary:
// Set this handler to be notified of changes to value.
// tags:
// callback
},
onCancel: function(){
// summary:
// Set this handler to be notified when editing is cancelled.
// tags:
// callback
},
// width: String
// Width of editor. By default it's width=100% (ie, block mode).
width: "100%",
// value: String
// The display value of the widget in read-only mode
value: "",
// noValueIndicator: [const] String
// The text that gets displayed when there is no value (so that the user has a place to click to edit)
noValueIndicator: has("ie") <= 6 ? // font-family needed on IE6 but it messes up IE8
"<span style='font-family: wingdings; text-decoration: underline;'>&#160;&#160;&#160;&#160;&#x270d;&#160;&#160;&#160;&#160;</span>" :
"<span style='text-decoration: underline;'>&#160;&#160;&#160;&#160;&#x270d;&#160;&#160;&#160;&#160;</span>", // &#160; == &nbsp;
constructor: function(/*===== params, srcNodeRef =====*/){
// summary:
// Create the widget.
// params: Object|null
// Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
// and functions, typically callbacks like onClick.
// The hash can contain any of the widget's properties, excluding read-only properties.
// srcNodeRef: DOMNode|String?
// If a srcNodeRef (DOM node) is specified:
//
// - use srcNodeRef.innerHTML as my value
// - replace srcNodeRef with my generated DOM tree
this.editorParams = {};
},
postMixInProperties: function(){
this.inherited(arguments);
// save pointer to original source node, since Widget nulls-out srcNodeRef
this.displayNode = this.srcNodeRef;
// connect handlers to the display node
var events = {
ondijitclick: "_onClick",
onmouseover: "_onMouseOver",
onmouseout: "_onMouseOut",
onfocus: "_onMouseOver",
onblur: "_onMouseOut"
};
for(var name in events){
this.connect(this.displayNode, name, events[name]);
}
this.displayNode.setAttribute("role", "button");
if(!this.displayNode.getAttribute("tabIndex")){
this.displayNode.setAttribute("tabIndex", 0);
}
if(!this.value && !("value" in this.params)){ // "" is a good value if specified directly so check params){
this.value = lang.trim(this.renderAsHtml ? this.displayNode.innerHTML :
(this.displayNode.innerText || this.displayNode.textContent || ""));
}
if(!this.value){
this.displayNode.innerHTML = this.noValueIndicator;
}
domClass.add(this.displayNode, 'dijitInlineEditBoxDisplayMode');
},
setDisabled: function(/*Boolean*/ disabled){
// summary:
// Deprecated. Use set('disabled', ...) instead.
// tags:
// deprecated
kernel.deprecated("dijit.InlineEditBox.setDisabled() is deprecated. Use set('disabled', bool) instead.", "", "2.0");
this.set('disabled', disabled);
},
_setDisabledAttr: function(/*Boolean*/ disabled){
// summary:
// Hook to make set("disabled", ...) work.
// Set disabled state of widget.
this.domNode.setAttribute("aria-disabled", disabled ? "true" : "false");
if(disabled){
this.displayNode.removeAttribute("tabIndex");
}else{
this.displayNode.setAttribute("tabIndex", 0);
}
domClass.toggle(this.displayNode, "dijitInlineEditBoxDisplayModeDisabled", disabled);
this._set("disabled", disabled);
},
_onMouseOver: function(){
// summary:
// Handler for onmouseover and onfocus event.
// tags:
// private
if(!this.disabled){
domClass.add(this.displayNode, "dijitInlineEditBoxDisplayModeHover");
}
},
_onMouseOut: function(){
// summary:
// Handler for onmouseout and onblur event.
// tags:
// private
domClass.remove(this.displayNode, "dijitInlineEditBoxDisplayModeHover");
},
_onClick: function(/*Event*/ e){
// summary:
// Handler for onclick event.
// tags:
// private
if(this.disabled){
return;
}
if(e){
event.stop(e);
}
this._onMouseOut();
// Since FF gets upset if you move a node while in an event handler for that node...
this.defer("edit");
},
edit: function(){
// summary:
// Display the editor widget in place of the original (read only) markup.
// tags:
// private
if(this.disabled || this.editing){
return;
}
this._set('editing', true);
// save some display node values that can be restored later
this._savedTabIndex = domAttr.get(this.displayNode, "tabIndex") || "0";
if(this.wrapperWidget){
var ew = this.wrapperWidget.editWidget;
ew.set("displayedValue" in ew ? "displayedValue" : "value", this.value);
}else{
// Placeholder for edit widget
// Put place holder (and eventually editWidget) before the display node so that it's positioned correctly
// when Calendar dropdown appears, which happens automatically on focus.
var placeholder = domConstruct.create("span", null, this.domNode, "before");
// Create the editor wrapper (the thing that holds the editor widget and the save/cancel buttons)
var Ewc = typeof this.editorWrapper == "string" ? lang.getObject(this.editorWrapper) : this.editorWrapper;
this.wrapperWidget = new Ewc({
value: this.value,
buttonSave: this.buttonSave,
buttonCancel: this.buttonCancel,
dir: this.dir,
lang: this.lang,
tabIndex: this._savedTabIndex,
editor: this.editor,
inlineEditBox: this,
sourceStyle: domStyle.getComputedStyle(this.displayNode),
save: lang.hitch(this, "save"),
cancel: lang.hitch(this, "cancel"),
textDir: this.textDir
}, placeholder);
if(!this.wrapperWidget._started){
this.wrapperWidget.startup();
}
if(!this._started){
this.startup();
}
}
var ww = this.wrapperWidget;
// to avoid screen jitter, we first create the editor with position: absolute, visibility: hidden,
// and then when it's finished rendering, we switch from display mode to editor
// position: absolute releases screen space allocated to the display node
// opacity:0 is the same as visibility: hidden but is still focusable
// visibility: hidden removes focus outline
domClass.add(this.displayNode, "dijitOffScreen");
domClass.remove(ww.domNode, "dijitOffScreen");
domStyle.set(ww.domNode, { visibility: "visible" });
domAttr.set(this.displayNode, "tabIndex", "-1"); // needed by WebKit for TAB from editor to skip displayNode
// After edit widget has finished initializing (in particular need to wait for dijit.Editor),
// or immediately if there is no onLoadDeferred Deferred,
// replace the display widget with edit widget, leaving them both displayed for a brief time so that
// focus can be shifted without incident.
when(ww.editWidget.onLoadDeferred, lang.hitch(ww, function(){
this.defer(function(){ // defer needed so that the change of focus doesn't happen on mousedown which also sets focus
this.focus(); // both nodes are showing, so we can switch focus safely
this._resetValue = this.getValue();
});
}));
},
_onBlur: function(){
// summary:
// Called when focus moves outside the InlineEditBox.
// Performs garbage collection.
// tags:
// private
this.inherited(arguments);
if(!this.editing){
/* causes IE focus problems, see TooltipDialog_a11y.html...
this.defer(function(){
if(this.wrapperWidget){
this.wrapperWidget.destroy();
delete this.wrapperWidget;
}
});
*/
}
},
destroy: function(){
if(this.wrapperWidget && !this.wrapperWidget._destroyed){
this.wrapperWidget.destroy();
delete this.wrapperWidget;
}
this.inherited(arguments);
},
_showText: function(/*Boolean*/ focus){
// summary:
// Revert to display mode, and optionally focus on display node
// tags:
// private
var ww = this.wrapperWidget;
domStyle.set(ww.domNode, { visibility: "hidden" }); // hide the editor from mouse/keyboard events
domClass.add(ww.domNode, "dijitOffScreen");
domClass.remove(this.displayNode, "dijitOffScreen");
domAttr.set(this.displayNode, "tabIndex", this._savedTabIndex);
if(focus){
fm.focus(this.displayNode);
}
},
save: function(/*Boolean*/ focus){
// summary:
// Save the contents of the editor and revert to display mode.
// focus: Boolean
// Focus on the display mode text
// tags:
// private
if(this.disabled || !this.editing){
return;
}
this._set('editing', false);
var ww = this.wrapperWidget;
var value = ww.getValue();
this.set('value', value); // display changed, formatted value
this._showText(focus); // set focus as needed
},
setValue: function(/*String*/ val){
// summary:
// Deprecated. Use set('value', ...) instead.
// tags:
// deprecated
kernel.deprecated("dijit.InlineEditBox.setValue() is deprecated. Use set('value', ...) instead.", "", "2.0");
return this.set("value", val);
},
_setValueAttr: function(/*String*/ val){
// summary:
// Hook to make set("value", ...) work.
// Inserts specified HTML value into this node, or an "input needed" character if node is blank.
val = lang.trim(val);
var renderVal = this.renderAsHtml ? val : val.replace(/&/gm, "&amp;").replace(/</gm, "&lt;").replace(/>/gm, "&gt;").replace(/"/gm, "&quot;").replace(/\n/g, "<br>");
this.displayNode.innerHTML = renderVal || this.noValueIndicator;
this._set("value", val);
if(this._started){
// tell the world that we have changed
this.defer(function(){
this.onChange(val);
}); // defer prevents browser freeze for long-running event handlers
}
// contextual (auto) text direction depends on the text value
if(this.textDir == "auto"){
this.applyTextDir(this.displayNode, this.displayNode.innerText);
}
},
getValue: function(){
// summary:
// Deprecated. Use get('value') instead.
// tags:
// deprecated
kernel.deprecated("dijit.InlineEditBox.getValue() is deprecated. Use get('value') instead.", "", "2.0");
return this.get("value");
},
cancel: function(/*Boolean*/ focus){
// summary:
// Revert to display mode, discarding any changes made in the editor
// tags:
// private
if(this.disabled || !this.editing){
return;
}
this._set('editing', false);
// tell the world that we have no changes
this.defer("onCancel"); // defer prevents browser freeze for long-running event handlers
this._showText(focus);
},
_setTextDirAttr: function(/*String*/ textDir){
// summary:
// Setter for textDir.
// description:
// Users shouldn't call this function; they should be calling
// set('textDir', value)
// tags:
// private
if(!this._created || this.textDir != textDir){
this._set("textDir", textDir);
this.applyTextDir(this.displayNode, this.displayNode.innerText);
this.displayNode.align = this.dir == "rtl" ? "right" : "left"; //fix the text alignment
}
}
});
InlineEditBox._InlineEditor = InlineEditor; // for monkey patching
return InlineEditBox;
});

View File

@ -0,0 +1,195 @@
Dojo is available 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-2012, 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.

View File

@ -0,0 +1,133 @@
//>>built
define("dijit/Menu",["require","dojo/_base/array","dojo/_base/declare","dojo/_base/event","dojo/dom","dojo/dom-attr","dojo/dom-geometry","dojo/dom-style","dojo/keys","dojo/_base/lang","dojo/on","dojo/sniff","dojo/_base/window","dojo/window","./popup","./DropDownMenu","dojo/ready"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,on,_b,_c,_d,pm,_e,_f){
if(_b("dijit-legacy-requires")){
_f(0,function(){
var _10=["dijit/MenuItem","dijit/PopupMenuItem","dijit/CheckedMenuItem","dijit/MenuSeparator"];
_1(_10);
});
}
return _3("dijit.Menu",_e,{constructor:function(){
this._bindings=[];
},targetNodeIds:[],selector:"",contextMenuForWindow:false,leftClickToOpen:false,refocus:true,postCreate:function(){
if(this.contextMenuForWindow){
this.bindDomNode(this.ownerDocumentBody);
}else{
_2.forEach(this.targetNodeIds,this.bindDomNode,this);
}
this.inherited(arguments);
},_iframeContentWindow:function(_11){
return _d.get(this._iframeContentDocument(_11))||this._iframeContentDocument(_11)["__parent__"]||(_11.name&&_c.doc.frames[_11.name])||null;
},_iframeContentDocument:function(_12){
return _12.contentDocument||(_12.contentWindow&&_12.contentWindow.document)||(_12.name&&_c.doc.frames[_12.name]&&_c.doc.frames[_12.name].document)||null;
},bindDomNode:function(_13){
_13=_5.byId(_13,this.ownerDocument);
var cn;
if(_13.tagName.toLowerCase()=="iframe"){
var _14=_13,_15=this._iframeContentWindow(_14);
cn=_c.body(_15.document);
}else{
cn=(_13==_c.body(this.ownerDocument)?this.ownerDocument.documentElement:_13);
}
var _16={node:_13,iframe:_14};
_6.set(_13,"_dijitMenu"+this.id,this._bindings.push(_16));
var _17=_a.hitch(this,function(cn){
var _18=this.selector,_19=_18?function(_1a){
return on.selector(_18,_1a);
}:function(_1b){
return _1b;
},_1c=this;
return [on(cn,_19(this.leftClickToOpen?"click":"contextmenu"),function(evt){
_4.stop(evt);
_1c._scheduleOpen(this,_14,{x:evt.pageX,y:evt.pageY});
}),on(cn,_19("keydown"),function(evt){
if(evt.shiftKey&&evt.keyCode==_9.F10){
_4.stop(evt);
_1c._scheduleOpen(this,_14);
}
})];
});
_16.connects=cn?_17(cn):[];
if(_14){
_16.onloadHandler=_a.hitch(this,function(){
var _1d=this._iframeContentWindow(_14);
cn=_c.body(_1d.document);
_16.connects=_17(cn);
});
if(_14.addEventListener){
_14.addEventListener("load",_16.onloadHandler,false);
}else{
_14.attachEvent("onload",_16.onloadHandler);
}
}
},unBindDomNode:function(_1e){
var _1f;
try{
_1f=_5.byId(_1e,this.ownerDocument);
}
catch(e){
return;
}
var _20="_dijitMenu"+this.id;
if(_1f&&_6.has(_1f,_20)){
var bid=_6.get(_1f,_20)-1,b=this._bindings[bid],h;
while((h=b.connects.pop())){
h.remove();
}
var _21=b.iframe;
if(_21){
if(_21.removeEventListener){
_21.removeEventListener("load",b.onloadHandler,false);
}else{
_21.detachEvent("onload",b.onloadHandler);
}
}
_6.remove(_1f,_20);
delete this._bindings[bid];
}
},_scheduleOpen:function(_22,_23,_24){
if(!this._openTimer){
this._openTimer=this.defer(function(){
delete this._openTimer;
this._openMyself({target:_22,iframe:_23,coords:_24});
},1);
}
},_openMyself:function(_25){
var _26=_25.target,_27=_25.iframe,_28=_25.coords;
this.currentTarget=_26;
if(_28){
if(_27){
var ifc=_7.position(_27,true),_29=this._iframeContentWindow(_27),_2a=_7.docScroll(_29.document);
var cs=_8.getComputedStyle(_27),tp=_8.toPixelValue,_2b=(_b("ie")&&_b("quirks")?0:tp(_27,cs.paddingLeft))+(_b("ie")&&_b("quirks")?tp(_27,cs.borderLeftWidth):0),top=(_b("ie")&&_b("quirks")?0:tp(_27,cs.paddingTop))+(_b("ie")&&_b("quirks")?tp(_27,cs.borderTopWidth):0);
_28.x+=ifc.x+_2b-_2a.x;
_28.y+=ifc.y+top-_2a.y;
}
}else{
_28=_7.position(_26,true);
_28.x+=10;
_28.y+=10;
}
var _2c=this;
var _2d=this._focusManager.get("prevNode");
var _2e=this._focusManager.get("curNode");
var _2f=!_2e||(_5.isDescendant(_2e,this.domNode))?_2d:_2e;
function _30(){
if(_2c.refocus&&_2f){
_2f.focus();
}
pm.close(_2c);
};
pm.open({popup:this,x:_28.x,y:_28.y,onExecute:_30,onCancel:_30,orient:this.isLeftToRight()?"L":"R"});
this.focus();
this._onBlur=function(){
this.inherited("_onBlur",arguments);
pm.close(this);
};
},destroy:function(){
_2.forEach(this._bindings,function(b){
if(b){
this.unBindDomNode(b.node);
}
},this);
this.inherited(arguments);
}});
});

View File

@ -0,0 +1,349 @@
define("dijit/Menu", [
"require",
"dojo/_base/array", // array.forEach
"dojo/_base/declare", // declare
"dojo/_base/event", // event.stop
"dojo/dom", // dom.byId dom.isDescendant
"dojo/dom-attr", // domAttr.get domAttr.set domAttr.has domAttr.remove
"dojo/dom-geometry", // domStyle.getComputedStyle domGeometry.position
"dojo/dom-style", // domStyle.getComputedStyle
"dojo/keys", // keys.F10
"dojo/_base/lang", // lang.hitch
"dojo/on",
"dojo/sniff", // has("ie"), has("quirks")
"dojo/_base/window", // win.body win.doc.documentElement win.doc.frames
"dojo/window", // winUtils.get
"./popup",
"./DropDownMenu",
"dojo/ready"
], function(require, array, declare, event, dom, domAttr, domGeometry, domStyle, keys, lang, on,
has, win, winUtils, pm, DropDownMenu, ready){
// module:
// dijit/Menu
// Back compat w/1.6, remove for 2.0
if(has("dijit-legacy-requires")){
ready(0, function(){
var requires = ["dijit/MenuItem", "dijit/PopupMenuItem", "dijit/CheckedMenuItem", "dijit/MenuSeparator"];
require(requires); // use indirection so modules not rolled into a build
});
}
return declare("dijit.Menu", DropDownMenu, {
// summary:
// A context menu you can assign to multiple elements
constructor: function(/*===== params, srcNodeRef =====*/){
// summary:
// Create the widget.
// params: Object|null
// Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
// and functions, typically callbacks like onClick.
// The hash can contain any of the widget's properties, excluding read-only properties.
// srcNodeRef: DOMNode|String?
// If a srcNodeRef (DOM node) is specified:
//
// - use srcNodeRef.innerHTML as my contents
// - replace srcNodeRef with my generated DOM tree
this._bindings = [];
},
// targetNodeIds: [const] String[]
// Array of dom node ids of nodes to attach to.
// Fill this with nodeIds upon widget creation and it becomes context menu for those nodes.
targetNodeIds: [],
// selector: String?
// CSS expression to apply this Menu to descendants of targetNodeIds, rather than to
// the nodes specified by targetNodeIds themselves. Useful for applying a Menu to
// a range of rows in a table, tree, etc.
//
// The application must require() an appropriate level of dojo/query to handle the selector.
selector: "",
// TODO: in 2.0 remove support for multiple targetNodeIds. selector gives the same effect.
// So, change targetNodeIds to a targetNodeId: "", remove bindDomNode()/unBindDomNode(), etc.
/*=====
// currentTarget: [readonly] DOMNode
// For context menus, set to the current node that the Menu is being displayed for.
// Useful so that the menu actions can be tailored according to the node
currentTarget: null,
=====*/
// contextMenuForWindow: [const] Boolean
// If true, right clicking anywhere on the window will cause this context menu to open.
// If false, must specify targetNodeIds.
contextMenuForWindow: false,
// leftClickToOpen: [const] Boolean
// If true, menu will open on left click instead of right click, similar to a file menu.
leftClickToOpen: false,
// refocus: Boolean
// When this menu closes, re-focus the element which had focus before it was opened.
refocus: true,
postCreate: function(){
if(this.contextMenuForWindow){
this.bindDomNode(this.ownerDocumentBody);
}else{
// TODO: should have _setTargetNodeIds() method to handle initialization and a possible
// later set('targetNodeIds', ...) call. There's also a problem that targetNodeIds[]
// gets stale after calls to bindDomNode()/unBindDomNode() as it still is just the original list (see #9610)
array.forEach(this.targetNodeIds, this.bindDomNode, this);
}
this.inherited(arguments);
},
// thanks burstlib!
_iframeContentWindow: function(/* HTMLIFrameElement */iframe_el){
// summary:
// Returns the window reference of the passed iframe
// tags:
// private
return winUtils.get(this._iframeContentDocument(iframe_el)) ||
// Moz. TODO: is this available when defaultView isn't?
this._iframeContentDocument(iframe_el)['__parent__'] ||
(iframe_el.name && win.doc.frames[iframe_el.name]) || null; // Window
},
_iframeContentDocument: function(/* HTMLIFrameElement */iframe_el){
// summary:
// Returns a reference to the document object inside iframe_el
// tags:
// protected
return iframe_el.contentDocument // W3
|| (iframe_el.contentWindow && iframe_el.contentWindow.document) // IE
|| (iframe_el.name && win.doc.frames[iframe_el.name] && win.doc.frames[iframe_el.name].document)
|| null; // HTMLDocument
},
bindDomNode: function(/*String|DomNode*/ node){
// summary:
// Attach menu to given node
node = dom.byId(node, this.ownerDocument);
var cn; // Connect node
// Support context menus on iframes. Rather than binding to the iframe itself we need
// to bind to the <body> node inside the iframe.
if(node.tagName.toLowerCase() == "iframe"){
var iframe = node,
window = this._iframeContentWindow(iframe);
cn = win.body(window.document);
}else{
// To capture these events at the top level, attach to <html>, not <body>.
// Otherwise right-click context menu just doesn't work.
cn = (node == win.body(this.ownerDocument) ? this.ownerDocument.documentElement : node);
}
// "binding" is the object to track our connection to the node (ie, the parameter to bindDomNode())
var binding = {
node: node,
iframe: iframe
};
// Save info about binding in _bindings[], and make node itself record index(+1) into
// _bindings[] array. Prefix w/_dijitMenu to avoid setting an attribute that may
// start with a number, which fails on FF/safari.
domAttr.set(node, "_dijitMenu" + this.id, this._bindings.push(binding));
// Setup the connections to monitor click etc., unless we are connecting to an iframe which hasn't finished
// loading yet, in which case we need to wait for the onload event first, and then connect
// On linux Shift-F10 produces the oncontextmenu event, but on Windows it doesn't, so
// we need to monitor keyboard events in addition to the oncontextmenu event.
var doConnects = lang.hitch(this, function(cn){
var selector = this.selector,
delegatedEvent = selector ?
function(eventType){ return on.selector(selector, eventType); } :
function(eventType){ return eventType; },
self = this;
return [
// TODO: when leftClickToOpen is true then shouldn't space/enter key trigger the menu,
// rather than shift-F10?
on(cn, delegatedEvent(this.leftClickToOpen ? "click" : "contextmenu"), function(evt){
// Schedule context menu to be opened unless it's already been scheduled from onkeydown handler
event.stop(evt);
self._scheduleOpen(this, iframe, {x: evt.pageX, y: evt.pageY});
}),
on(cn, delegatedEvent("keydown"), function(evt){
if(evt.shiftKey && evt.keyCode == keys.F10){
event.stop(evt);
self._scheduleOpen(this, iframe); // no coords - open near target node
}
})
];
});
binding.connects = cn ? doConnects(cn) : [];
if(iframe){
// Setup handler to [re]bind to the iframe when the contents are initially loaded,
// and every time the contents change.
// Need to do this b/c we are actually binding to the iframe's <body> node.
// Note: can't use connect.connect(), see #9609.
binding.onloadHandler = lang.hitch(this, function(){
// want to remove old connections, but IE throws exceptions when trying to
// access the <body> node because it's already gone, or at least in a state of limbo
var window = this._iframeContentWindow(iframe);
cn = win.body(window.document)
binding.connects = doConnects(cn);
});
if(iframe.addEventListener){
iframe.addEventListener("load", binding.onloadHandler, false);
}else{
iframe.attachEvent("onload", binding.onloadHandler);
}
}
},
unBindDomNode: function(/*String|DomNode*/ nodeName){
// summary:
// Detach menu from given node
var node;
try{
node = dom.byId(nodeName, this.ownerDocument);
}catch(e){
// On IE the dom.byId() call will get an exception if the attach point was
// the <body> node of an <iframe> that has since been reloaded (and thus the
// <body> node is in a limbo state of destruction.
return;
}
// node["_dijitMenu" + this.id] contains index(+1) into my _bindings[] array
var attrName = "_dijitMenu" + this.id;
if(node && domAttr.has(node, attrName)){
var bid = domAttr.get(node, attrName)-1, b = this._bindings[bid], h;
while((h = b.connects.pop())){
h.remove();
}
// Remove listener for iframe onload events
var iframe = b.iframe;
if(iframe){
if(iframe.removeEventListener){
iframe.removeEventListener("load", b.onloadHandler, false);
}else{
iframe.detachEvent("onload", b.onloadHandler);
}
}
domAttr.remove(node, attrName);
delete this._bindings[bid];
}
},
_scheduleOpen: function(/*DomNode?*/ target, /*DomNode?*/ iframe, /*Object?*/ coords){
// summary:
// Set timer to display myself. Using a timer rather than displaying immediately solves
// two problems:
//
// 1. IE: without the delay, focus work in "open" causes the system
// context menu to appear in spite of stopEvent.
//
// 2. Avoid double-shows on linux, where shift-F10 generates an oncontextmenu event
// even after a event.stop(e). (Shift-F10 on windows doesn't generate the
// oncontextmenu event.)
if(!this._openTimer){
this._openTimer = this.defer(function(){
delete this._openTimer;
this._openMyself({
target: target,
iframe: iframe,
coords: coords
});
}, 1);
}
},
_openMyself: function(args){
// summary:
// Internal function for opening myself when the user does a right-click or something similar.
// args:
// This is an Object containing:
//
// - target: The node that is being clicked
// - iframe: If an `<iframe>` is being clicked, iframe points to that iframe
// - coords: Put menu at specified x/y position in viewport, or if iframe is
// specified, then relative to iframe.
//
// _openMyself() formerly took the event object, and since various code references
// evt.target (after connecting to _openMyself()), using an Object for parameters
// (so that old code still works).
var target = args.target,
iframe = args.iframe,
coords = args.coords;
// To be used by MenuItem event handlers to tell which node the menu was opened on
this.currentTarget = target;
// Get coordinates to open menu, either at specified (mouse) position or (if triggered via keyboard)
// then near the node the menu is assigned to.
if(coords){
if(iframe){
// Specified coordinates are on <body> node of an <iframe>, convert to match main document
var ifc = domGeometry.position(iframe, true),
window = this._iframeContentWindow(iframe),
scroll = domGeometry.docScroll(window.document);
var cs = domStyle.getComputedStyle(iframe),
tp = domStyle.toPixelValue,
left = (has("ie") && has("quirks") ? 0 : tp(iframe, cs.paddingLeft)) + (has("ie") && has("quirks") ? tp(iframe, cs.borderLeftWidth) : 0),
top = (has("ie") && has("quirks") ? 0 : tp(iframe, cs.paddingTop)) + (has("ie") && has("quirks") ? tp(iframe, cs.borderTopWidth) : 0);
coords.x += ifc.x + left - scroll.x;
coords.y += ifc.y + top - scroll.y;
}
}else{
coords = domGeometry.position(target, true);
coords.x += 10;
coords.y += 10;
}
var self=this;
var prevFocusNode = this._focusManager.get("prevNode");
var curFocusNode = this._focusManager.get("curNode");
var savedFocusNode = !curFocusNode || (dom.isDescendant(curFocusNode, this.domNode)) ? prevFocusNode : curFocusNode;
function closeAndRestoreFocus(){
// user has clicked on a menu or popup
if(self.refocus && savedFocusNode){
savedFocusNode.focus();
}
pm.close(self);
}
pm.open({
popup: this,
x: coords.x,
y: coords.y,
onExecute: closeAndRestoreFocus,
onCancel: closeAndRestoreFocus,
orient: this.isLeftToRight() ? 'L' : 'R'
});
this.focus();
this._onBlur = function(){
this.inherited('_onBlur', arguments);
// Usually the parent closes the child widget but if this is a context
// menu then there is no parent
pm.close(this);
// don't try to restore focus; user has clicked another part of the screen
// and set focus there
};
},
destroy: function(){
array.forEach(this._bindings, function(b){ if(b){ this.unBindDomNode(b.node); } }, this);
this.inherited(arguments);
}
});
});

View File

@ -0,0 +1,35 @@
//>>built
require({cache:{"url:dijit/templates/MenuBar.html":"<div class=\"dijitMenuBar dijitMenuPassive\" data-dojo-attach-point=\"containerNode\" role=\"menubar\" tabIndex=\"${tabIndex}\" data-dojo-attach-event=\"onkeypress: _onKeyPress\"></div>\n"}});
define("dijit/MenuBar",["dojo/_base/declare","dojo/_base/event","dojo/keys","./_MenuBase","dojo/text!./templates/MenuBar.html"],function(_1,_2,_3,_4,_5){
return _1("dijit.MenuBar",_4,{templateString:_5,baseClass:"dijitMenuBar",_isMenuBar:true,postCreate:function(){
this.inherited(arguments);
var l=this.isLeftToRight();
this.connectKeyNavHandlers(l?[_3.LEFT_ARROW]:[_3.RIGHT_ARROW],l?[_3.RIGHT_ARROW]:[_3.LEFT_ARROW]);
this._orient=["below"];
},_moveToPopup:function(_6){
if(this.focusedChild&&this.focusedChild.popup&&!this.focusedChild.disabled){
this.onItemClick(this.focusedChild,_6);
}
},focusChild:function(_7){
var _8=this.focusedChild,_9=_8&&_8.popup&&_8.popup.isShowingNow;
this.inherited(arguments);
if(_9&&_7.popup&&!_7.disabled){
this._openPopup(true);
}
},_onKeyPress:function(_a){
if(_a.ctrlKey||_a.altKey){
return;
}
switch(_a.charOrCode){
case _3.DOWN_ARROW:
this._moveToPopup(_a);
_2.stop(_a);
}
},onItemClick:function(_b,_c){
if(_b.popup&&_b.popup.isShowingNow&&(_c.type!=="keypress"||_c.keyCode!==_3.DOWN_ARROW)){
_b.popup.onCancel();
}else{
this.inherited(arguments);
}
}});
});

View File

@ -0,0 +1,92 @@
require({cache:{
'url:dijit/templates/MenuBar.html':"<div class=\"dijitMenuBar dijitMenuPassive\" data-dojo-attach-point=\"containerNode\" role=\"menubar\" tabIndex=\"${tabIndex}\" data-dojo-attach-event=\"onkeypress: _onKeyPress\"></div>\n"}});
define("dijit/MenuBar", [
"dojo/_base/declare", // declare
"dojo/_base/event", // event.stop
"dojo/keys", // keys.DOWN_ARROW
"./_MenuBase",
"dojo/text!./templates/MenuBar.html"
], function(declare, event, keys, _MenuBase, template){
// module:
// dijit/MenuBar
return declare("dijit.MenuBar", _MenuBase, {
// summary:
// A menu bar, listing menu choices horizontally, like the "File" menu in most desktop applications
templateString: template,
baseClass: "dijitMenuBar",
// _isMenuBar: [protected] Boolean
// This is a MenuBar widget, not a (vertical) Menu widget.
_isMenuBar: true,
postCreate: function(){
this.inherited(arguments);
var l = this.isLeftToRight();
this.connectKeyNavHandlers(
l ? [keys.LEFT_ARROW] : [keys.RIGHT_ARROW],
l ? [keys.RIGHT_ARROW] : [keys.LEFT_ARROW]
);
// parameter to dijit.popup.open() about where to put popup (relative to this.domNode)
this._orient = ["below"];
},
_moveToPopup: function(/*Event*/ evt){
// summary:
// This handles the down arrow key, opening a submenu if one exists.
// Unlike _MenuBase._moveToPopup(), will never move to the next item in the MenuBar.
// tags:
// private
if(this.focusedChild && this.focusedChild.popup && !this.focusedChild.disabled){
this.onItemClick(this.focusedChild, evt);
}
},
focusChild: function(item){
// overload focusChild so that whenever the focus is moved to a new item,
// check the previous focused whether it has its popup open, if so, after
// focusing the new item, open its submenu immediately
var prev_item = this.focusedChild,
showpopup = prev_item && prev_item.popup && prev_item.popup.isShowingNow;
this.inherited(arguments);
if(showpopup && item.popup && !item.disabled){
this._openPopup(true); // TODO: on down arrow, _openPopup() is called here and in onItemClick()
}
},
_onKeyPress: function(/*Event*/ evt){
// summary:
// Handle keyboard based menu navigation.
// tags:
// protected
if(evt.ctrlKey || evt.altKey){ return; }
switch(evt.charOrCode){
case keys.DOWN_ARROW:
this._moveToPopup(evt);
event.stop(evt);
}
},
onItemClick: function(/*dijit/_WidgetBase*/ item, /*Event*/ evt){
// summary:
// Handle clicks on an item. Also called by _moveToPopup() due to a down-arrow key on the item.
// Cancels a dropdown if already open and click is either mouse or space/enter.
// Don't close dropdown due to down arrow.
// tags:
// private
if(item.popup && item.popup.isShowingNow && (evt.type !== "keypress" || evt.keyCode !== keys.DOWN_ARROW)){
item.popup.onCancel();
}else{
this.inherited(arguments);
}
}
});
});

View File

@ -0,0 +1,8 @@
//>>built
require({cache:{"url:dijit/templates/MenuBarItem.html":"<div class=\"dijitReset dijitInline dijitMenuItem dijitMenuItemLabel\" data-dojo-attach-point=\"focusNode\"\n\t \trole=\"menuitem\" tabIndex=\"-1\">\n\t<span data-dojo-attach-point=\"containerNode\"></span>\n</div>\n"}});
define("dijit/MenuBarItem",["dojo/_base/declare","./MenuItem","dojo/text!./templates/MenuBarItem.html"],function(_1,_2,_3){
var _4=_1("dijit._MenuBarItemMixin",null,{templateString:_3,_setIconClassAttr:null});
var _5=_1("dijit.MenuBarItem",[_2,_4],{});
_5._MenuBarItemMixin=_4;
return _5;
});

View File

@ -0,0 +1,28 @@
require({cache:{
'url:dijit/templates/MenuBarItem.html':"<div class=\"dijitReset dijitInline dijitMenuItem dijitMenuItemLabel\" data-dojo-attach-point=\"focusNode\"\n\t \trole=\"menuitem\" tabIndex=\"-1\">\n\t<span data-dojo-attach-point=\"containerNode\"></span>\n</div>\n"}});
define("dijit/MenuBarItem", [
"dojo/_base/declare", // declare
"./MenuItem",
"dojo/text!./templates/MenuBarItem.html"
], function(declare, MenuItem, template){
// module:
// dijit/MenuBarItem
var _MenuBarItemMixin = declare("dijit._MenuBarItemMixin", null, {
templateString: template,
// Map widget attributes to DOMNode attributes.
_setIconClassAttr: null // cancel MenuItem setter because we don't have a place for an icon
});
var MenuBarItem = declare("dijit.MenuBarItem", [MenuItem, _MenuBarItemMixin], {
// summary:
// Item in a MenuBar that's clickable, and doesn't spawn a submenu when pressed (or hovered)
});
MenuBarItem._MenuBarItemMixin = _MenuBarItemMixin; // dojox.mobile is accessing this
return MenuBarItem;
});

View File

@ -0,0 +1,60 @@
//>>built
require({cache:{"url:dijit/templates/MenuItem.html":"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitem\" tabIndex=\"-1\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitIcon dijitMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">\n\t\t<div data-dojo-attach-point=\"arrowWrapper\" style=\"visibility: hidden\">\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuExpand\"/>\n\t\t\t<span class=\"dijitMenuExpandA11y\">+</span>\n\t\t</div>\n\t</td>\n</tr>\n"}});
define("dijit/MenuItem",["dojo/_base/declare","dojo/dom","dojo/dom-attr","dojo/dom-class","dojo/_base/kernel","dojo/sniff","./_Widget","./_TemplatedMixin","./_Contained","./_CssStateMixin","dojo/text!./templates/MenuItem.html"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b){
return _1("dijit.MenuItem",[_7,_8,_9,_a],{templateString:_b,baseClass:"dijitMenuItem",label:"",_setLabelAttr:function(_c){
this.containerNode.innerHTML=_c;
this._set("label",_c);
if(this.textDir==="auto"){
this.applyTextDir(this.focusNode,this.label);
}
},iconClass:"dijitNoIcon",_setIconClassAttr:{node:"iconNode",type:"class"},accelKey:"",disabled:false,_fillContent:function(_d){
if(_d&&!("label" in this.params)){
this.set("label",_d.innerHTML);
}
},buildRendering:function(){
this.inherited(arguments);
var _e=this.id+"_text";
_3.set(this.containerNode,"id",_e);
if(this.accelKeyNode){
_3.set(this.accelKeyNode,"id",this.id+"_accel");
_e+=" "+this.id+"_accel";
}
this.domNode.setAttribute("aria-labelledby",_e);
_2.setSelectable(this.domNode,false);
},onClick:function(){
},focus:function(){
try{
if(_6("ie")==8){
this.containerNode.focus();
}
this.focusNode.focus();
}
catch(e){
}
},_onFocus:function(){
this._setSelected(true);
this.getParent()._onItemFocus(this);
this.inherited(arguments);
},_setSelected:function(_f){
_4.toggle(this.domNode,"dijitMenuItemSelected",_f);
},setLabel:function(_10){
_5.deprecated("dijit.MenuItem.setLabel() is deprecated. Use set('label', ...) instead.","","2.0");
this.set("label",_10);
},setDisabled:function(_11){
_5.deprecated("dijit.Menu.setDisabled() is deprecated. Use set('disabled', bool) instead.","","2.0");
this.set("disabled",_11);
},_setDisabledAttr:function(_12){
this.focusNode.setAttribute("aria-disabled",_12?"true":"false");
this._set("disabled",_12);
},_setAccelKeyAttr:function(_13){
this.accelKeyNode.style.display=_13?"":"none";
this.accelKeyNode.innerHTML=_13;
_3.set(this.containerNode,"colSpan",_13?"1":"2");
this._set("accelKey",_13);
},_setTextDirAttr:function(_14){
if(!this._created||this.textDir!=_14){
this._set("textDir",_14);
this.applyTextDir(this.focusNode,this.label);
}
}});
});

View File

@ -0,0 +1,187 @@
require({cache:{
'url:dijit/templates/MenuItem.html':"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitem\" tabIndex=\"-1\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitIcon dijitMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">\n\t\t<div data-dojo-attach-point=\"arrowWrapper\" style=\"visibility: hidden\">\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuExpand\"/>\n\t\t\t<span class=\"dijitMenuExpandA11y\">+</span>\n\t\t</div>\n\t</td>\n</tr>\n"}});
define("dijit/MenuItem", [
"dojo/_base/declare", // declare
"dojo/dom", // dom.setSelectable
"dojo/dom-attr", // domAttr.set
"dojo/dom-class", // domClass.toggle
"dojo/_base/kernel", // kernel.deprecated
"dojo/sniff", // has("ie")
"./_Widget",
"./_TemplatedMixin",
"./_Contained",
"./_CssStateMixin",
"dojo/text!./templates/MenuItem.html"
], function(declare, dom, domAttr, domClass, kernel, has,
_Widget, _TemplatedMixin, _Contained, _CssStateMixin, template){
// module:
// dijit/MenuItem
return declare("dijit.MenuItem",
[_Widget, _TemplatedMixin, _Contained, _CssStateMixin],
{
// summary:
// A line item in a Menu Widget
// Make 3 columns
// icon, label, and expand arrow (BiDi-dependent) indicating sub-menu
templateString: template,
baseClass: "dijitMenuItem",
// label: String
// Menu text
label: "",
_setLabelAttr: function(val){
this.containerNode.innerHTML = val;
this._set("label", val);
if(this.textDir === "auto"){
this.applyTextDir(this.focusNode, this.label);
}
},
// iconClass: String
// Class to apply to DOMNode to make it display an icon.
iconClass: "dijitNoIcon",
_setIconClassAttr: { node: "iconNode", type: "class" },
// accelKey: String
// Text for the accelerator (shortcut) key combination.
// Note that although Menu can display accelerator keys there
// is no infrastructure to actually catch and execute these
// accelerators.
accelKey: "",
// disabled: Boolean
// If true, the menu item is disabled.
// If false, the menu item is enabled.
disabled: false,
_fillContent: function(/*DomNode*/ source){
// If button label is specified as srcNodeRef.innerHTML rather than
// this.params.label, handle it here.
if(source && !("label" in this.params)){
this.set('label', source.innerHTML);
}
},
buildRendering: function(){
this.inherited(arguments);
var label = this.id+"_text";
domAttr.set(this.containerNode, "id", label);
if(this.accelKeyNode){
domAttr.set(this.accelKeyNode, "id", this.id + "_accel");
label += " " + this.id + "_accel";
}
this.domNode.setAttribute("aria-labelledby", label);
dom.setSelectable(this.domNode, false);
},
onClick: function(/*Event*/){
// summary:
// User defined function to handle clicks
// tags:
// callback
},
focus: function(){
// summary:
// Focus on this MenuItem
try{
if(has("ie") == 8){
// needed for IE8 which won't scroll TR tags into view on focus yet calling scrollIntoView creates flicker (#10275)
this.containerNode.focus();
}
this.focusNode.focus();
}catch(e){
// this throws on IE (at least) in some scenarios
}
},
_onFocus: function(){
// summary:
// This is called by the focus manager when focus
// goes to this MenuItem or a child menu.
// tags:
// protected
this._setSelected(true);
this.getParent()._onItemFocus(this);
this.inherited(arguments);
},
_setSelected: function(selected){
// summary:
// Indicate that this node is the currently selected one
// tags:
// private
/***
* TODO: remove this method and calls to it, when _onBlur() is working for MenuItem.
* Currently _onBlur() gets called when focus is moved from the MenuItem to a child menu.
* That's not supposed to happen, but the problem is:
* In order to allow dijit.popup's getTopPopup() to work,a sub menu's popupParent
* points to the parent Menu, bypassing the parent MenuItem... thus the
* MenuItem is not in the chain of active widgets and gets a premature call to
* _onBlur()
*/
domClass.toggle(this.domNode, "dijitMenuItemSelected", selected);
},
setLabel: function(/*String*/ content){
// summary:
// Deprecated. Use set('label', ...) instead.
// tags:
// deprecated
kernel.deprecated("dijit.MenuItem.setLabel() is deprecated. Use set('label', ...) instead.", "", "2.0");
this.set("label", content);
},
setDisabled: function(/*Boolean*/ disabled){
// summary:
// Deprecated. Use set('disabled', bool) instead.
// tags:
// deprecated
kernel.deprecated("dijit.Menu.setDisabled() is deprecated. Use set('disabled', bool) instead.", "", "2.0");
this.set('disabled', disabled);
},
_setDisabledAttr: function(/*Boolean*/ value){
// summary:
// Hook for attr('disabled', ...) to work.
// Enable or disable this menu item.
this.focusNode.setAttribute('aria-disabled', value ? 'true' : 'false');
this._set("disabled", value);
},
_setAccelKeyAttr: function(/*String*/ value){
// summary:
// Hook for attr('accelKey', ...) to work.
// Set accelKey on this menu item.
this.accelKeyNode.style.display=value?"":"none";
this.accelKeyNode.innerHTML=value;
//have to use colSpan to make it work in IE
domAttr.set(this.containerNode,'colSpan',value?"1":"2");
this._set("accelKey", value);
},
_setTextDirAttr: function(/*String*/ textDir){
// summary:
// Setter for textDir.
// description:
// Users shouldn't call this function; they should be calling
// set('textDir', value)
// tags:
// private
// only if new textDir is different from the old one
// and on widgets creation.
if(!this._created || this.textDir != textDir){
this._set("textDir", textDir);
this.applyTextDir(this.focusNode, this.label);
}
}
});
});

View File

@ -0,0 +1,10 @@
//>>built
require({cache:{"url:dijit/templates/MenuSeparator.html":"<tr class=\"dijitMenuSeparator\">\n\t<td class=\"dijitMenuSeparatorIconCell\">\n\t\t<div class=\"dijitMenuSeparatorTop\"></div>\n\t\t<div class=\"dijitMenuSeparatorBottom\"></div>\n\t</td>\n\t<td colspan=\"3\" class=\"dijitMenuSeparatorLabelCell\">\n\t\t<div class=\"dijitMenuSeparatorTop dijitMenuSeparatorLabel\"></div>\n\t\t<div class=\"dijitMenuSeparatorBottom\"></div>\n\t</td>\n</tr>"}});
define("dijit/MenuSeparator",["dojo/_base/declare","dojo/dom","./_WidgetBase","./_TemplatedMixin","./_Contained","dojo/text!./templates/MenuSeparator.html"],function(_1,_2,_3,_4,_5,_6){
return _1("dijit.MenuSeparator",[_3,_4,_5],{templateString:_6,buildRendering:function(){
this.inherited(arguments);
_2.setSelectable(this.domNode,false);
},isFocusable:function(){
return false;
}});
});

View File

@ -0,0 +1,35 @@
require({cache:{
'url:dijit/templates/MenuSeparator.html':"<tr class=\"dijitMenuSeparator\">\n\t<td class=\"dijitMenuSeparatorIconCell\">\n\t\t<div class=\"dijitMenuSeparatorTop\"></div>\n\t\t<div class=\"dijitMenuSeparatorBottom\"></div>\n\t</td>\n\t<td colspan=\"3\" class=\"dijitMenuSeparatorLabelCell\">\n\t\t<div class=\"dijitMenuSeparatorTop dijitMenuSeparatorLabel\"></div>\n\t\t<div class=\"dijitMenuSeparatorBottom\"></div>\n\t</td>\n</tr>"}});
define("dijit/MenuSeparator", [
"dojo/_base/declare", // declare
"dojo/dom", // dom.setSelectable
"./_WidgetBase",
"./_TemplatedMixin",
"./_Contained",
"dojo/text!./templates/MenuSeparator.html"
], function(declare, dom, _WidgetBase, _TemplatedMixin, _Contained, template){
// module:
// dijit/MenuSeparator
return declare("dijit.MenuSeparator", [_WidgetBase, _TemplatedMixin, _Contained], {
// summary:
// A line between two menu items
templateString: template,
buildRendering: function(){
this.inherited(arguments);
dom.setSelectable(this.domNode, false);
},
isFocusable: function(){
// summary:
// Override to always return false
// tags:
// protected
return false; // Boolean
}
});
});

View File

@ -0,0 +1,5 @@
//>>built
define("dijit/PopupMenuBarItem",["dojo/_base/declare","./PopupMenuItem","./MenuBarItem"],function(_1,_2,_3){
var _4=_3._MenuBarItemMixin;
return _1("dijit.PopupMenuBarItem",[_2,_4],{});
});

View File

@ -0,0 +1,16 @@
define("dijit/PopupMenuBarItem", [
"dojo/_base/declare", // declare
"./PopupMenuItem",
"./MenuBarItem"
], function(declare, PopupMenuItem, MenuBarItem){
// module:
// dijit/PopupMenuBarItem
var _MenuBarItemMixin = MenuBarItem._MenuBarItemMixin;
return declare("dijit.PopupMenuBarItem", [PopupMenuItem, _MenuBarItemMixin], {
// summary:
// Item in a MenuBar like "File" or "Edit", that spawns a submenu when pressed (or hovered)
});
});

View File

@ -0,0 +1,34 @@
//>>built
define("dijit/PopupMenuItem",["dojo/_base/declare","dojo/dom-style","dojo/query","./registry","./MenuItem","./hccss"],function(_1,_2,_3,_4,_5){
return _1("dijit.PopupMenuItem",_5,{_fillContent:function(){
if(this.srcNodeRef){
var _6=_3("*",this.srcNodeRef);
this.inherited(arguments,[_6[0]]);
this.dropDownContainer=this.srcNodeRef;
}
},startup:function(){
if(this._started){
return;
}
this.inherited(arguments);
if(!this.popup){
var _7=_3("[widgetId]",this.dropDownContainer)[0];
this.popup=_4.byNode(_7);
}
this.ownerDocumentBody.appendChild(this.popup.domNode);
this.popup.startup();
this.popup.domNode.style.display="none";
if(this.arrowWrapper){
_2.set(this.arrowWrapper,"visibility","");
}
this.focusNode.setAttribute("aria-haspopup","true");
},destroyDescendants:function(_8){
if(this.popup){
if(!this.popup._destroyed){
this.popup.destroyRecursive(_8);
}
delete this.popup;
}
this.inherited(arguments);
}});
});

View File

@ -0,0 +1,73 @@
define("dijit/PopupMenuItem", [
"dojo/_base/declare", // declare
"dojo/dom-style", // domStyle.set
"dojo/query", // query
"./registry", // registry.byNode
"./MenuItem",
"./hccss"
], function(declare, domStyle, query, registry, MenuItem){
// module:
// dijit/PopupMenuItem
return declare("dijit.PopupMenuItem", MenuItem, {
// summary:
// An item in a Menu that spawn a drop down (usually a drop down menu)
_fillContent: function(){
// summary:
// When Menu is declared in markup, this code gets the menu label and
// the popup widget from the srcNodeRef.
// description:
// srcNodeRefinnerHTML contains both the menu item text and a popup widget
// The first part holds the menu item text and the second part is the popup
// example:
// | <div data-dojo-type="dijit/PopupMenuItem">
// | <span>pick me</span>
// | <popup> ... </popup>
// | </div>
// tags:
// protected
if(this.srcNodeRef){
var nodes = query("*", this.srcNodeRef);
this.inherited(arguments, [nodes[0]]);
// save pointer to srcNode so we can grab the drop down widget after it's instantiated
this.dropDownContainer = this.srcNodeRef;
}
},
startup: function(){
if(this._started){ return; }
this.inherited(arguments);
// we didn't copy the dropdown widget from the this.srcNodeRef, so it's in no-man's
// land now. move it to win.doc.body.
if(!this.popup){
var node = query("[widgetId]", this.dropDownContainer)[0];
this.popup = registry.byNode(node);
}
this.ownerDocumentBody.appendChild(this.popup.domNode);
this.popup.startup();
this.popup.domNode.style.display="none";
if(this.arrowWrapper){
domStyle.set(this.arrowWrapper, "visibility", "");
}
this.focusNode.setAttribute("aria-haspopup", "true");
},
destroyDescendants: function(/*Boolean*/ preserveDom){
if(this.popup){
// Destroy the popup, unless it's already been destroyed. This can happen because
// the popup is a direct child of <body> even though it's logically my child.
if(!this.popup._destroyed){
this.popup.destroyRecursive(preserveDom);
}
delete this.popup;
}
this.inherited(arguments);
}
});
});

View File

@ -0,0 +1,53 @@
//>>built
require({cache:{"url:dijit/templates/ProgressBar.html":"<div class=\"dijitProgressBar dijitProgressBarEmpty\" role=\"progressbar\"\n\t><div data-dojo-attach-point=\"internalProgress\" class=\"dijitProgressBarFull\"\n\t\t><div class=\"dijitProgressBarTile\" role=\"presentation\"></div\n\t\t><span style=\"visibility:hidden\">&#160;</span\n\t></div\n\t><div data-dojo-attach-point=\"labelNode\" class=\"dijitProgressBarLabel\" id=\"${id}_label\"></div\n\t><img data-dojo-attach-point=\"indeterminateHighContrastImage\" class=\"dijitProgressBarIndeterminateHighContrastImage\" alt=\"\"\n/></div>\n"}});
define("dijit/ProgressBar",["require","dojo/_base/declare","dojo/dom-class","dojo/_base/lang","dojo/number","./_Widget","./_TemplatedMixin","dojo/text!./templates/ProgressBar.html"],function(_1,_2,_3,_4,_5,_6,_7,_8){
return _2("dijit.ProgressBar",[_6,_7],{progress:"0",value:"",maximum:100,places:0,indeterminate:false,label:"",name:"",templateString:_8,_indeterminateHighContrastImagePath:_1.toUrl("./themes/a11y/indeterminate_progress.gif"),postMixInProperties:function(){
this.inherited(arguments);
if(!(this.params&&"value" in this.params)){
this.value=this.indeterminate?Infinity:this.progress;
}
},buildRendering:function(){
this.inherited(arguments);
this.indeterminateHighContrastImage.setAttribute("src",this._indeterminateHighContrastImagePath.toString());
this.update();
},update:function(_9){
_4.mixin(this,_9||{});
var _a=this.internalProgress,ap=this.domNode;
var _b=1;
if(this.indeterminate){
ap.removeAttribute("aria-valuenow");
}else{
if(String(this.progress).indexOf("%")!=-1){
_b=Math.min(parseFloat(this.progress)/100,1);
this.progress=_b*this.maximum;
}else{
this.progress=Math.min(this.progress,this.maximum);
_b=this.maximum?this.progress/this.maximum:0;
}
ap.setAttribute("aria-valuenow",this.progress);
}
ap.setAttribute("aria-describedby",this.labelNode.id);
ap.setAttribute("aria-valuemin",0);
ap.setAttribute("aria-valuemax",this.maximum);
this.labelNode.innerHTML=this.report(_b);
_3.toggle(this.domNode,"dijitProgressBarIndeterminate",this.indeterminate);
_a.style.width=(_b*100)+"%";
this.onChange();
},_setValueAttr:function(v){
this._set("value",v);
if(v==Infinity){
this.update({indeterminate:true});
}else{
this.update({indeterminate:false,progress:v});
}
},_setLabelAttr:function(_c){
this._set("label",_c);
this.update();
},_setIndeterminateAttr:function(_d){
this.indeterminate=_d;
this.update();
},report:function(_e){
return this.label?this.label:(this.indeterminate?"&#160;":_5.format(_e,{type:"percent",places:this.places,locale:this.lang}));
},onChange:function(){
}});
});

View File

@ -0,0 +1,171 @@
require({cache:{
'url:dijit/templates/ProgressBar.html':"<div class=\"dijitProgressBar dijitProgressBarEmpty\" role=\"progressbar\"\n\t><div data-dojo-attach-point=\"internalProgress\" class=\"dijitProgressBarFull\"\n\t\t><div class=\"dijitProgressBarTile\" role=\"presentation\"></div\n\t\t><span style=\"visibility:hidden\">&#160;</span\n\t></div\n\t><div data-dojo-attach-point=\"labelNode\" class=\"dijitProgressBarLabel\" id=\"${id}_label\"></div\n\t><img data-dojo-attach-point=\"indeterminateHighContrastImage\" class=\"dijitProgressBarIndeterminateHighContrastImage\" alt=\"\"\n/></div>\n"}});
define("dijit/ProgressBar", [
"require", // require.toUrl
"dojo/_base/declare", // declare
"dojo/dom-class", // domClass.toggle
"dojo/_base/lang", // lang.mixin
"dojo/number", // number.format
"./_Widget",
"./_TemplatedMixin",
"dojo/text!./templates/ProgressBar.html"
], function(require, declare, domClass, lang, number, _Widget, _TemplatedMixin, template){
// module:
// dijit/ProgressBar
return declare("dijit.ProgressBar", [_Widget, _TemplatedMixin], {
// summary:
// A progress indication widget, showing the amount completed
// (often the percentage completed) of a task.
//
// example:
// | <div data-dojo-type="ProgressBar"
// | places="0"
// | value="..." maximum="...">
// | </div>
// progress: [const] String (Percentage or Number)
// Number or percentage indicating amount of task completed.
// Deprecated. Use "value" instead.
progress: "0",
// value: String (Percentage or Number)
// Number or percentage indicating amount of task completed.
// With "%": percentage value, 0% <= progress <= 100%, or
// without "%": absolute value, 0 <= progress <= maximum.
// Infinity means that the progress bar is indeterminate.
value: "",
// maximum: [const] Float
// Max sample number
maximum: 100,
// places: [const] Number
// Number of places to show in values; 0 by default
places: 0,
// indeterminate: [const] Boolean
// If false: show progress value (number or percentage).
// If true: show that a process is underway but that the amount completed is unknown.
// Deprecated. Use "value" instead.
indeterminate: false,
// label: String?
// Label on progress bar. Defaults to percentage for determinate progress bar and
// blank for indeterminate progress bar.
label:"",
// name: String
// this is the field name (for a form) if set. This needs to be set if you want to use
// this widget in a dijit/form/Form widget (such as dijit/Dialog)
name: '',
templateString: template,
// _indeterminateHighContrastImagePath: [private] URL
// URL to image to use for indeterminate progress bar when display is in high contrast mode
_indeterminateHighContrastImagePath:
require.toUrl("./themes/a11y/indeterminate_progress.gif"),
postMixInProperties: function(){
this.inherited(arguments);
// Back-compat for when constructor specifies indeterminate or progress, rather than value. Remove for 2.0.
if(!(this.params && "value" in this.params)){
this.value = this.indeterminate ? Infinity : this.progress;
}
},
buildRendering: function(){
this.inherited(arguments);
this.indeterminateHighContrastImage.setAttribute("src",
this._indeterminateHighContrastImagePath.toString());
this.update();
},
update: function(/*Object?*/attributes){
// summary:
// Internal method to change attributes of ProgressBar, similar to set(hash). Users should call
// set("value", ...) rather than calling this method directly.
// attributes:
// May provide progress and/or maximum properties on this parameter;
// see attribute specs for details.
// example:
// | myProgressBar.update({'indeterminate': true});
// | myProgressBar.update({'progress': 80});
// | myProgressBar.update({'indeterminate': true, label:"Loading ..." })
// tags:
// private
// TODO: deprecate this method and use set() instead
lang.mixin(this, attributes || {});
var tip = this.internalProgress, ap = this.domNode;
var percent = 1;
if(this.indeterminate){
ap.removeAttribute("aria-valuenow");
}else{
if(String(this.progress).indexOf("%") != -1){
percent = Math.min(parseFloat(this.progress)/100, 1);
this.progress = percent * this.maximum;
}else{
this.progress = Math.min(this.progress, this.maximum);
percent = this.maximum ? this.progress / this.maximum : 0;
}
ap.setAttribute("aria-valuenow", this.progress);
}
// Even indeterminate ProgressBars should have these attributes
ap.setAttribute("aria-describedby", this.labelNode.id);
ap.setAttribute("aria-valuemin", 0);
ap.setAttribute("aria-valuemax", this.maximum);
this.labelNode.innerHTML = this.report(percent);
domClass.toggle(this.domNode, "dijitProgressBarIndeterminate", this.indeterminate);
tip.style.width = (percent * 100) + "%";
this.onChange();
},
_setValueAttr: function(v){
this._set("value", v);
if(v == Infinity){
this.update({indeterminate:true});
}else{
this.update({indeterminate:false, progress:v});
}
},
_setLabelAttr: function(label){
this._set("label", label);
this.update();
},
_setIndeterminateAttr: function(indeterminate){
// Deprecated, use set("value", ...) instead
this.indeterminate = indeterminate;
this.update();
},
report: function(/*float*/percent){
// summary:
// Generates message to show inside progress bar (normally indicating amount of task completed).
// May be overridden.
// tags:
// extension
return this.label ? this.label :
(this.indeterminate ? "&#160;" : number.format(percent, { type: "percent", places: this.places, locale: this.lang }));
},
onChange: function(){
// summary:
// Callback fired when progress updates.
// tags:
// extension
}
});
});

View File

@ -0,0 +1,98 @@
//>>built
require({cache:{"url:dijit/templates/TitlePane.html":"<div>\n\t<div data-dojo-attach-event=\"onclick:_onTitleClick, onkeydown:_onTitleKey\"\n\t\t\tclass=\"dijitTitlePaneTitle\" data-dojo-attach-point=\"titleBarNode\" id=\"${id}_titleBarNode\">\n\t\t<div class=\"dijitTitlePaneTitleFocus\" data-dojo-attach-point=\"focusNode\">\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" data-dojo-attach-point=\"arrowNode\" class=\"dijitArrowNode\" role=\"presentation\"\n\t\t\t/><span data-dojo-attach-point=\"arrowNodeInner\" class=\"dijitArrowNodeInner\"></span\n\t\t\t><span data-dojo-attach-point=\"titleNode\" class=\"dijitTitlePaneTextNode\"></span>\n\t\t</div>\n\t</div>\n\t<div class=\"dijitTitlePaneContentOuter\" data-dojo-attach-point=\"hideNode\" role=\"presentation\">\n\t\t<div class=\"dijitReset\" data-dojo-attach-point=\"wipeNode\" role=\"presentation\">\n\t\t\t<div class=\"dijitTitlePaneContentInner\" data-dojo-attach-point=\"containerNode\" role=\"region\" id=\"${id}_pane\" aria-labelledby=\"${id}_titleBarNode\">\n\t\t\t\t<!-- nested divs because wipeIn()/wipeOut() doesn't work right on node w/padding etc. Put padding on inner div. -->\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n"}});
define("dijit/TitlePane",["dojo/_base/array","dojo/_base/declare","dojo/dom","dojo/dom-attr","dojo/dom-class","dojo/dom-geometry","dojo/_base/event","dojo/fx","dojo/_base/kernel","dojo/keys","./_CssStateMixin","./_TemplatedMixin","./layout/ContentPane","dojo/text!./templates/TitlePane.html","./_base/manager"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c,_d,_e,_f){
return _2("dijit.TitlePane",[_d,_c,_b],{title:"",_setTitleAttr:{node:"titleNode",type:"innerHTML"},open:true,toggleable:true,tabIndex:"0",duration:_f.defaultDuration,baseClass:"dijitTitlePane",templateString:_e,doLayout:false,_setTooltipAttr:{node:"focusNode",type:"attribute",attribute:"title"},buildRendering:function(){
this.inherited(arguments);
_3.setSelectable(this.titleNode,false);
},postCreate:function(){
this.inherited(arguments);
if(this.toggleable){
this._trackMouseState(this.titleBarNode,"dijitTitlePaneTitle");
}
var _10=this.hideNode,_11=this.wipeNode;
this._wipeIn=_8.wipeIn({node:_11,duration:this.duration,beforeBegin:function(){
_10.style.display="";
}});
this._wipeOut=_8.wipeOut({node:_11,duration:this.duration,onEnd:function(){
_10.style.display="none";
}});
},_setOpenAttr:function(_12,_13){
_1.forEach([this._wipeIn,this._wipeOut],function(_14){
if(_14&&_14.status()=="playing"){
_14.stop();
}
});
if(_13){
var _15=this[_12?"_wipeIn":"_wipeOut"];
_15.play();
}else{
this.hideNode.style.display=this.wipeNode.style.display=_12?"":"none";
}
if(this._started){
if(_12){
this._onShow();
}else{
this.onHide();
}
}
this.containerNode.setAttribute("aria-hidden",_12?"false":"true");
this.focusNode.setAttribute("aria-pressed",_12?"true":"false");
this._set("open",_12);
this._setCss();
},_setToggleableAttr:function(_16){
this.focusNode.setAttribute("role",_16?"button":"heading");
if(_16){
this.focusNode.setAttribute("aria-controls",this.id+"_pane");
this.focusNode.setAttribute("tabIndex",this.tabIndex);
this.focusNode.setAttribute("aria-pressed",this.open);
}else{
_4.remove(this.focusNode,"aria-controls");
_4.remove(this.focusNode,"tabIndex");
_4.remove(this.focusNode,"aria-pressed");
}
this._set("toggleable",_16);
this._setCss();
},_setContentAttr:function(_17){
if(!this.open||!this._wipeOut||this._wipeOut.status()=="playing"){
this.inherited(arguments);
}else{
if(this._wipeIn&&this._wipeIn.status()=="playing"){
this._wipeIn.stop();
}
_6.setMarginBox(this.wipeNode,{h:_6.getMarginBox(this.wipeNode).h});
this.inherited(arguments);
if(this._wipeIn){
this._wipeIn.play();
}else{
this.hideNode.style.display="";
}
}
},toggle:function(){
this._setOpenAttr(!this.open,true);
},_setCss:function(){
var _18=this.titleBarNode||this.focusNode;
var _19=this._titleBarClass;
this._titleBarClass="dijit"+(this.toggleable?"":"Fixed")+(this.open?"Open":"Closed");
_5.replace(_18,this._titleBarClass,_19||"");
this.arrowNodeInner.innerHTML=this.open?"-":"+";
},_onTitleKey:function(e){
if(e.keyCode==_a.ENTER||e.keyCode==_a.SPACE){
if(this.toggleable){
this.toggle();
_7.stop(e);
}
}else{
if(e.keyCode==_a.DOWN_ARROW&&this.open){
this.containerNode.focus();
e.preventDefault();
}
}
},_onTitleClick:function(){
if(this.toggleable){
this.toggle();
}
},setTitle:function(_1a){
_9.deprecated("dijit.TitlePane.setTitle() is deprecated. Use set('title', ...) instead.","","2.0");
this.set("title",_1a);
}});
});

View File

@ -0,0 +1,268 @@
require({cache:{
'url:dijit/templates/TitlePane.html':"<div>\n\t<div data-dojo-attach-event=\"onclick:_onTitleClick, onkeydown:_onTitleKey\"\n\t\t\tclass=\"dijitTitlePaneTitle\" data-dojo-attach-point=\"titleBarNode\" id=\"${id}_titleBarNode\">\n\t\t<div class=\"dijitTitlePaneTitleFocus\" data-dojo-attach-point=\"focusNode\">\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" data-dojo-attach-point=\"arrowNode\" class=\"dijitArrowNode\" role=\"presentation\"\n\t\t\t/><span data-dojo-attach-point=\"arrowNodeInner\" class=\"dijitArrowNodeInner\"></span\n\t\t\t><span data-dojo-attach-point=\"titleNode\" class=\"dijitTitlePaneTextNode\"></span>\n\t\t</div>\n\t</div>\n\t<div class=\"dijitTitlePaneContentOuter\" data-dojo-attach-point=\"hideNode\" role=\"presentation\">\n\t\t<div class=\"dijitReset\" data-dojo-attach-point=\"wipeNode\" role=\"presentation\">\n\t\t\t<div class=\"dijitTitlePaneContentInner\" data-dojo-attach-point=\"containerNode\" role=\"region\" id=\"${id}_pane\" aria-labelledby=\"${id}_titleBarNode\">\n\t\t\t\t<!-- nested divs because wipeIn()/wipeOut() doesn't work right on node w/padding etc. Put padding on inner div. -->\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n"}});
define("dijit/TitlePane", [
"dojo/_base/array", // array.forEach
"dojo/_base/declare", // declare
"dojo/dom", // dom.setSelectable
"dojo/dom-attr", // domAttr.set or get domAttr.remove
"dojo/dom-class", // domClass.replace
"dojo/dom-geometry", // domGeometry.setMarginBox domGeometry.getMarginBox
"dojo/_base/event", // event.stop
"dojo/fx", // fxUtils.wipeIn fxUtils.wipeOut
"dojo/_base/kernel", // kernel.deprecated
"dojo/keys", // keys.DOWN_ARROW keys.ENTER
"./_CssStateMixin",
"./_TemplatedMixin",
"./layout/ContentPane",
"dojo/text!./templates/TitlePane.html",
"./_base/manager" // defaultDuration
], function(array, declare, dom, domAttr, domClass, domGeometry, event, fxUtils, kernel, keys,
_CssStateMixin, _TemplatedMixin, ContentPane, template, manager){
// module:
// dijit/TitlePane
return declare("dijit.TitlePane", [ContentPane, _TemplatedMixin, _CssStateMixin], {
// summary:
// A pane with a title on top, that can be expanded or collapsed.
//
// description:
// An accessible container with a title Heading, and a content
// section that slides open and closed. TitlePane is an extension to
// `dijit/layout/ContentPane`, providing all the useful content-control aspects from it.
//
// example:
// | // load a TitlePane from remote file:
// | var foo = new dijit.TitlePane({ href: "foobar.html", title:"Title" });
// | foo.startup();
//
// example:
// | <!-- markup href example: -->
// | <div data-dojo-type="dijit/TitlePane" data-dojo-props="href: 'foobar.html', title: 'Title'"></div>
//
// example:
// | <!-- markup with inline data -->
// | <div data-dojo-type="dijit/TitlePane" title="Title">
// | <p>I am content</p>
// | </div>
// title: String
// Title of the pane
title: "",
_setTitleAttr: { node: "titleNode", type: "innerHTML" }, // override default where title becomes a hover tooltip
// open: Boolean
// Whether pane is opened or closed.
open: true,
// toggleable: Boolean
// Whether pane can be opened or closed by clicking the title bar.
toggleable: true,
// tabIndex: String
// Tabindex setting for the title (so users can tab to the title then
// use space/enter to open/close the title pane)
tabIndex: "0",
// duration: Integer
// Time in milliseconds to fade in/fade out
duration: manager.defaultDuration,
// baseClass: [protected] String
// The root className to be placed on this widget's domNode.
baseClass: "dijitTitlePane",
templateString: template,
// doLayout: [protected] Boolean
// Don't change this parameter from the default value.
// This ContentPane parameter doesn't make sense for TitlePane, since TitlePane
// is never a child of a layout container, nor should TitlePane try to control
// the size of an inner widget.
doLayout: false,
// Tooltip is defined in _WidgetBase but we need to handle the mapping to DOM here
_setTooltipAttr: {node: "focusNode", type: "attribute", attribute: "title"}, // focusNode spans the entire width, titleNode doesn't
buildRendering: function(){
this.inherited(arguments);
dom.setSelectable(this.titleNode, false);
},
postCreate: function(){
this.inherited(arguments);
// Hover and focus effect on title bar, except for non-toggleable TitlePanes
// This should really be controlled from _setToggleableAttr() but _CssStateMixin
// doesn't provide a way to disconnect a previous _trackMouseState() call
if(this.toggleable){
this._trackMouseState(this.titleBarNode, "dijitTitlePaneTitle");
}
// setup open/close animations
var hideNode = this.hideNode, wipeNode = this.wipeNode;
this._wipeIn = fxUtils.wipeIn({
node: wipeNode,
duration: this.duration,
beforeBegin: function(){
hideNode.style.display="";
}
});
this._wipeOut = fxUtils.wipeOut({
node: wipeNode,
duration: this.duration,
onEnd: function(){
hideNode.style.display="none";
}
});
},
_setOpenAttr: function(/*Boolean*/ open, /*Boolean*/ animate){
// summary:
// Hook to make set("open", boolean) control the open/closed state of the pane.
// open: Boolean
// True if you want to open the pane, false if you want to close it.
array.forEach([this._wipeIn, this._wipeOut], function(animation){
if(animation && animation.status() == "playing"){
animation.stop();
}
});
if(animate){
var anim = this[open ? "_wipeIn" : "_wipeOut"];
anim.play();
}else{
this.hideNode.style.display = this.wipeNode.style.display = open ? "" : "none";
}
// load content (if this is the first time we are opening the TitlePane
// and content is specified as an href, or href was set when hidden)
if(this._started){
if(open){
this._onShow();
}else{
this.onHide();
}
}
this.containerNode.setAttribute("aria-hidden", open ? "false" : "true");
this.focusNode.setAttribute("aria-pressed", open ? "true" : "false");
this._set("open", open);
this._setCss();
},
_setToggleableAttr: function(/*Boolean*/ canToggle){
// summary:
// Hook to make set("toggleable", boolean) work.
// canToggle: Boolean
// True to allow user to open/close pane by clicking title bar.
this.focusNode.setAttribute("role", canToggle ? "button" : "heading");
if(canToggle){
this.focusNode.setAttribute("aria-controls", this.id+"_pane");
this.focusNode.setAttribute("tabIndex", this.tabIndex);
this.focusNode.setAttribute("aria-pressed", this.open);
}else{
domAttr.remove(this.focusNode, "aria-controls");
domAttr.remove(this.focusNode, "tabIndex");
domAttr.remove(this.focusNode, "aria-pressed");
}
this._set("toggleable", canToggle);
this._setCss();
},
_setContentAttr: function(/*String|DomNode|Nodelist*/ content){
// summary:
// Hook to make set("content", ...) work.
// Typically called when an href is loaded. Our job is to make the animation smooth.
if(!this.open || !this._wipeOut || this._wipeOut.status() == "playing"){
// we are currently *closing* the pane (or the pane is closed), so just let that continue
this.inherited(arguments);
}else{
if(this._wipeIn && this._wipeIn.status() == "playing"){
this._wipeIn.stop();
}
// freeze container at current height so that adding new content doesn't make it jump
domGeometry.setMarginBox(this.wipeNode, { h: domGeometry.getMarginBox(this.wipeNode).h });
// add the new content (erasing the old content, if any)
this.inherited(arguments);
// call _wipeIn.play() to animate from current height to new height
if(this._wipeIn){
this._wipeIn.play();
}else{
this.hideNode.style.display = "";
}
}
},
toggle: function(){
// summary:
// Switches between opened and closed state
// tags:
// private
this._setOpenAttr(!this.open, true);
},
_setCss: function(){
// summary:
// Set the open/close css state for the TitlePane
// tags:
// private
var node = this.titleBarNode || this.focusNode;
var oldCls = this._titleBarClass;
this._titleBarClass = "dijit" + (this.toggleable ? "" : "Fixed") + (this.open ? "Open" : "Closed");
domClass.replace(node, this._titleBarClass, oldCls || "");
this.arrowNodeInner.innerHTML = this.open ? "-" : "+";
},
_onTitleKey: function(/*Event*/ e){
// summary:
// Handler for when user hits a key
// tags:
// private
if(e.keyCode == keys.ENTER || e.keyCode == keys.SPACE){
if(this.toggleable){
this.toggle();
event.stop(e);
}
}else if(e.keyCode == keys.DOWN_ARROW && this.open){
this.containerNode.focus();
e.preventDefault();
}
},
_onTitleClick: function(){
// summary:
// Handler when user clicks the title bar
// tags:
// private
if(this.toggleable){
this.toggle();
}
},
setTitle: function(/*String*/ title){
// summary:
// Deprecated. Use set('title', ...) instead.
// tags:
// deprecated
kernel.deprecated("dijit.TitlePane.setTitle() is deprecated. Use set('title', ...) instead.", "", "2.0");
this.set("title", title);
}
});
});

View File

@ -0,0 +1,13 @@
//>>built
define("dijit/Toolbar",["require","dojo/_base/declare","dojo/has","dojo/keys","dojo/ready","./_Widget","./_KeyNavContainer","./_TemplatedMixin"],function(_1,_2,_3,_4,_5,_6,_7,_8){
if(_3("dijit-legacy-requires")){
_5(0,function(){
var _9=["dijit/ToolbarSeparator"];
_1(_9);
});
}
return _2("dijit.Toolbar",[_6,_8,_7],{templateString:"<div class=\"dijit\" role=\"toolbar\" tabIndex=\"${tabIndex}\" data-dojo-attach-point=\"containerNode\">"+"</div>",baseClass:"dijitToolbar",postCreate:function(){
this.inherited(arguments);
this.connectKeyNavHandlers(this.isLeftToRight()?[_4.LEFT_ARROW]:[_4.RIGHT_ARROW],this.isLeftToRight()?[_4.RIGHT_ARROW]:[_4.LEFT_ARROW]);
}});
});

View File

@ -0,0 +1,43 @@
define("dijit/Toolbar", [
"require",
"dojo/_base/declare", // declare
"dojo/has",
"dojo/keys", // keys.LEFT_ARROW keys.RIGHT_ARROW
"dojo/ready",
"./_Widget",
"./_KeyNavContainer",
"./_TemplatedMixin"
], function(require, declare, has, keys, ready, _Widget, _KeyNavContainer, _TemplatedMixin){
// module:
// dijit/Toolbar
// Back compat w/1.6, remove for 2.0
if(has("dijit-legacy-requires")){
ready(0, function(){
var requires = ["dijit/ToolbarSeparator"];
require(requires); // use indirection so modules not rolled into a build
});
}
return declare("dijit.Toolbar", [_Widget, _TemplatedMixin, _KeyNavContainer], {
// summary:
// A Toolbar widget, used to hold things like `dijit.Editor` buttons
templateString:
'<div class="dijit" role="toolbar" tabIndex="${tabIndex}" data-dojo-attach-point="containerNode">' +
'</div>',
baseClass: "dijitToolbar",
postCreate: function(){
this.inherited(arguments);
this.connectKeyNavHandlers(
this.isLeftToRight() ? [keys.LEFT_ARROW] : [keys.RIGHT_ARROW],
this.isLeftToRight() ? [keys.RIGHT_ARROW] : [keys.LEFT_ARROW]
);
}
});
});

View File

@ -0,0 +1,9 @@
//>>built
define("dijit/ToolbarSeparator",["dojo/_base/declare","dojo/dom","./_Widget","./_TemplatedMixin"],function(_1,_2,_3,_4){
return _1("dijit.ToolbarSeparator",[_3,_4],{templateString:"<div class=\"dijitToolbarSeparator dijitInline\" role=\"presentation\"></div>",buildRendering:function(){
this.inherited(arguments);
_2.setSelectable(this.domNode,false);
},isFocusable:function(){
return false;
}});
});

View File

@ -0,0 +1,31 @@
define("dijit/ToolbarSeparator", [
"dojo/_base/declare", // declare
"dojo/dom", // dom.setSelectable
"./_Widget",
"./_TemplatedMixin"
], function(declare, dom, _Widget, _TemplatedMixin){
// module:
// dijit/ToolbarSeparator
return declare("dijit.ToolbarSeparator", [_Widget, _TemplatedMixin], {
// summary:
// A spacer between two `dijit.Toolbar` items
templateString: '<div class="dijitToolbarSeparator dijitInline" role="presentation"></div>',
buildRendering: function(){
this.inherited(arguments);
dom.setSelectable(this.domNode, false);
},
isFocusable: function(){
// summary:
// This widget isn't focusable, so pass along that fact.
// tags:
// protected
return false;
}
});
});

View File

@ -0,0 +1,208 @@
//>>built
require({cache:{"url:dijit/templates/Tooltip.html":"<div class=\"dijitTooltip dijitTooltipLeft\" id=\"dojoTooltip\"\n\t><div class=\"dijitTooltipContainer dijitTooltipContents\" data-dojo-attach-point=\"containerNode\" role='alert'></div\n\t><div class=\"dijitTooltipConnector\" data-dojo-attach-point=\"connectorNode\"></div\n></div>\n"}});
define("dijit/Tooltip",["dojo/_base/array","dojo/_base/declare","dojo/_base/fx","dojo/dom","dojo/dom-class","dojo/dom-geometry","dojo/dom-style","dojo/_base/lang","dojo/mouse","dojo/on","dojo/sniff","./_base/manager","./place","./_Widget","./_TemplatedMixin","./BackgroundIframe","dojo/text!./templates/Tooltip.html","./main"],function(_1,_2,fx,_3,_4,_5,_6,_7,_8,on,_9,_a,_b,_c,_d,_e,_f,_10){
var _11=_2("dijit._MasterTooltip",[_c,_d],{duration:_a.defaultDuration,templateString:_f,postCreate:function(){
this.ownerDocumentBody.appendChild(this.domNode);
this.bgIframe=new _e(this.domNode);
this.fadeIn=fx.fadeIn({node:this.domNode,duration:this.duration,onEnd:_7.hitch(this,"_onShow")});
this.fadeOut=fx.fadeOut({node:this.domNode,duration:this.duration,onEnd:_7.hitch(this,"_onHide")});
},show:function(_12,_13,_14,rtl,_15){
if(this.aroundNode&&this.aroundNode===_13&&this.containerNode.innerHTML==_12){
return;
}
if(this.fadeOut.status()=="playing"){
this._onDeck=arguments;
return;
}
this.containerNode.innerHTML=_12;
if(_15){
this.set("textDir",_15);
}
this.containerNode.align=rtl?"right":"left";
var pos=_b.around(this.domNode,_13,_14&&_14.length?_14:_16.defaultPosition,!rtl,_7.hitch(this,"orient"));
var _17=pos.aroundNodePos;
if(pos.corner.charAt(0)=="M"&&pos.aroundCorner.charAt(0)=="M"){
this.connectorNode.style.top=_17.y+((_17.h-this.connectorNode.offsetHeight)>>1)-pos.y+"px";
this.connectorNode.style.left="";
}else{
if(pos.corner.charAt(1)=="M"&&pos.aroundCorner.charAt(1)=="M"){
this.connectorNode.style.left=_17.x+((_17.w-this.connectorNode.offsetWidth)>>1)-pos.x+"px";
}else{
this.connectorNode.style.left="";
this.connectorNode.style.top="";
}
}
_6.set(this.domNode,"opacity",0);
this.fadeIn.play();
this.isShowingNow=true;
this.aroundNode=_13;
},orient:function(_18,_19,_1a,_1b,_1c){
this.connectorNode.style.top="";
var _1d=_1b.h,_1e=_1b.w;
_18.className="dijitTooltip "+{"MR-ML":"dijitTooltipRight","ML-MR":"dijitTooltipLeft","TM-BM":"dijitTooltipAbove","BM-TM":"dijitTooltipBelow","BL-TL":"dijitTooltipBelow dijitTooltipABLeft","TL-BL":"dijitTooltipAbove dijitTooltipABLeft","BR-TR":"dijitTooltipBelow dijitTooltipABRight","TR-BR":"dijitTooltipAbove dijitTooltipABRight","BR-BL":"dijitTooltipRight","BL-BR":"dijitTooltipLeft"}[_19+"-"+_1a];
this.domNode.style.width="auto";
var _1f=_5.position(this.domNode);
if(_9("ie")==9){
_1f.w+=2;
}
var _20=Math.min((Math.max(_1e,1)),_1f.w);
_5.setMarginBox(this.domNode,{w:_20});
if(_1a.charAt(0)=="B"&&_19.charAt(0)=="B"){
var bb=_5.position(_18);
var _21=this.connectorNode.offsetHeight;
if(bb.h>_1d){
var _22=_1d-((_1c.h+_21)>>1);
this.connectorNode.style.top=_22+"px";
this.connectorNode.style.bottom="";
}else{
this.connectorNode.style.bottom=Math.min(Math.max(_1c.h/2-_21/2,0),bb.h-_21)+"px";
this.connectorNode.style.top="";
}
}else{
this.connectorNode.style.top="";
this.connectorNode.style.bottom="";
}
return Math.max(0,_1f.w-_1e);
},_onShow:function(){
if(_9("ie")){
this.domNode.style.filter="";
}
},hide:function(_23){
if(this._onDeck&&this._onDeck[1]==_23){
this._onDeck=null;
}else{
if(this.aroundNode===_23){
this.fadeIn.stop();
this.isShowingNow=false;
this.aroundNode=null;
this.fadeOut.play();
}else{
}
}
},_onHide:function(){
this.domNode.style.cssText="";
this.containerNode.innerHTML="";
if(this._onDeck){
this.show.apply(this,this._onDeck);
this._onDeck=null;
}
},_setAutoTextDir:function(_24){
this.applyTextDir(_24,_9("ie")?_24.outerText:_24.textContent);
_1.forEach(_24.children,function(_25){
this._setAutoTextDir(_25);
},this);
},_setTextDirAttr:function(_26){
this._set("textDir",_26);
if(_26=="auto"){
this._setAutoTextDir(this.containerNode);
}else{
this.containerNode.dir=this.textDir;
}
}});
_10.showTooltip=function(_27,_28,_29,rtl,_2a){
if(_29){
_29=_1.map(_29,function(val){
return {after:"after-centered",before:"before-centered"}[val]||val;
});
}
if(!_16._masterTT){
_10._masterTT=_16._masterTT=new _11();
}
return _16._masterTT.show(_27,_28,_29,rtl,_2a);
};
_10.hideTooltip=function(_2b){
return _16._masterTT&&_16._masterTT.hide(_2b);
};
var _16=_2("dijit.Tooltip",_c,{label:"",showDelay:400,connectId:[],position:[],selector:"",_setConnectIdAttr:function(_2c){
_1.forEach(this._connections||[],function(_2d){
_1.forEach(_2d,function(_2e){
_2e.remove();
});
},this);
this._connectIds=_1.filter(_7.isArrayLike(_2c)?_2c:(_2c?[_2c]:[]),function(id){
return _3.byId(id,this.ownerDocument);
},this);
this._connections=_1.map(this._connectIds,function(id){
var _2f=_3.byId(id,this.ownerDocument),_30=this.selector,_31=_30?function(_32){
return on.selector(_30,_32);
}:function(_33){
return _33;
},_34=this;
return [on(_2f,_31(_8.enter),function(){
_34._onHover(this);
}),on(_2f,_31("focusin"),function(){
_34._onHover(this);
}),on(_2f,_31(_8.leave),_7.hitch(_34,"_onUnHover")),on(_2f,_31("focusout"),_7.hitch(_34,"_onUnHover"))];
},this);
this._set("connectId",_2c);
},addTarget:function(_35){
var id=_35.id||_35;
if(_1.indexOf(this._connectIds,id)==-1){
this.set("connectId",this._connectIds.concat(id));
}
},removeTarget:function(_36){
var id=_36.id||_36,idx=_1.indexOf(this._connectIds,id);
if(idx>=0){
this._connectIds.splice(idx,1);
this.set("connectId",this._connectIds);
}
},buildRendering:function(){
this.inherited(arguments);
_4.add(this.domNode,"dijitTooltipData");
},startup:function(){
this.inherited(arguments);
var ids=this.connectId;
_1.forEach(_7.isArrayLike(ids)?ids:[ids],this.addTarget,this);
},getContent:function(_37){
return this.label||this.domNode.innerHTML;
},_onHover:function(_38){
if(!this._showTimer){
this._showTimer=this.defer(function(){
this.open(_38);
},this.showDelay);
}
},_onUnHover:function(){
if(this._showTimer){
this._showTimer.remove();
delete this._showTimer;
}
this.close();
},open:function(_39){
if(this._showTimer){
this._showTimer.remove();
delete this._showTimer;
}
var _3a=this.getContent(_39);
if(!_3a){
return;
}
_16.show(_3a,_39,this.position,!this.isLeftToRight(),this.textDir);
this._connectNode=_39;
this.onShow(_39,this.position);
},close:function(){
if(this._connectNode){
_16.hide(this._connectNode);
delete this._connectNode;
this.onHide();
}
if(this._showTimer){
this._showTimer.remove();
delete this._showTimer;
}
},onShow:function(){
},onHide:function(){
},destroy:function(){
this.close();
_1.forEach(this._connections||[],function(_3b){
_1.forEach(_3b,function(_3c){
_3c.remove();
});
},this);
this.inherited(arguments);
}});
_16._MasterTooltip=_11;
_16.show=_10.showTooltip;
_16.hide=_10.hideTooltip;
_16.defaultPosition=["after-centered","before-centered"];
return _16;
});

View File

@ -0,0 +1,542 @@
require({cache:{
'url:dijit/templates/Tooltip.html':"<div class=\"dijitTooltip dijitTooltipLeft\" id=\"dojoTooltip\"\n\t><div class=\"dijitTooltipContainer dijitTooltipContents\" data-dojo-attach-point=\"containerNode\" role='alert'></div\n\t><div class=\"dijitTooltipConnector\" data-dojo-attach-point=\"connectorNode\"></div\n></div>\n"}});
define("dijit/Tooltip", [
"dojo/_base/array", // array.forEach array.indexOf array.map
"dojo/_base/declare", // declare
"dojo/_base/fx", // fx.fadeIn fx.fadeOut
"dojo/dom", // dom.byId
"dojo/dom-class", // domClass.add
"dojo/dom-geometry", // domGeometry.position
"dojo/dom-style", // domStyle.set, domStyle.get
"dojo/_base/lang", // lang.hitch lang.isArrayLike
"dojo/mouse",
"dojo/on",
"dojo/sniff", // has("ie")
"./_base/manager", // manager.defaultDuration
"./place",
"./_Widget",
"./_TemplatedMixin",
"./BackgroundIframe",
"dojo/text!./templates/Tooltip.html",
"./main" // sets dijit.showTooltip etc. for back-compat
], function(array, declare, fx, dom, domClass, domGeometry, domStyle, lang, mouse, on, has,
manager, place, _Widget, _TemplatedMixin, BackgroundIframe, template, dijit){
// module:
// dijit/Tooltip
// TODO: Tooltip should really share more positioning code with TooltipDialog, like:
// - the orient() method
// - the connector positioning code in show()
// - the dijitTooltip[Dialog] class
//
// The problem is that Tooltip's implementation supplies it's own <iframe> and interacts directly
// with dijit/place, rather than going through dijit/popup like TooltipDialog and other popups (ex: Menu).
var MasterTooltip = declare("dijit._MasterTooltip", [_Widget, _TemplatedMixin], {
// summary:
// Internal widget that holds the actual tooltip markup,
// which occurs once per page.
// Called by Tooltip widgets which are just containers to hold
// the markup
// tags:
// protected
// duration: Integer
// Milliseconds to fade in/fade out
duration: manager.defaultDuration,
templateString: template,
postCreate: function(){
this.ownerDocumentBody.appendChild(this.domNode);
this.bgIframe = new BackgroundIframe(this.domNode);
// Setup fade-in and fade-out functions.
this.fadeIn = fx.fadeIn({ node: this.domNode, duration: this.duration, onEnd: lang.hitch(this, "_onShow") });
this.fadeOut = fx.fadeOut({ node: this.domNode, duration: this.duration, onEnd: lang.hitch(this, "_onHide") });
},
show: function(innerHTML, aroundNode, position, rtl, textDir){
// summary:
// Display tooltip w/specified contents to right of specified node
// (To left if there's no space on the right, or if rtl == true)
// innerHTML: String
// Contents of the tooltip
// aroundNode: DomNode|dijit/place.__Rectangle
// Specifies that tooltip should be next to this node / area
// position: String[]?
// List of positions to try to position tooltip (ex: ["right", "above"])
// rtl: Boolean?
// Corresponds to `WidgetBase.dir` attribute, where false means "ltr" and true
// means "rtl"; specifies GUI direction, not text direction.
// textDir: String?
// Corresponds to `WidgetBase.textdir` attribute; specifies direction of text.
if(this.aroundNode && this.aroundNode === aroundNode && this.containerNode.innerHTML == innerHTML){
return;
}
if(this.fadeOut.status() == "playing"){
// previous tooltip is being hidden; wait until the hide completes then show new one
this._onDeck=arguments;
return;
}
this.containerNode.innerHTML=innerHTML;
if(textDir){
this.set("textDir", textDir);
}
this.containerNode.align = rtl? "right" : "left"; //fix the text alignment
var pos = place.around(this.domNode, aroundNode,
position && position.length ? position : Tooltip.defaultPosition, !rtl, lang.hitch(this, "orient"));
// Position the tooltip connector for middle alignment.
// This could not have been done in orient() since the tooltip wasn't positioned at that time.
var aroundNodeCoords = pos.aroundNodePos;
if(pos.corner.charAt(0) == 'M' && pos.aroundCorner.charAt(0) == 'M'){
this.connectorNode.style.top = aroundNodeCoords.y + ((aroundNodeCoords.h - this.connectorNode.offsetHeight) >> 1) - pos.y + "px";
this.connectorNode.style.left = "";
}else if(pos.corner.charAt(1) == 'M' && pos.aroundCorner.charAt(1) == 'M'){
this.connectorNode.style.left = aroundNodeCoords.x + ((aroundNodeCoords.w - this.connectorNode.offsetWidth) >> 1) - pos.x + "px";
}else{
// Not *-centered, but just above/below/after/before
this.connectorNode.style.left = "";
this.connectorNode.style.top = "";
}
// show it
domStyle.set(this.domNode, "opacity", 0);
this.fadeIn.play();
this.isShowingNow = true;
this.aroundNode = aroundNode;
},
orient: function(/*DomNode*/ node, /*String*/ aroundCorner, /*String*/ tooltipCorner, /*Object*/ spaceAvailable, /*Object*/ aroundNodeCoords){
// summary:
// Private function to set CSS for tooltip node based on which position it's in.
// This is called by the dijit popup code. It will also reduce the tooltip's
// width to whatever width is available
// tags:
// protected
this.connectorNode.style.top = ""; //reset to default
var heightAvailable = spaceAvailable.h,
widthAvailable = spaceAvailable.w;
node.className = "dijitTooltip " +
{
"MR-ML": "dijitTooltipRight",
"ML-MR": "dijitTooltipLeft",
"TM-BM": "dijitTooltipAbove",
"BM-TM": "dijitTooltipBelow",
"BL-TL": "dijitTooltipBelow dijitTooltipABLeft",
"TL-BL": "dijitTooltipAbove dijitTooltipABLeft",
"BR-TR": "dijitTooltipBelow dijitTooltipABRight",
"TR-BR": "dijitTooltipAbove dijitTooltipABRight",
"BR-BL": "dijitTooltipRight",
"BL-BR": "dijitTooltipLeft"
}[aroundCorner + "-" + tooltipCorner];
// reset width; it may have been set by orient() on a previous tooltip show()
this.domNode.style.width = "auto";
// Reduce tooltip's width to the amount of width available, so that it doesn't overflow screen.
// Note that sometimes widthAvailable is negative, but we guard against setting style.width to a
// negative number since that causes an exception on IE.
var size = domGeometry.position(this.domNode);
if(has("ie") == 9){
// workaround strange IE9 bug where setting width to offsetWidth causes words to wrap
size.w += 2;
}
var width = Math.min((Math.max(widthAvailable,1)), size.w);
domGeometry.setMarginBox(this.domNode, {w: width});
// Reposition the tooltip connector.
if(tooltipCorner.charAt(0) == 'B' && aroundCorner.charAt(0) == 'B'){
var bb = domGeometry.position(node);
var tooltipConnectorHeight = this.connectorNode.offsetHeight;
if(bb.h > heightAvailable){
// The tooltip starts at the top of the page and will extend past the aroundNode
var aroundNodePlacement = heightAvailable - ((aroundNodeCoords.h + tooltipConnectorHeight) >> 1);
this.connectorNode.style.top = aroundNodePlacement + "px";
this.connectorNode.style.bottom = "";
}else{
// Align center of connector with center of aroundNode, except don't let bottom
// of connector extend below bottom of tooltip content, or top of connector
// extend past top of tooltip content
this.connectorNode.style.bottom = Math.min(
Math.max(aroundNodeCoords.h/2 - tooltipConnectorHeight/2, 0),
bb.h - tooltipConnectorHeight) + "px";
this.connectorNode.style.top = "";
}
}else{
// reset the tooltip back to the defaults
this.connectorNode.style.top = "";
this.connectorNode.style.bottom = "";
}
return Math.max(0, size.w - widthAvailable);
},
_onShow: function(){
// summary:
// Called at end of fade-in operation
// tags:
// protected
if(has("ie")){
// the arrow won't show up on a node w/an opacity filter
this.domNode.style.filter="";
}
},
hide: function(aroundNode){
// summary:
// Hide the tooltip
if(this._onDeck && this._onDeck[1] == aroundNode){
// this hide request is for a show() that hasn't even started yet;
// just cancel the pending show()
this._onDeck=null;
}else if(this.aroundNode === aroundNode){
// this hide request is for the currently displayed tooltip
this.fadeIn.stop();
this.isShowingNow = false;
this.aroundNode = null;
this.fadeOut.play();
}else{
// just ignore the call, it's for a tooltip that has already been erased
}
},
_onHide: function(){
// summary:
// Called at end of fade-out operation
// tags:
// protected
this.domNode.style.cssText=""; // to position offscreen again
this.containerNode.innerHTML="";
if(this._onDeck){
// a show request has been queued up; do it now
this.show.apply(this, this._onDeck);
this._onDeck=null;
}
},
_setAutoTextDir: function(/*Object*/node){
// summary:
// Resolve "auto" text direction for children nodes
// tags:
// private
this.applyTextDir(node, has("ie") ? node.outerText : node.textContent);
array.forEach(node.children, function(child){this._setAutoTextDir(child); }, this);
},
_setTextDirAttr: function(/*String*/ textDir){
// summary:
// Setter for textDir.
// description:
// Users shouldn't call this function; they should be calling
// set('textDir', value)
// tags:
// private
this._set("textDir", textDir);
if (textDir == "auto"){
this._setAutoTextDir(this.containerNode);
}else{
this.containerNode.dir = this.textDir;
}
}
});
dijit.showTooltip = function(innerHTML, aroundNode, position, rtl, textDir){
// summary:
// Static method to display tooltip w/specified contents in specified position.
// See description of dijit/Tooltip.defaultPosition for details on position parameter.
// If position is not specified then dijit/Tooltip.defaultPosition is used.
// innerHTML: String
// Contents of the tooltip
// aroundNode: place.__Rectangle
// Specifies that tooltip should be next to this node / area
// position: String[]?
// List of positions to try to position tooltip (ex: ["right", "above"])
// rtl: Boolean?
// Corresponds to `WidgetBase.dir` attribute, where false means "ltr" and true
// means "rtl"; specifies GUI direction, not text direction.
// textDir: String?
// Corresponds to `WidgetBase.textdir` attribute; specifies direction of text.
// After/before don't work, but for back-compat convert them to the working after-centered, before-centered.
// Possibly remove this in 2.0. Alternately, get before/after to work.
if(position){
position = array.map(position, function(val){
return {after: "after-centered", before: "before-centered"}[val] || val;
});
}
if(!Tooltip._masterTT){ dijit._masterTT = Tooltip._masterTT = new MasterTooltip(); }
return Tooltip._masterTT.show(innerHTML, aroundNode, position, rtl, textDir);
};
dijit.hideTooltip = function(aroundNode){
// summary:
// Static method to hide the tooltip displayed via showTooltip()
return Tooltip._masterTT && Tooltip._masterTT.hide(aroundNode);
};
var Tooltip = declare("dijit.Tooltip", _Widget, {
// summary:
// Pops up a tooltip (a help message) when you hover over a node.
// Also provides static show() and hide() methods that can be used without instantiating a dijit/Tooltip.
// label: String
// Text to display in the tooltip.
// Specified as innerHTML when creating the widget from markup.
label: "",
// showDelay: Integer
// Number of milliseconds to wait after hovering over/focusing on the object, before
// the tooltip is displayed.
showDelay: 400,
// connectId: String|String[]|DomNode|DomNode[]
// Id of domNode(s) to attach the tooltip to.
// When user hovers over specified dom node(s), the tooltip will appear.
connectId: [],
// position: String[]
// See description of `dijit/Tooltip.defaultPosition` for details on position parameter.
position: [],
// selector: String?
// CSS expression to apply this Tooltip to descendants of connectIds, rather than to
// the nodes specified by connectIds themselves. Useful for applying a Tooltip to
// a range of rows in a table, tree, etc. Use in conjunction with getContent() parameter.
// Ex: connectId: myTable, selector: "tr", getContent: function(node){ return ...; }
//
// The application must require() an appropriate level of dojo/query to handle the selector.
selector: "",
// TODO: in 2.0 remove support for multiple connectIds. selector gives the same effect.
// So, change connectId to a "", remove addTarget()/removeTarget(), etc.
_setConnectIdAttr: function(/*String|String[]}DomNode|DomNode[]*/ newId){
// summary:
// Connect to specified node(s)
// Remove connections to old nodes (if there are any)
array.forEach(this._connections || [], function(nested){
array.forEach(nested, function(handle){ handle.remove(); });
}, this);
// Make array of id's to connect to, excluding entries for nodes that don't exist yet, see startup()
this._connectIds = array.filter(lang.isArrayLike(newId) ? newId : (newId ? [newId] : []),
function(id){ return dom.byId(id, this.ownerDocument); }, this);
// Make connections
this._connections = array.map(this._connectIds, function(id){
var node = dom.byId(id, this.ownerDocument),
selector = this.selector,
delegatedEvent = selector ?
function(eventType){ return on.selector(selector, eventType); } :
function(eventType){ return eventType; },
self = this;
return [
on(node, delegatedEvent(mouse.enter), function(){
self._onHover(this);
}),
on(node, delegatedEvent("focusin"), function(){
self._onHover(this);
}),
on(node, delegatedEvent(mouse.leave), lang.hitch(self, "_onUnHover")),
on(node, delegatedEvent("focusout"), lang.hitch(self, "_onUnHover"))
];
}, this);
this._set("connectId", newId);
},
addTarget: function(/*OomNode|String*/ node){
// summary:
// Attach tooltip to specified node if it's not already connected
// TODO: remove in 2.0 and just use set("connectId", ...) interface
var id = node.id || node;
if(array.indexOf(this._connectIds, id) == -1){
this.set("connectId", this._connectIds.concat(id));
}
},
removeTarget: function(/*DomNode|String*/ node){
// summary:
// Detach tooltip from specified node
// TODO: remove in 2.0 and just use set("connectId", ...) interface
var id = node.id || node, // map from DOMNode back to plain id string
idx = array.indexOf(this._connectIds, id);
if(idx >= 0){
// remove id (modifies original this._connectIds but that's OK in this case)
this._connectIds.splice(idx, 1);
this.set("connectId", this._connectIds);
}
},
buildRendering: function(){
this.inherited(arguments);
domClass.add(this.domNode,"dijitTooltipData");
},
startup: function(){
this.inherited(arguments);
// If this tooltip was created in a template, or for some other reason the specified connectId[s]
// didn't exist during the widget's initialization, then connect now.
var ids = this.connectId;
array.forEach(lang.isArrayLike(ids) ? ids : [ids], this.addTarget, this);
},
getContent: function(/*DomNode*/ node){
// summary:
// User overridable function that return the text to display in the tooltip.
// tags:
// extension
return this.label || this.domNode.innerHTML;
},
_onHover: function(/*DomNode*/ target){
// summary:
// Despite the name of this method, it actually handles both hover and focus
// events on the target node, setting a timer to show the tooltip.
// tags:
// private
if(!this._showTimer){
this._showTimer = this.defer(function(){ this.open(target); }, this.showDelay);
}
},
_onUnHover: function(){
// summary:
// Despite the name of this method, it actually handles both mouseleave and blur
// events on the target node, hiding the tooltip.
// tags:
// private
if(this._showTimer){
this._showTimer.remove();
delete this._showTimer;
}
this.close();
},
open: function(/*DomNode*/ target){
// summary:
// Display the tooltip; usually not called directly.
// tags:
// private
if(this._showTimer){
this._showTimer.remove();
delete this._showTimer;
}
var content = this.getContent(target);
if(!content){
return;
}
Tooltip.show(content, target, this.position, !this.isLeftToRight(), this.textDir);
this._connectNode = target; // _connectNode means "tooltip currently displayed for this node"
this.onShow(target, this.position);
},
close: function(){
// summary:
// Hide the tooltip or cancel timer for show of tooltip
// tags:
// private
if(this._connectNode){
// if tooltip is currently shown
Tooltip.hide(this._connectNode);
delete this._connectNode;
this.onHide();
}
if(this._showTimer){
// if tooltip is scheduled to be shown (after a brief delay)
this._showTimer.remove();
delete this._showTimer;
}
},
onShow: function(/*===== target, position =====*/){
// summary:
// Called when the tooltip is shown
// tags:
// callback
},
onHide: function(){
// summary:
// Called when the tooltip is hidden
// tags:
// callback
},
destroy: function(){
this.close();
// Remove connections manually since they aren't registered to be removed by _WidgetBase
array.forEach(this._connections || [], function(nested){
array.forEach(nested, function(handle){ handle.remove(); });
}, this);
this.inherited(arguments);
}
});
Tooltip._MasterTooltip = MasterTooltip; // for monkey patching
Tooltip.show = dijit.showTooltip; // export function through module return value
Tooltip.hide = dijit.hideTooltip; // export function through module return value
Tooltip.defaultPosition = ["after-centered", "before-centered"];
/*=====
lang.mixin(Tooltip, {
// defaultPosition: String[]
// This variable controls the position of tooltips, if the position is not specified to
// the Tooltip widget or *TextBox widget itself. It's an array of strings with the values
// possible for `dijit/place.around()`. The recommended values are:
//
// - before-centered: centers tooltip to the left of the anchor node/widget, or to the right
// in the case of RTL scripts like Hebrew and Arabic
// - after-centered: centers tooltip to the right of the anchor node/widget, or to the left
// in the case of RTL scripts like Hebrew and Arabic
// - above-centered: tooltip is centered above anchor node
// - below-centered: tooltip is centered above anchor node
//
// The list is positions is tried, in order, until a position is found where the tooltip fits
// within the viewport.
//
// Be careful setting this parameter. A value of "above-centered" may work fine until the user scrolls
// the screen so that there's no room above the target node. Nodes with drop downs, like
// DropDownButton or FilteringSelect, are especially problematic, in that you need to be sure
// that the drop down and tooltip don't overlap, even when the viewport is scrolled so that there
// is only room below (or above) the target node, but not both.
});
=====*/
return Tooltip;
});

View File

@ -0,0 +1,60 @@
//>>built
require({cache:{"url:dijit/templates/TooltipDialog.html":"<div role=\"presentation\" tabIndex=\"-1\">\n\t<div class=\"dijitTooltipContainer\" role=\"presentation\">\n\t\t<div class =\"dijitTooltipContents dijitTooltipFocusNode\" data-dojo-attach-point=\"containerNode\" role=\"dialog\"></div>\n\t</div>\n\t<div class=\"dijitTooltipConnector\" role=\"presentation\" data-dojo-attach-point=\"connectorNode\"></div>\n</div>\n"}});
define("dijit/TooltipDialog",["dojo/_base/declare","dojo/dom-class","dojo/_base/event","dojo/keys","dojo/_base/lang","./focus","./layout/ContentPane","./_DialogMixin","./form/_FormMixin","./_TemplatedMixin","dojo/text!./templates/TooltipDialog.html","./main"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c){
return _1("dijit.TooltipDialog",[_7,_a,_9,_8],{title:"",doLayout:false,autofocus:true,baseClass:"dijitTooltipDialog",_firstFocusItem:null,_lastFocusItem:null,templateString:_b,_setTitleAttr:function(_d){
this.containerNode.title=_d;
this._set("title",_d);
},postCreate:function(){
this.inherited(arguments);
this.connect(this.containerNode,"onkeypress","_onKey");
},orient:function(_e,_f,_10){
var _11={"MR-ML":"dijitTooltipRight","ML-MR":"dijitTooltipLeft","TM-BM":"dijitTooltipAbove","BM-TM":"dijitTooltipBelow","BL-TL":"dijitTooltipBelow dijitTooltipABLeft","TL-BL":"dijitTooltipAbove dijitTooltipABLeft","BR-TR":"dijitTooltipBelow dijitTooltipABRight","TR-BR":"dijitTooltipAbove dijitTooltipABRight","BR-BL":"dijitTooltipRight","BL-BR":"dijitTooltipLeft"}[_f+"-"+_10];
_2.replace(this.domNode,_11,this._currentOrientClass||"");
this._currentOrientClass=_11;
},focus:function(){
this._getFocusItems(this.containerNode);
_6.focus(this._firstFocusItem);
},onOpen:function(pos){
this.orient(this.domNode,pos.aroundCorner,pos.corner);
var _12=pos.aroundNodePos;
if(pos.corner.charAt(0)=="M"&&pos.aroundCorner.charAt(0)=="M"){
this.connectorNode.style.top=_12.y+((_12.h-this.connectorNode.offsetHeight)>>1)-pos.y+"px";
this.connectorNode.style.left="";
}else{
if(pos.corner.charAt(1)=="M"&&pos.aroundCorner.charAt(1)=="M"){
this.connectorNode.style.left=_12.x+((_12.w-this.connectorNode.offsetWidth)>>1)-pos.x+"px";
}
}
this._onShow();
},onClose:function(){
this.onHide();
},_onKey:function(evt){
var _13=evt.target;
if(evt.charOrCode===_4.TAB){
this._getFocusItems(this.containerNode);
}
var _14=(this._firstFocusItem==this._lastFocusItem);
if(evt.charOrCode==_4.ESCAPE){
this.defer("onCancel");
_3.stop(evt);
}else{
if(_13==this._firstFocusItem&&evt.shiftKey&&evt.charOrCode===_4.TAB){
if(!_14){
_6.focus(this._lastFocusItem);
}
_3.stop(evt);
}else{
if(_13==this._lastFocusItem&&evt.charOrCode===_4.TAB&&!evt.shiftKey){
if(!_14){
_6.focus(this._firstFocusItem);
}
_3.stop(evt);
}else{
if(evt.charOrCode===_4.TAB){
evt.stopPropagation();
}
}
}
}
}});
});

View File

@ -0,0 +1,174 @@
require({cache:{
'url:dijit/templates/TooltipDialog.html':"<div role=\"presentation\" tabIndex=\"-1\">\n\t<div class=\"dijitTooltipContainer\" role=\"presentation\">\n\t\t<div class =\"dijitTooltipContents dijitTooltipFocusNode\" data-dojo-attach-point=\"containerNode\" role=\"dialog\"></div>\n\t</div>\n\t<div class=\"dijitTooltipConnector\" role=\"presentation\" data-dojo-attach-point=\"connectorNode\"></div>\n</div>\n"}});
define("dijit/TooltipDialog", [
"dojo/_base/declare", // declare
"dojo/dom-class", // domClass.replace
"dojo/_base/event", // event.stop
"dojo/keys", // keys
"dojo/_base/lang", // lang.hitch
"./focus",
"./layout/ContentPane",
"./_DialogMixin",
"./form/_FormMixin",
"./_TemplatedMixin",
"dojo/text!./templates/TooltipDialog.html",
"./main" // exports methods to dijit global
], function(declare, domClass, event, keys, lang,
focus, ContentPane, _DialogMixin, _FormMixin, _TemplatedMixin, template, dijit){
// module:
// dijit/TooltipDialog
return declare("dijit.TooltipDialog",
[ContentPane, _TemplatedMixin, _FormMixin, _DialogMixin], {
// summary:
// Pops up a dialog that appears like a Tooltip
// title: String
// Description of tooltip dialog (required for a11y)
title: "",
// doLayout: [protected] Boolean
// Don't change this parameter from the default value.
// This ContentPane parameter doesn't make sense for TooltipDialog, since TooltipDialog
// is never a child of a layout container, nor can you specify the size of
// TooltipDialog in order to control the size of an inner widget.
doLayout: false,
// autofocus: Boolean
// A Toggle to modify the default focus behavior of a Dialog, which
// is to focus on the first dialog element after opening the dialog.
// False will disable autofocusing. Default: true.
autofocus: true,
// baseClass: [protected] String
// The root className to use for the various states of this widget
baseClass: "dijitTooltipDialog",
// _firstFocusItem: [private readonly] DomNode
// The pointer to the first focusable node in the dialog.
// Set by `dijit/_DialogMixin._getFocusItems()`.
_firstFocusItem: null,
// _lastFocusItem: [private readonly] DomNode
// The pointer to which node has focus prior to our dialog.
// Set by `dijit/_DialogMixin._getFocusItems()`.
_lastFocusItem: null,
templateString: template,
_setTitleAttr: function(/*String*/ title){
this.containerNode.title = title;
this._set("title", title);
},
postCreate: function(){
this.inherited(arguments);
this.connect(this.containerNode, "onkeypress", "_onKey");
},
orient: function(/*DomNode*/ node, /*String*/ aroundCorner, /*String*/ tooltipCorner){
// summary:
// Configure widget to be displayed in given position relative to the button.
// This is called from the dijit.popup code, and should not be called
// directly.
// tags:
// protected
// Note: intentionally not using dijitTooltip class since that sets position:absolute, which
// confuses dijit/popup trying to get the size of the tooltip.
var newC = {
"MR-ML": "dijitTooltipRight",
"ML-MR": "dijitTooltipLeft",
"TM-BM": "dijitTooltipAbove",
"BM-TM": "dijitTooltipBelow",
"BL-TL": "dijitTooltipBelow dijitTooltipABLeft",
"TL-BL": "dijitTooltipAbove dijitTooltipABLeft",
"BR-TR": "dijitTooltipBelow dijitTooltipABRight",
"TR-BR": "dijitTooltipAbove dijitTooltipABRight",
"BR-BL": "dijitTooltipRight",
"BL-BR": "dijitTooltipLeft"
}[aroundCorner + "-" + tooltipCorner];
domClass.replace(this.domNode, newC, this._currentOrientClass || "");
this._currentOrientClass = newC;
// Tooltip.orient() has code to reposition connector for when Tooltip is before/after anchor.
// Not putting here to avoid code bloat, and since TooltipDialogs are generally above/below.
// Should combine code from Tooltip and TooltipDialog.
},
focus: function(){
// summary:
// Focus on first field
this._getFocusItems(this.containerNode);
focus.focus(this._firstFocusItem);
},
onOpen: function(/*Object*/ pos){
// summary:
// Called when dialog is displayed.
// This is called from the dijit.popup code, and should not be called directly.
// tags:
// protected
this.orient(this.domNode,pos.aroundCorner, pos.corner);
// Position the tooltip connector for middle alignment.
// This could not have been done in orient() since the tooltip wasn't positioned at that time.
var aroundNodeCoords = pos.aroundNodePos;
if(pos.corner.charAt(0) == 'M' && pos.aroundCorner.charAt(0) == 'M'){
this.connectorNode.style.top = aroundNodeCoords.y + ((aroundNodeCoords.h - this.connectorNode.offsetHeight) >> 1) - pos.y + "px";
this.connectorNode.style.left = "";
}else if(pos.corner.charAt(1) == 'M' && pos.aroundCorner.charAt(1) == 'M'){
this.connectorNode.style.left = aroundNodeCoords.x + ((aroundNodeCoords.w - this.connectorNode.offsetWidth) >> 1) - pos.x + "px";
}
this._onShow(); // lazy load trigger (TODO: shouldn't we load before positioning?)
},
onClose: function(){
// summary:
// Called when dialog is hidden.
// This is called from the dijit.popup code, and should not be called directly.
// tags:
// protected
this.onHide();
},
_onKey: function(/*Event*/ evt){
// summary:
// Handler for keyboard events
// description:
// Keep keyboard focus in dialog; close dialog on escape key
// tags:
// private
var node = evt.target;
if(evt.charOrCode === keys.TAB){
this._getFocusItems(this.containerNode);
}
var singleFocusItem = (this._firstFocusItem == this._lastFocusItem);
if(evt.charOrCode == keys.ESCAPE){
// Use defer to avoid crash on IE, see #10396.
this.defer("onCancel");
event.stop(evt);
}else if(node == this._firstFocusItem && evt.shiftKey && evt.charOrCode === keys.TAB){
if(!singleFocusItem){
focus.focus(this._lastFocusItem); // send focus to last item in dialog
}
event.stop(evt);
}else if(node == this._lastFocusItem && evt.charOrCode === keys.TAB && !evt.shiftKey){
if(!singleFocusItem){
focus.focus(this._firstFocusItem); // send focus to first item in dialog
}
event.stop(evt);
}else if(evt.charOrCode === keys.TAB){
// we want the browser's default tab handling to move focus
// but we don't want the tab to propagate upwards
evt.stopPropagation();
}
}
});
});

View File

@ -0,0 +1,791 @@
//>>built
require({cache:{"url:dijit/templates/TreeNode.html":"<div class=\"dijitTreeNode\" role=\"presentation\"\n\t><div data-dojo-attach-point=\"rowNode\" class=\"dijitTreeRow dijitInline\" role=\"presentation\"\n\t\t><div data-dojo-attach-point=\"indentNode\" class=\"dijitInline\"></div\n\t\t><img src=\"${_blankGif}\" alt=\"\" data-dojo-attach-point=\"expandoNode\" class=\"dijitTreeExpando\" role=\"presentation\"\n\t\t/><span data-dojo-attach-point=\"expandoNodeText\" class=\"dijitExpandoText\" role=\"presentation\"\n\t\t></span\n\t\t><span data-dojo-attach-point=\"contentNode\"\n\t\t\tclass=\"dijitTreeContent\" role=\"presentation\">\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" data-dojo-attach-point=\"iconNode\" class=\"dijitIcon dijitTreeIcon\" role=\"presentation\"\n\t\t\t/><span data-dojo-attach-point=\"labelNode\" class=\"dijitTreeLabel\" role=\"treeitem\" tabindex=\"-1\" aria-selected=\"false\"></span>\n\t\t</span\n\t></div>\n\t<div data-dojo-attach-point=\"containerNode\" class=\"dijitTreeContainer\" role=\"presentation\" style=\"display: none;\"></div>\n</div>\n","url:dijit/templates/Tree.html":"<div class=\"dijitTree dijitTreeContainer\" role=\"tree\">\n\t<div class=\"dijitInline dijitTreeIndent\" style=\"position: absolute; top: -9999px\" data-dojo-attach-point=\"indentDetector\"></div>\n</div>\n"}});
define("dijit/Tree",["dojo/_base/array","dojo/_base/connect","dojo/cookie","dojo/_base/declare","dojo/Deferred","dojo/DeferredList","dojo/dom","dojo/dom-class","dojo/dom-geometry","dojo/dom-style","dojo/_base/event","dojo/errors/create","dojo/fx","dojo/_base/kernel","dojo/keys","dojo/_base/lang","dojo/on","dojo/topic","dojo/touch","dojo/when","./focus","./registry","./_base/manager","./_Widget","./_TemplatedMixin","./_Container","./_Contained","./_CssStateMixin","dojo/text!./templates/TreeNode.html","dojo/text!./templates/Tree.html","./tree/TreeStoreModel","./tree/ForestStoreModel","./tree/_dndSelector"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c,_d,_e,_f,_10,on,_11,_12,_13,_14,_15,_16,_17,_18,_19,_1a,_1b,_1c,_1d,_1e,_1f,_20){
_5=_4(_5,{addCallback:function(_21){
this.then(_21);
},addErrback:function(_22){
this.then(null,_22);
}});
var _23=_4("dijit._TreeNode",[_17,_18,_19,_1a,_1b],{item:null,isTreeNode:true,label:"",_setLabelAttr:{node:"labelNode",type:"innerText"},isExpandable:null,isExpanded:false,state:"UNCHECKED",templateString:_1c,baseClass:"dijitTreeNode",cssStateNodes:{rowNode:"dijitTreeRow"},_setTooltipAttr:{node:"rowNode",type:"attribute",attribute:"title"},buildRendering:function(){
this.inherited(arguments);
this._setExpando();
this._updateItemClasses(this.item);
if(this.isExpandable){
this.labelNode.setAttribute("aria-expanded",this.isExpanded);
}
this.setSelected(false);
},_setIndentAttr:function(_24){
var _25=(Math.max(_24,0)*this.tree._nodePixelIndent)+"px";
_a.set(this.domNode,"backgroundPosition",_25+" 0px");
_a.set(this.indentNode,this.isLeftToRight()?"paddingLeft":"paddingRight",_25);
_1.forEach(this.getChildren(),function(_26){
_26.set("indent",_24+1);
});
this._set("indent",_24);
},markProcessing:function(){
this.state="LOADING";
this._setExpando(true);
},unmarkProcessing:function(){
this._setExpando(false);
},_updateItemClasses:function(_27){
var _28=this.tree,_29=_28.model;
if(_28._v10Compat&&_27===_29.root){
_27=null;
}
this._applyClassAndStyle(_27,"icon","Icon");
this._applyClassAndStyle(_27,"label","Label");
this._applyClassAndStyle(_27,"row","Row");
this.tree._startPaint(true);
},_applyClassAndStyle:function(_2a,_2b,_2c){
var _2d="_"+_2b+"Class";
var _2e=_2b+"Node";
var _2f=this[_2d];
this[_2d]=this.tree["get"+_2c+"Class"](_2a,this.isExpanded);
_8.replace(this[_2e],this[_2d]||"",_2f||"");
_a.set(this[_2e],this.tree["get"+_2c+"Style"](_2a,this.isExpanded)||{});
},_updateLayout:function(){
var _30=this.getParent();
if(!_30||!_30.rowNode||_30.rowNode.style.display=="none"){
_8.add(this.domNode,"dijitTreeIsRoot");
}else{
_8.toggle(this.domNode,"dijitTreeIsLast",!this.getNextSibling());
}
},_setExpando:function(_31){
var _32=["dijitTreeExpandoLoading","dijitTreeExpandoOpened","dijitTreeExpandoClosed","dijitTreeExpandoLeaf"],_33=["*","-","+","*"],idx=_31?0:(this.isExpandable?(this.isExpanded?1:2):3);
_8.replace(this.expandoNode,_32[idx],_32);
this.expandoNodeText.innerHTML=_33[idx];
},expand:function(){
if(this._expandDeferred){
return this._expandDeferred;
}
if(this._collapseDeferred){
this._collapseDeferred.cancel();
delete this._collapseDeferred;
}
this.isExpanded=true;
this.labelNode.setAttribute("aria-expanded","true");
if(this.tree.showRoot||this!==this.tree.rootNode){
this.containerNode.setAttribute("role","group");
}
_8.add(this.contentNode,"dijitTreeContentExpanded");
this._setExpando();
this._updateItemClasses(this.item);
if(this==this.tree.rootNode&&this.tree.showRoot){
this.tree.domNode.setAttribute("aria-expanded","true");
}
var def,_34=_d.wipeIn({node:this.containerNode,duration:_16.defaultDuration,onEnd:function(){
def.resolve(true);
}});
def=(this._expandDeferred=new _5(function(){
_34.stop();
}));
_34.play();
return def;
},collapse:function(){
if(this._collapseDeferred){
return this._collapseDeferred;
}
if(this._expandDeferred){
this._expandDeferred.cancel();
delete this._expandDeferred;
}
this.isExpanded=false;
this.labelNode.setAttribute("aria-expanded","false");
if(this==this.tree.rootNode&&this.tree.showRoot){
this.tree.domNode.setAttribute("aria-expanded","false");
}
_8.remove(this.contentNode,"dijitTreeContentExpanded");
this._setExpando();
this._updateItemClasses(this.item);
var def,_35=_d.wipeOut({node:this.containerNode,duration:_16.defaultDuration,onEnd:function(){
def.resolve(true);
}});
def=(this._collapseDeferred=new _5(function(){
_35.stop();
}));
_35.play();
return def;
},indent:0,setChildItems:function(_36){
var _37=this.tree,_38=_37.model,_39=[];
var _3a=this.getChildren();
_1.forEach(_3a,function(_3b){
_19.prototype.removeChild.call(this,_3b);
},this);
this.defer(function(){
_1.forEach(_3a,function(_3c){
if(!_3c._destroyed&&!_3c.getParent()){
_37.dndController.removeTreeNode(_3c);
var id=_38.getIdentity(_3c.item),ary=_37._itemNodesMap[id];
if(ary.length==1){
delete _37._itemNodesMap[id];
}else{
var _3d=_1.indexOf(ary,_3c);
if(_3d!=-1){
ary.splice(_3d,1);
}
}
_3c.destroyRecursive();
}
});
});
this.state="LOADED";
if(_36&&_36.length>0){
this.isExpandable=true;
_1.forEach(_36,function(_3e){
var id=_38.getIdentity(_3e),_3f=_37._itemNodesMap[id],_40;
if(_3f){
for(var i=0;i<_3f.length;i++){
if(_3f[i]&&!_3f[i].getParent()){
_40=_3f[i];
_40.set("indent",this.indent+1);
break;
}
}
}
if(!_40){
_40=this.tree._createTreeNode({item:_3e,tree:_37,isExpandable:_38.mayHaveChildren(_3e),label:_37.getLabel(_3e),tooltip:_37.getTooltip(_3e),ownerDocument:_37.ownerDocument,dir:_37.dir,lang:_37.lang,textDir:_37.textDir,indent:this.indent+1});
if(_3f){
_3f.push(_40);
}else{
_37._itemNodesMap[id]=[_40];
}
}
this.addChild(_40);
if(this.tree.autoExpand||this.tree._state(_40)){
_39.push(_37._expandNode(_40));
}
},this);
_1.forEach(this.getChildren(),function(_41){
_41._updateLayout();
});
}else{
this.isExpandable=false;
}
if(this._setExpando){
this._setExpando(false);
}
this._updateItemClasses(this.item);
if(this==_37.rootNode){
var fc=this.tree.showRoot?this:this.getChildren()[0];
if(fc){
fc.setFocusable(true);
_37.lastFocused=fc;
}else{
_37.domNode.setAttribute("tabIndex","0");
}
}
var def=new _6(_39);
this.tree._startPaint(def);
return def;
},getTreePath:function(){
var _42=this;
var _43=[];
while(_42&&_42!==this.tree.rootNode){
_43.unshift(_42.item);
_42=_42.getParent();
}
_43.unshift(this.tree.rootNode.item);
return _43;
},getIdentity:function(){
return this.tree.model.getIdentity(this.item);
},removeChild:function(_44){
this.inherited(arguments);
var _45=this.getChildren();
if(_45.length==0){
this.isExpandable=false;
this.collapse();
}
_1.forEach(_45,function(_46){
_46._updateLayout();
});
},makeExpandable:function(){
this.isExpandable=true;
this._setExpando(false);
},setSelected:function(_47){
this.labelNode.setAttribute("aria-selected",_47?"true":"false");
_8.toggle(this.rowNode,"dijitTreeRowSelected",_47);
},setFocusable:function(_48){
this.labelNode.setAttribute("tabIndex",_48?"0":"-1");
},_setTextDirAttr:function(_49){
if(_49&&((this.textDir!=_49)||!this._created)){
this._set("textDir",_49);
this.applyTextDir(this.labelNode,this.labelNode.innerText||this.labelNode.textContent||"");
_1.forEach(this.getChildren(),function(_4a){
_4a.set("textDir",_49);
},this);
}
}});
var _4b=_4("dijit.Tree",[_17,_18],{store:null,model:null,query:null,label:"",showRoot:true,childrenAttr:["children"],paths:[],path:[],selectedItems:null,selectedItem:null,openOnClick:false,openOnDblClick:false,templateString:_1d,persist:true,autoExpand:false,dndController:_20,dndParams:["onDndDrop","itemCreator","onDndCancel","checkAcceptance","checkItemAcceptance","dragThreshold","betweenThreshold"],onDndDrop:null,itemCreator:null,onDndCancel:null,checkAcceptance:null,checkItemAcceptance:null,dragThreshold:5,betweenThreshold:0,_nodePixelIndent:19,_publish:function(_4c,_4d){
_11.publish(this.id,_10.mixin({tree:this,event:_4c},_4d||{}));
},postMixInProperties:function(){
this.tree=this;
if(this.autoExpand){
this.persist=false;
}
this._itemNodesMap={};
if(!this.cookieName&&this.id){
this.cookieName=this.id+"SaveStateCookie";
}
this.expandChildrenDeferred=new _5();
this.pendingCommandsDeferred=this.expandChildrenDeferred;
this.inherited(arguments);
},postCreate:function(){
this._initState();
var _4e=this;
this.own(on(this.domNode,on.selector(".dijitTreeNode",_12.enter),function(evt){
_4e._onNodeMouseEnter(_15.byNode(this),evt);
}),on(this.domNode,on.selector(".dijitTreeNode",_12.leave),function(evt){
_4e._onNodeMouseLeave(_15.byNode(this),evt);
}),on(this.domNode,on.selector(".dijitTreeNode","click"),function(evt){
_4e._onClick(_15.byNode(this),evt);
}),on(this.domNode,on.selector(".dijitTreeNode","dblclick"),function(evt){
_4e._onDblClick(_15.byNode(this),evt);
}),on(this.domNode,on.selector(".dijitTreeNode","keypress"),function(evt){
_4e._onKeyPress(_15.byNode(this),evt);
}),on(this.domNode,on.selector(".dijitTreeNode","keydown"),function(evt){
_4e._onKeyDown(_15.byNode(this),evt);
}),on(this.domNode,on.selector(".dijitTreeRow","focusin"),function(evt){
_4e._onNodeFocus(_15.getEnclosingWidget(this),evt);
}));
if(!this.model){
this._store2model();
}
this.connect(this.model,"onChange","_onItemChange");
this.connect(this.model,"onChildrenChange","_onItemChildrenChange");
this.connect(this.model,"onDelete","_onItemDelete");
this.inherited(arguments);
if(this.dndController){
if(_10.isString(this.dndController)){
this.dndController=_10.getObject(this.dndController);
}
var _4f={};
for(var i=0;i<this.dndParams.length;i++){
if(this[this.dndParams[i]]){
_4f[this.dndParams[i]]=this[this.dndParams[i]];
}
}
this.dndController=new this.dndController(this,_4f);
}
this._load();
if(!this.params.path&&!this.params.paths&&this.persist){
this.set("paths",this.dndController._getSavedPaths());
}
this.onLoadDeferred=this.pendingCommandsDeferred;
this.onLoadDeferred.then(_10.hitch(this,"onLoad"));
},_store2model:function(){
this._v10Compat=true;
_e.deprecated("Tree: from version 2.0, should specify a model object rather than a store/query");
var _50={id:this.id+"_ForestStoreModel",store:this.store,query:this.query,childrenAttrs:this.childrenAttr};
if(this.params.mayHaveChildren){
_50.mayHaveChildren=_10.hitch(this,"mayHaveChildren");
}
if(this.params.getItemChildren){
_50.getChildren=_10.hitch(this,function(_51,_52,_53){
this.getItemChildren((this._v10Compat&&_51===this.model.root)?null:_51,_52,_53);
});
}
this.model=new _1f(_50);
this.showRoot=Boolean(this.label);
},onLoad:function(){
},_load:function(){
this.model.getRoot(_10.hitch(this,function(_54){
var rn=(this.rootNode=this.tree._createTreeNode({item:_54,tree:this,isExpandable:true,label:this.label||this.getLabel(_54),textDir:this.textDir,indent:this.showRoot?0:-1}));
if(!this.showRoot){
rn.rowNode.style.display="none";
this.domNode.setAttribute("role","presentation");
this.domNode.removeAttribute("aria-expanded");
this.domNode.removeAttribute("aria-multiselectable");
rn.labelNode.setAttribute("role","presentation");
rn.containerNode.setAttribute("role","tree");
rn.containerNode.setAttribute("aria-expanded","true");
rn.containerNode.setAttribute("aria-multiselectable",!this.dndController.singular);
}else{
this.domNode.setAttribute("aria-multiselectable",!this.dndController.singular);
}
this.domNode.appendChild(rn.domNode);
var _55=this.model.getIdentity(_54);
if(this._itemNodesMap[_55]){
this._itemNodesMap[_55].push(rn);
}else{
this._itemNodesMap[_55]=[rn];
}
rn._updateLayout();
this._expandNode(rn).then(_10.hitch(this,function(){
this.expandChildrenDeferred.resolve(true);
}));
}),_10.hitch(this,function(err){
console.error(this,": error loading root: ",err);
}));
},getNodesByItem:function(_56){
if(!_56){
return [];
}
var _57=_10.isString(_56)?_56:this.model.getIdentity(_56);
return [].concat(this._itemNodesMap[_57]);
},_setSelectedItemAttr:function(_58){
this.set("selectedItems",[_58]);
},_setSelectedItemsAttr:function(_59){
var _5a=this;
return this.pendingCommandsDeferred=this.pendingCommandsDeferred.then(_10.hitch(this,function(){
var _5b=_1.map(_59,function(_5c){
return (!_5c||_10.isString(_5c))?_5c:_5a.model.getIdentity(_5c);
});
var _5d=[];
_1.forEach(_5b,function(id){
_5d=_5d.concat(_5a._itemNodesMap[id]||[]);
});
this.set("selectedNodes",_5d);
}));
},_setPathAttr:function(_5e){
if(_5e.length){
return this.set("paths",[_5e]);
}else{
return this.set("paths",[]);
}
},_setPathsAttr:function(_5f){
var _60=this;
return this.pendingCommandsDeferred=this.pendingCommandsDeferred.then(function(){
return new _6(_1.map(_5f,function(_61){
var d=new _5();
_61=_1.map(_61,function(_62){
return _10.isString(_62)?_62:_60.model.getIdentity(_62);
});
if(_61.length){
_63(_61,[_60.rootNode],d);
}else{
d.reject(new _4b.PathError("Empty path"));
}
return d;
}));
}).then(_64);
function _63(_65,_66,def){
var _67=_65.shift();
var _68=_1.filter(_66,function(_69){
return _69.getIdentity()==_67;
})[0];
if(!!_68){
if(_65.length){
_60._expandNode(_68).then(function(){
_63(_65,_68.getChildren(),def);
});
}else{
def.resolve(_68);
}
}else{
def.reject(new _4b.PathError("Could not expand path at "+_67));
}
};
function _64(_6a){
_60.set("selectedNodes",_1.map(_1.filter(_6a,function(x){
return x[0];
}),function(x){
return x[1];
}));
};
},_setSelectedNodeAttr:function(_6b){
this.set("selectedNodes",[_6b]);
},_setSelectedNodesAttr:function(_6c){
this.dndController.setSelection(_6c);
},expandAll:function(){
var _6d=this;
function _6e(_6f){
var def=new dojo.Deferred();
_6d._expandNode(_6f).then(function(){
var _70=_1.filter(_6f.getChildren()||[],function(_71){
return _71.isExpandable;
}),_72=_1.map(_70,_6e);
new dojo.DeferredList(_72).then(function(){
def.resolve(true);
});
});
return def;
};
return _6e(this.rootNode);
},collapseAll:function(){
var _73=this;
function _74(_75){
var def=new dojo.Deferred();
def.label="collapseAllDeferred";
var _76=_1.filter(_75.getChildren()||[],function(_77){
return _77.isExpandable;
}),_78=_1.map(_76,_74);
new dojo.DeferredList(_78).then(function(){
if(!_75.isExpanded||(_75==_73.rootNode&&!_73.showRoot)){
def.resolve(true);
}else{
_73._collapseNode(_75).then(function(){
def.resolve(true);
});
}
});
return def;
};
return _74(this.rootNode);
},mayHaveChildren:function(){
},getItemChildren:function(){
},getLabel:function(_79){
return this.model.getLabel(_79);
},getIconClass:function(_7a,_7b){
return (!_7a||this.model.mayHaveChildren(_7a))?(_7b?"dijitFolderOpened":"dijitFolderClosed"):"dijitLeaf";
},getLabelClass:function(){
},getRowClass:function(){
},getIconStyle:function(){
},getLabelStyle:function(){
},getRowStyle:function(){
},getTooltip:function(){
return "";
},_onKeyPress:function(_7c,e){
if(e.charCode<=32){
return;
}
if(!e.altKey&&!e.ctrlKey&&!e.shiftKey&&!e.metaKey){
var c=String.fromCharCode(e.charCode);
this._onLetterKeyNav({node:_7c,key:c.toLowerCase()});
_b.stop(e);
}
},_onKeyDown:function(_7d,e){
var key=e.keyCode;
var map=this._keyHandlerMap;
if(!map){
map={};
map[_f.ENTER]=map[_f.SPACE]=map[" "]="_onEnterKey";
map[this.isLeftToRight()?_f.LEFT_ARROW:_f.RIGHT_ARROW]="_onLeftArrow";
map[this.isLeftToRight()?_f.RIGHT_ARROW:_f.LEFT_ARROW]="_onRightArrow";
map[_f.UP_ARROW]="_onUpArrow";
map[_f.DOWN_ARROW]="_onDownArrow";
map[_f.HOME]="_onHomeKey";
map[_f.END]="_onEndKey";
this._keyHandlerMap=map;
}
if(this._keyHandlerMap[key]){
if(this._curSearch){
this._curSearch.timer.remove();
delete this._curSearch;
}
this[this._keyHandlerMap[key]]({node:_7d,item:_7d.item,evt:e});
_b.stop(e);
}
},_onEnterKey:function(_7e){
this._publish("execute",{item:_7e.item,node:_7e.node});
this.dndController.userSelect(_7e.node,_2.isCopyKey(_7e.evt),_7e.evt.shiftKey);
this.onClick(_7e.item,_7e.node,_7e.evt);
},_onDownArrow:function(_7f){
var _80=this._getNextNode(_7f.node);
if(_80&&_80.isTreeNode){
this.focusNode(_80);
}
},_onUpArrow:function(_81){
var _82=_81.node;
var _83=_82.getPreviousSibling();
if(_83){
_82=_83;
while(_82.isExpandable&&_82.isExpanded&&_82.hasChildren()){
var _84=_82.getChildren();
_82=_84[_84.length-1];
}
}else{
var _85=_82.getParent();
if(!(!this.showRoot&&_85===this.rootNode)){
_82=_85;
}
}
if(_82&&_82.isTreeNode){
this.focusNode(_82);
}
},_onRightArrow:function(_86){
var _87=_86.node;
if(_87.isExpandable&&!_87.isExpanded){
this._expandNode(_87);
}else{
if(_87.hasChildren()){
_87=_87.getChildren()[0];
if(_87&&_87.isTreeNode){
this.focusNode(_87);
}
}
}
},_onLeftArrow:function(_88){
var _89=_88.node;
if(_89.isExpandable&&_89.isExpanded){
this._collapseNode(_89);
}else{
var _8a=_89.getParent();
if(_8a&&_8a.isTreeNode&&!(!this.showRoot&&_8a===this.rootNode)){
this.focusNode(_8a);
}
}
},_onHomeKey:function(){
var _8b=this._getRootOrFirstNode();
if(_8b){
this.focusNode(_8b);
}
},_onEndKey:function(){
var _8c=this.rootNode;
while(_8c.isExpanded){
var c=_8c.getChildren();
_8c=c[c.length-1];
}
if(_8c&&_8c.isTreeNode){
this.focusNode(_8c);
}
},multiCharSearchDuration:250,_onLetterKeyNav:function(_8d){
var cs=this._curSearch;
if(cs){
cs.pattern=cs.pattern+_8d.key;
cs.timer.remove();
}else{
cs=this._curSearch={pattern:_8d.key,startNode:_8d.node};
}
cs.timer=this.defer(function(){
delete this._curSearch;
},this.multiCharSearchDuration);
var _8e=cs.startNode;
do{
_8e=this._getNextNode(_8e);
if(!_8e){
_8e=this._getRootOrFirstNode();
}
}while(_8e!==cs.startNode&&(_8e.label.toLowerCase().substr(0,cs.pattern.length)!=cs.pattern));
if(_8e&&_8e.isTreeNode){
if(_8e!==cs.startNode){
this.focusNode(_8e);
}
}
},isExpandoNode:function(_8f,_90){
return _7.isDescendant(_8f,_90.expandoNode)||_7.isDescendant(_8f,_90.expandoNodeText);
},_onClick:function(_91,e){
var _92=e.target,_93=this.isExpandoNode(_92,_91);
if((this.openOnClick&&_91.isExpandable)||_93){
if(_91.isExpandable){
this._onExpandoClick({node:_91});
}
}else{
this._publish("execute",{item:_91.item,node:_91,evt:e});
this.onClick(_91.item,_91,e);
this.focusNode(_91);
}
_b.stop(e);
},_onDblClick:function(_94,e){
var _95=e.target,_96=(_95==_94.expandoNode||_95==_94.expandoNodeText);
if((this.openOnDblClick&&_94.isExpandable)||_96){
if(_94.isExpandable){
this._onExpandoClick({node:_94});
}
}else{
this._publish("execute",{item:_94.item,node:_94,evt:e});
this.onDblClick(_94.item,_94,e);
this.focusNode(_94);
}
_b.stop(e);
},_onExpandoClick:function(_97){
var _98=_97.node;
this.focusNode(_98);
if(_98.isExpanded){
this._collapseNode(_98);
}else{
this._expandNode(_98);
}
},onClick:function(){
},onDblClick:function(){
},onOpen:function(){
},onClose:function(){
},_getNextNode:function(_99){
if(_99.isExpandable&&_99.isExpanded&&_99.hasChildren()){
return _99.getChildren()[0];
}else{
while(_99&&_99.isTreeNode){
var _9a=_99.getNextSibling();
if(_9a){
return _9a;
}
_99=_99.getParent();
}
return null;
}
},_getRootOrFirstNode:function(){
return this.showRoot?this.rootNode:this.rootNode.getChildren()[0];
},_collapseNode:function(_9b){
if(_9b._expandNodeDeferred){
delete _9b._expandNodeDeferred;
}
if(_9b.state=="LOADING"){
return;
}
if(_9b.isExpanded){
var ret=_9b.collapse();
this.onClose(_9b.item,_9b);
this._state(_9b,false);
this._startPaint(ret);
return ret;
}
},_expandNode:function(_9c){
var def=new _5();
if(_9c._expandNodeDeferred){
return _9c._expandNodeDeferred;
}
var _9d=this.model,_9e=_9c.item,_9f=this;
if(!_9c._loadDeferred){
_9c.markProcessing();
_9c._loadDeferred=new _5();
_9d.getChildren(_9e,function(_a0){
_9c.unmarkProcessing();
_9c.setChildItems(_a0).then(function(){
_9c._loadDeferred.resolve(_a0);
});
},function(err){
console.error(_9f,": error loading "+_9c.label+" children: ",err);
_9c._loadDeferred.reject(err);
});
}
_9c._loadDeferred.then(_10.hitch(this,function(){
_9c.expand().then(function(){
def.resolve(true);
});
this.onOpen(_9c.item,_9c);
this._state(_9c,true);
}));
this._startPaint(def);
return def;
},focusNode:function(_a1){
_14.focus(_a1.labelNode);
},_onNodeFocus:function(_a2){
if(_a2&&_a2!=this.lastFocused){
if(this.lastFocused&&!this.lastFocused._destroyed){
this.lastFocused.setFocusable(false);
}
_a2.setFocusable(true);
this.lastFocused=_a2;
}
},_onNodeMouseEnter:function(){
},_onNodeMouseLeave:function(){
},_onItemChange:function(_a3){
var _a4=this.model,_a5=_a4.getIdentity(_a3),_a6=this._itemNodesMap[_a5];
if(_a6){
var _a7=this.getLabel(_a3),_a8=this.getTooltip(_a3);
_1.forEach(_a6,function(_a9){
_a9.set({item:_a3,label:_a7,tooltip:_a8});
_a9._updateItemClasses(_a3);
});
}
},_onItemChildrenChange:function(_aa,_ab){
var _ac=this.model,_ad=_ac.getIdentity(_aa),_ae=this._itemNodesMap[_ad];
if(_ae){
_1.forEach(_ae,function(_af){
_af.setChildItems(_ab);
});
}
},_onItemDelete:function(_b0){
var _b1=this.model,_b2=_b1.getIdentity(_b0),_b3=this._itemNodesMap[_b2];
if(_b3){
_1.forEach(_b3,function(_b4){
this.dndController.removeTreeNode(_b4);
var _b5=_b4.getParent();
if(_b5){
_b5.removeChild(_b4);
}
_b4.destroyRecursive();
},this);
delete this._itemNodesMap[_b2];
}
},_initState:function(){
this._openedNodes={};
if(this.persist&&this.cookieName){
var _b6=_3(this.cookieName);
if(_b6){
_1.forEach(_b6.split(","),function(_b7){
this._openedNodes[_b7]=true;
},this);
}
}
},_state:function(_b8,_b9){
if(!this.persist){
return false;
}
var _ba=_1.map(_b8.getTreePath(),function(_bb){
return this.model.getIdentity(_bb);
},this).join("/");
if(arguments.length===1){
return this._openedNodes[_ba];
}else{
if(_b9){
this._openedNodes[_ba]=true;
}else{
delete this._openedNodes[_ba];
}
if(this.persist&&this.cookieName){
var ary=[];
for(var id in this._openedNodes){
ary.push(id);
}
_3(this.cookieName,ary.join(","),{expires:365});
}
}
},destroy:function(){
if(this._curSearch){
this._curSearch.timer.remove();
delete this._curSearch;
}
if(this.rootNode){
this.rootNode.destroyRecursive();
}
if(this.dndController&&!_10.isString(this.dndController)){
this.dndController.destroy();
}
this.rootNode=null;
this.inherited(arguments);
},destroyRecursive:function(){
this.destroy();
},resize:function(_bc){
if(_bc){
_9.setMarginBox(this.domNode,_bc);
}
this._nodePixelIndent=_9.position(this.tree.indentDetector).w||this._nodePixelIndent;
this.expandChildrenDeferred.then(_10.hitch(this,function(){
this.rootNode.set("indent",this.showRoot?0:-1);
this._adjustWidths();
}));
},_outstandingPaintOperations:0,_startPaint:function(p){
this._outstandingPaintOperations++;
if(this._adjustWidthsTimer){
this._adjustWidthsTimer.remove();
delete this._adjustWidthsTimer;
}
var oc=_10.hitch(this,function(){
this._outstandingPaintOperations--;
if(this._outstandingPaintOperations<=0&&!this._adjustWidthsTimer&&this._started){
this._adjustWidthsTimer=this.defer("_adjustWidths");
}
});
_13(p,oc,oc);
},_adjustWidths:function(){
if(this._adjustWidthsTimer){
this._adjustWidthsTimer.remove();
delete this._adjustWidthsTimer;
}
var _bd=0,_be=[];
function _bf(_c0){
var _c1=_c0.rowNode;
_c1.style.width="auto";
_bd=Math.max(_bd,_c1.clientWidth);
_be.push(_c1);
if(_c0.isExpanded){
_1.forEach(_c0.getChildren(),_bf);
}
};
_bf(this.rootNode);
_bd=Math.max(_bd,_9.getContentBox(this.domNode).w);
_1.forEach(_be,function(_c2){
_c2.style.width=_bd+"px";
});
},_createTreeNode:function(_c3){
return new _23(_c3);
},_setTextDirAttr:function(_c4){
if(_c4&&this.textDir!=_c4){
this._set("textDir",_c4);
this.rootNode.set("textDir",_c4);
}
}});
_4b.PathError=_c("TreePathError");
_4b._TreeNode=_23;
return _4b;
});

View File

@ -0,0 +1,25 @@
//>>built
define("dijit/Viewport",["dojo/Evented","dojo/on","dojo/ready","dojo/sniff","dojo/_base/window","dojo/window"],function(_1,on,_2,_3,_4,_5){
var _6=new _1();
_2(200,function(){
var _7=_5.getBox();
_6._rlh=on(_4.global,"resize",function(){
var _8=_5.getBox();
if(_7.h==_8.h&&_7.w==_8.w){
return;
}
_7=_8;
_6.emit("resize");
});
if(_3("ie")==8){
var _9=screen.deviceXDPI;
setInterval(function(){
if(screen.deviceXDPI!=_9){
_9=screen.deviceXDPI;
_6.emit("resize");
}
},500);
}
});
return _6;
});

View File

@ -0,0 +1,50 @@
define("dijit/Viewport", [
"dojo/Evented",
"dojo/on",
"dojo/ready",
"dojo/sniff",
"dojo/_base/window", // global
"dojo/window" // getBox()
], function(Evented, on, ready, has, win, winUtils){
// module:
// dijit/Viewport
/*=====
return {
// summary:
// Utility singleton to watch for viewport resizes, avoiding duplicate notifications
// which can lead to infinite loops.
// description:
// Usage: Viewport.on("resize", myCallback).
//
// myCallback() is called without arguments in case it's _WidgetBase.resize(),
// which would interpret the argument as the size to make the widget.
};
=====*/
var Viewport = new Evented();
ready(200, function(){
var oldBox = winUtils.getBox();
Viewport._rlh = on(win.global, "resize", function(){
var newBox = winUtils.getBox();
if(oldBox.h == newBox.h && oldBox.w == newBox.w){ return; }
oldBox = newBox;
Viewport.emit("resize");
});
// Also catch zoom changes on IE8, since they don't naturally generate resize events
if(has("ie") == 8){
var deviceXDPI = screen.deviceXDPI;
setInterval(function(){
if(screen.deviceXDPI != deviceXDPI){
deviceXDPI = screen.deviceXDPI;
Viewport.emit("resize");
}
}, 500);
}
});
return Viewport;
});

View File

@ -0,0 +1,76 @@
//>>built
define("dijit/WidgetSet",["dojo/_base/array","dojo/_base/declare","dojo/_base/kernel","./registry"],function(_1,_2,_3,_4){
var _5=_2("dijit.WidgetSet",null,{constructor:function(){
this._hash={};
this.length=0;
},add:function(_6){
if(this._hash[_6.id]){
throw new Error("Tried to register widget with id=="+_6.id+" but that id is already registered");
}
this._hash[_6.id]=_6;
this.length++;
},remove:function(id){
if(this._hash[id]){
delete this._hash[id];
this.length--;
}
},forEach:function(_7,_8){
_8=_8||_3.global;
var i=0,id;
for(id in this._hash){
_7.call(_8,this._hash[id],i++,this._hash);
}
return this;
},filter:function(_9,_a){
_a=_a||_3.global;
var _b=new _5(),i=0,id;
for(id in this._hash){
var w=this._hash[id];
if(_9.call(_a,w,i++,this._hash)){
_b.add(w);
}
}
return _b;
},byId:function(id){
return this._hash[id];
},byClass:function(_c){
var _d=new _5(),id,_e;
for(id in this._hash){
_e=this._hash[id];
if(_e.declaredClass==_c){
_d.add(_e);
}
}
return _d;
},toArray:function(){
var ar=[];
for(var id in this._hash){
ar.push(this._hash[id]);
}
return ar;
},map:function(_f,_10){
return _1.map(this.toArray(),_f,_10);
},every:function(_11,_12){
_12=_12||_3.global;
var x=0,i;
for(i in this._hash){
if(!_11.call(_12,this._hash[i],x++,this._hash)){
return false;
}
}
return true;
},some:function(_13,_14){
_14=_14||_3.global;
var x=0,i;
for(i in this._hash){
if(_13.call(_14,this._hash[i],x++,this._hash)){
return true;
}
}
return false;
}});
_1.forEach(["forEach","filter","byClass","map","every","some"],function(_15){
_4[_15]=_5.prototype[_15];
});
return _5;
});

View File

@ -0,0 +1,247 @@
define("dijit/WidgetSet", [
"dojo/_base/array", // array.forEach array.map
"dojo/_base/declare", // declare
"dojo/_base/kernel", // kernel.global
"./registry" // to add functions to dijit.registry
], function(array, declare, kernel, registry){
// module:
// dijit/WidgetSet
var WidgetSet = declare("dijit.WidgetSet", null, {
// summary:
// A set of widgets indexed by id.
// Deprecated, will be removed in 2.0.
//
// example:
// Create a small list of widgets:
// | require(["dijit/WidgetSet", "dijit/registry"],
// | function(WidgetSet, registry){
// | var ws = new WidgetSet();
// | ws.add(registry.byId("one"));
// | ws.add(registry.byId("two"));
// | // destroy both:
// | ws.forEach(function(w){ w.destroy(); });
// | });
constructor: function(){
this._hash = {};
this.length = 0;
},
add: function(/*dijit/_WidgetBase*/ widget){
// summary:
// Add a widget to this list. If a duplicate ID is detected, a error is thrown.
//
// widget: dijit/_WidgetBase
// Any dijit/_WidgetBase subclass.
if(this._hash[widget.id]){
throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
}
this._hash[widget.id] = widget;
this.length++;
},
remove: function(/*String*/ id){
// summary:
// Remove a widget from this WidgetSet. Does not destroy the widget; simply
// removes the reference.
if(this._hash[id]){
delete this._hash[id];
this.length--;
}
},
forEach: function(/*Function*/ func, /* Object? */thisObj){
// summary:
// Call specified function for each widget in this set.
//
// func:
// A callback function to run for each item. Is passed the widget, the index
// in the iteration, and the full hash, similar to `array.forEach`.
//
// thisObj:
// An optional scope parameter
//
// example:
// Using the default `dijit.registry` instance:
// | require(["dijit/WidgetSet", "dijit/registry"],
// | function(WidgetSet, registry){
// | registry.forEach(function(widget){
// | console.log(widget.declaredClass);
// | });
// | });
//
// returns:
// Returns self, in order to allow for further chaining.
thisObj = thisObj || kernel.global;
var i = 0, id;
for(id in this._hash){
func.call(thisObj, this._hash[id], i++, this._hash);
}
return this; // dijit/WidgetSet
},
filter: function(/*Function*/ filter, /* Object? */thisObj){
// summary:
// Filter down this WidgetSet to a smaller new WidgetSet
// Works the same as `array.filter` and `NodeList.filter`
//
// filter:
// Callback function to test truthiness. Is passed the widget
// reference and the pseudo-index in the object.
//
// thisObj: Object?
// Option scope to use for the filter function.
//
// example:
// Arbitrary: select the odd widgets in this list
// |
// |
// |
// | require(["dijit/WidgetSet", "dijit/registry"],
// | function(WidgetSet, registry){
// | registry.filter(function(w, i){
// | return i % 2 == 0;
// | }).forEach(function(w){ /* odd ones */ });
// | });
thisObj = thisObj || kernel.global;
var res = new WidgetSet(), i = 0, id;
for(id in this._hash){
var w = this._hash[id];
if(filter.call(thisObj, w, i++, this._hash)){
res.add(w);
}
}
return res; // dijit/WidgetSet
},
byId: function(/*String*/ id){
// summary:
// Find a widget in this list by it's id.
// example:
// Test if an id is in a particular WidgetSet
// | require(["dijit/WidgetSet", "dijit/registry"],
// | function(WidgetSet, registry){
// | var ws = new WidgetSet();
// | ws.add(registry.byId("bar"));
// | var t = ws.byId("bar") // returns a widget
// | var x = ws.byId("foo"); // returns undefined
// | });
return this._hash[id]; // dijit/_WidgetBase
},
byClass: function(/*String*/ cls){
// summary:
// Reduce this widgetset to a new WidgetSet of a particular `declaredClass`
//
// cls: String
// The Class to scan for. Full dot-notated string.
//
// example:
// Find all `dijit.TitlePane`s in a page:
// | require(["dijit/WidgetSet", "dijit/registry"],
// | function(WidgetSet, registry){
// | registry.byClass("dijit.TitlePane").forEach(function(tp){ tp.close(); });
// | });
var res = new WidgetSet(), id, widget;
for(id in this._hash){
widget = this._hash[id];
if(widget.declaredClass == cls){
res.add(widget);
}
}
return res; // dijit/WidgetSet
},
toArray: function(){
// summary:
// Convert this WidgetSet into a true Array
//
// example:
// Work with the widget .domNodes in a real Array
// | require(["dijit/WidgetSet", "dijit/registry"],
// | function(WidgetSet, registry){
// | array.map(registry.toArray(), function(w){ return w.domNode; });
// | });
var ar = [];
for(var id in this._hash){
ar.push(this._hash[id]);
}
return ar; // dijit/_WidgetBase[]
},
map: function(/* Function */func, /* Object? */thisObj){
// summary:
// Create a new Array from this WidgetSet, following the same rules as `array.map`
// example:
// | require(["dijit/WidgetSet", "dijit/registry"],
// | function(WidgetSet, registry){
// | var nodes = registry.map(function(w){ return w.domNode; });
// | });
//
// returns:
// A new array of the returned values.
return array.map(this.toArray(), func, thisObj); // Array
},
every: function(func, thisObj){
// summary:
// A synthetic clone of `array.every` acting explicitly on this WidgetSet
//
// func: Function
// A callback function run for every widget in this list. Exits loop
// when the first false return is encountered.
//
// thisObj: Object?
// Optional scope parameter to use for the callback
thisObj = thisObj || kernel.global;
var x = 0, i;
for(i in this._hash){
if(!func.call(thisObj, this._hash[i], x++, this._hash)){
return false; // Boolean
}
}
return true; // Boolean
},
some: function(func, thisObj){
// summary:
// A synthetic clone of `array.some` acting explicitly on this WidgetSet
//
// func: Function
// A callback function run for every widget in this list. Exits loop
// when the first true return is encountered.
//
// thisObj: Object?
// Optional scope parameter to use for the callback
thisObj = thisObj || kernel.global;
var x = 0, i;
for(i in this._hash){
if(func.call(thisObj, this._hash[i], x++, this._hash)){
return true; // Boolean
}
}
return false; // Boolean
}
});
// Add in 1.x compatibility methods to dijit/registry.
// These functions won't show up in the API doc but since they are deprecated anyway,
// that's probably for the best.
array.forEach(["forEach", "filter", "byClass", "map", "every", "some"], function(func){
registry[func] = WidgetSet.prototype[func];
});
return WidgetSet;
});

View File

@ -0,0 +1,29 @@
//>>built
define("dijit/_BidiSupport",["./_WidgetBase"],function(_1){
_1.extend({getTextDir:function(_2){
return this.textDir=="auto"?this._checkContextual(_2):this.textDir;
},_checkContextual:function(_3){
var _4=/[A-Za-z\u05d0-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(_3);
return _4?(_4[0]<="z"?"ltr":"rtl"):this.dir?this.dir:this.isLeftToRight()?"ltr":"rtl";
},applyTextDir:function(_5,_6){
var _7=this.textDir=="auto"?this._checkContextual(_6):this.textDir;
if(_5.dir!=_7){
_5.dir=_7;
}
},enforceTextDirWithUcc:function(_8,_9){
if(this.textDir){
_8.originalText=_9;
var _a=this.textDir=="auto"?this._checkContextual(_9):this.textDir;
return (_a=="ltr"?_b.LRE:_b.RLE)+_9+_b.PDF;
}
return _9;
},restoreOriginalText:function(_c){
if(_c.originalText){
_c.text=_c.originalText;
delete _c.originalText;
}
return _c;
}});
var _b={LRM:"",LRE:"",PDF:"",RLM:"",RLE:""};
return _1;
});

View File

@ -0,0 +1,113 @@
define("dijit/_BidiSupport", ["./_WidgetBase"], function(_WidgetBase){
// module:
// dijit/_BidiSupport
/*=====
return function(){
// summary:
// Module that deals with BIDI, special with the auto
// direction if needed without changing the GUI direction.
// Including this module will extend _WidgetBase with BIDI related methods.
// description:
// There's a special need for displaying BIDI text in rtl direction
// in ltr GUI, sometimes needed auto support.
// In creation of widget, if it's want to activate this class,
// the widget should define the "textDir".
};
=====*/
_WidgetBase.extend({
getTextDir: function(/*String*/ text){
// summary:
// Gets the right direction of text.
// description:
// If textDir is ltr or rtl returns the value.
// If it's auto, calls to another function that responsible
// for checking the value, and defining the direction.
// tags:
// protected.
return this.textDir == "auto" ? this._checkContextual(text) : this.textDir;
},
_checkContextual: function(text){
// summary:
// Finds the first strong (directional) character, return ltr if isLatin
// or rtl if isBidiChar.
// tags:
// private.
// look for strong (directional) characters
var fdc = /[A-Za-z\u05d0-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(text);
// if found return the direction that defined by the character, else return widgets dir as defult.
return fdc ? ( fdc[0] <= 'z' ? "ltr" : "rtl" ) : this.dir ? this.dir : this.isLeftToRight() ? "ltr" : "rtl";
},
applyTextDir: function(/*Object*/ element, /*String*/ text){
// summary:
// Set element.dir according to this.textDir
// element:
// The text element to be set. Should have dir property.
// text:
// Used in case this.textDir is "auto", for calculating the right transformation
// description:
// If textDir is ltr or rtl returns the value.
// If it's auto, calls to another function that responsible
// for checking the value, and defining the direction.
// tags:
// protected.
var textDir = this.textDir == "auto" ? this._checkContextual(text) : this.textDir;
// update only when there's a difference
if(element.dir != textDir){
element.dir = textDir;
}
},
enforceTextDirWithUcc: function(option, text){
// summary:
// Wraps by UCC (Unicode control characters) option's text according to this.textDir
// option:
// The element (`<option>`) we wrapping the text for.
// text:
// The text to be wrapped.
// description:
// There's a dir problem with some HTML elements. For some elements (e.g. `<option>`, `<select>`)
// defining the dir in different direction then the GUI orientation, won't display correctly.
// FF 3.6 will change the alignment of the text in option - this doesn't follow the bidi standards (static text
// should be aligned following GUI direction). IE8 and Opera11.10 completely ignore dir setting for `<option>`.
// Therefore the only solution is to use UCC (Unicode control characters) to display the text in correct orientation.
// This function saves the original text value for later restoration if needed, for example if the textDir will change etc.
if(this.textDir){
option.originalText = text;
var dir = this.textDir == "auto" ? this._checkContextual(text) : this.textDir;
return (dir == "ltr" ? bidi_const.LRE : bidi_const.RLE ) + text + bidi_const.PDF;
}
return text;
},
restoreOriginalText: function(origObj){
// summary:
// Restores the text of origObj, if needed, after enforceTextDirWithUcc, e.g. set("textDir", textDir).
// origObj:
// The element (`<option>`) to restore.
// description:
// Sets the text of origObj to origObj.originalText, which is the original text, without the UCCs.
// The function than removes the originalText from origObj!
if(origObj.originalText){
origObj.text = origObj.originalText;
delete origObj.originalText;
}
return origObj;
}
});
// UCC - constants that will be used by bidi support.
var bidi_const = {
LRM : '\u200E',
LRE : '\u202A',
PDF : '\u202C',
RLM : '\u200f',
RLE : '\u202B'
};
return _WidgetBase;
});

View File

@ -0,0 +1,5 @@
//>>built
define("dijit/_Calendar",["dojo/_base/kernel","./Calendar","./main"],function(_1,_2,_3){
_1.deprecated("dijit._Calendar is deprecated","dijit._Calendar moved to dijit.Calendar",2);
_3._Calendar=_2;
});

View File

@ -0,0 +1,22 @@
define("dijit/_Calendar", [
"dojo/_base/kernel", // kernel.deprecated
"./Calendar",
"./main" // for exporting dijit.Calendar
], function(kernel, Calendar, dijit){
// module:
// dijit/_Calendar
/*=====
return {
// summary:
// Deprecated widget, used dijit/Calendar instead. Will be removed in 2.0.
};
=====*/
kernel.deprecated("dijit._Calendar is deprecated", "dijit._Calendar moved to dijit.Calendar", 2.0);
// dijit._Calendar had an underscore all this time merely because it did
// not satisfy dijit's a11y policy.
dijit._Calendar = Calendar;
});

View File

@ -0,0 +1,20 @@
//>>built
define("dijit/_Contained",["dojo/_base/declare","./registry"],function(_1,_2){
return _1("dijit._Contained",null,{_getSibling:function(_3){
var _4=this.domNode;
do{
_4=_4[_3+"Sibling"];
}while(_4&&_4.nodeType!=1);
return _4&&_2.byNode(_4);
},getPreviousSibling:function(){
return this._getSibling("previous");
},getNextSibling:function(){
return this._getSibling("next");
},getIndexInParent:function(){
var p=this.getParent();
if(!p||!p.getIndexOfChild){
return -1;
}
return p.getIndexOfChild(this);
}});
});

View File

@ -0,0 +1,60 @@
define("dijit/_Contained", [
"dojo/_base/declare", // declare
"./registry" // registry.getEnclosingWidget(), registry.byNode()
], function(declare, registry){
// module:
// dijit/_Contained
return declare("dijit._Contained", null, {
// summary:
// Mixin for widgets that are children of a container widget
//
// example:
// | // make a basic custom widget that knows about it's parents
// | declare("my.customClass",[dijit._Widget,dijit._Contained],{});
_getSibling: function(/*String*/ which){
// summary:
// Returns next or previous sibling
// which:
// Either "next" or "previous"
// tags:
// private
var node = this.domNode;
do{
node = node[which+"Sibling"];
}while(node && node.nodeType != 1);
return node && registry.byNode(node); // dijit/_WidgetBase
},
getPreviousSibling: function(){
// summary:
// Returns null if this is the first child of the parent,
// otherwise returns the next element sibling to the "left".
return this._getSibling("previous"); // dijit/_WidgetBase
},
getNextSibling: function(){
// summary:
// Returns null if this is the last child of the parent,
// otherwise returns the next element sibling to the "right".
return this._getSibling("next"); // dijit/_WidgetBase
},
getIndexInParent: function(){
// summary:
// Returns the index of this widget within its container parent.
// It returns -1 if the parent does not exist, or if the parent
// is not a dijit._Container
var p = this.getParent();
if(!p || !p.getIndexOfChild){
return -1; // int
}
return p.getIndexOfChild(this); // int
}
});
});

View File

@ -0,0 +1,39 @@
//>>built
define("dijit/_Container",["dojo/_base/array","dojo/_base/declare","dojo/dom-construct"],function(_1,_2,_3){
return _2("dijit._Container",null,{buildRendering:function(){
this.inherited(arguments);
if(!this.containerNode){
this.containerNode=this.domNode;
}
},addChild:function(_4,_5){
var _6=this.containerNode;
if(_5&&typeof _5=="number"){
var _7=this.getChildren();
if(_7&&_7.length>=_5){
_6=_7[_5-1].domNode;
_5="after";
}
}
_3.place(_4.domNode,_6,_5);
if(this._started&&!_4._started){
_4.startup();
}
},removeChild:function(_8){
if(typeof _8=="number"){
_8=this.getChildren()[_8];
}
if(_8){
var _9=_8.domNode;
if(_9&&_9.parentNode){
_9.parentNode.removeChild(_9);
}
}
},hasChildren:function(){
return this.getChildren().length>0;
},_getSiblingOfChild:function(_a,_b){
var _c=this.getChildren(),_d=_1.indexOf(this.getChildren(),_a);
return _c[_d+_b];
},getIndexOfChild:function(_e){
return _1.indexOf(this.getChildren(),_e);
}});
});

View File

@ -0,0 +1,94 @@
define("dijit/_Container", [
"dojo/_base/array", // array.forEach array.indexOf
"dojo/_base/declare", // declare
"dojo/dom-construct" // domConstruct.place
], function(array, declare, domConstruct){
// module:
// dijit/_Container
return declare("dijit._Container", null, {
// summary:
// Mixin for widgets that contain HTML and/or a set of widget children.
buildRendering: function(){
this.inherited(arguments);
if(!this.containerNode){
// all widgets with descendants must set containerNode
this.containerNode = this.domNode;
}
},
addChild: function(/*dijit/_WidgetBase*/ widget, /*int?*/ insertIndex){
// summary:
// Makes the given widget a child of this widget.
// description:
// Inserts specified child widget's dom node as a child of this widget's
// container node, and possibly does other processing (such as layout).
//
// Functionality is undefined if this widget contains anything besides
// a list of child widgets (ie, if it contains arbitrary non-widget HTML).
var refNode = this.containerNode;
if(insertIndex && typeof insertIndex == "number"){
var children = this.getChildren();
if(children && children.length >= insertIndex){
refNode = children[insertIndex-1].domNode;
insertIndex = "after";
}
}
domConstruct.place(widget.domNode, refNode, insertIndex);
// If I've been started but the child widget hasn't been started,
// start it now. Make sure to do this after widget has been
// inserted into the DOM tree, so it can see that it's being controlled by me,
// so it doesn't try to size itself.
if(this._started && !widget._started){
widget.startup();
}
},
removeChild: function(/*Widget|int*/ widget){
// summary:
// Removes the passed widget instance from this widget but does
// not destroy it. You can also pass in an integer indicating
// the index within the container to remove (ie, removeChild(5) removes the sixth widget).
if(typeof widget == "number"){
widget = this.getChildren()[widget];
}
if(widget){
var node = widget.domNode;
if(node && node.parentNode){
node.parentNode.removeChild(node); // detach but don't destroy
}
}
},
hasChildren: function(){
// summary:
// Returns true if widget has child widgets, i.e. if this.containerNode contains widgets.
return this.getChildren().length > 0; // Boolean
},
_getSiblingOfChild: function(/*dijit/_WidgetBase*/ child, /*int*/ dir){
// summary:
// Get the next or previous widget sibling of child
// dir:
// if 1, get the next sibling
// if -1, get the previous sibling
// tags:
// private
var children = this.getChildren(),
idx = array.indexOf(this.getChildren(), child); // int
return children[idx + dir];
},
getIndexOfChild: function(/*dijit/_WidgetBase*/ child){
// summary:
// Gets the index of the child in this container or -1 if not found
return array.indexOf(this.getChildren(), child); // int
}
});
});

View File

@ -0,0 +1,172 @@
//>>built
define("dijit/_CssStateMixin",["dojo/_base/array","dojo/_base/declare","dojo/dom","dojo/dom-class","dojo/has","dojo/_base/lang","dojo/on","dojo/ready","dojo/_base/window","./registry"],function(_1,_2,_3,_4,_5,_6,on,_7,_8,_9){
var _a=_2("dijit._CssStateMixin",[],{cssStateNodes:{},hovering:false,active:false,_applyAttributes:function(){
this.inherited(arguments);
_1.forEach(["disabled","readOnly","checked","selected","focused","state","hovering","active","_opened"],function(_b){
this.watch(_b,_6.hitch(this,"_setStateClass"));
},this);
for(var ap in this.cssStateNodes){
this._trackMouseState(this[ap],this.cssStateNodes[ap]);
}
this._trackMouseState(this.domNode,this.baseClass);
this._setStateClass();
},_cssMouseEvent:function(_c){
if(!this.disabled){
switch(_c.type){
case "mouseover":
this._set("hovering",true);
this._set("active",this._mouseDown);
break;
case "mouseout":
this._set("hovering",false);
this._set("active",false);
break;
case "mousedown":
case "touchstart":
this._set("active",true);
break;
case "mouseup":
case "touchend":
this._set("active",false);
break;
}
}
},_setStateClass:function(){
var _d=this.baseClass.split(" ");
function _e(_f){
_d=_d.concat(_1.map(_d,function(c){
return c+_f;
}),"dijit"+_f);
};
if(!this.isLeftToRight()){
_e("Rtl");
}
var _10=this.checked=="mixed"?"Mixed":(this.checked?"Checked":"");
if(this.checked){
_e(_10);
}
if(this.state){
_e(this.state);
}
if(this.selected){
_e("Selected");
}
if(this._opened){
_e("Opened");
}
if(this.disabled){
_e("Disabled");
}else{
if(this.readOnly){
_e("ReadOnly");
}else{
if(this.active){
_e("Active");
}else{
if(this.hovering){
_e("Hover");
}
}
}
}
if(this.focused){
_e("Focused");
}
var tn=this.stateNode||this.domNode,_11={};
_1.forEach(tn.className.split(" "),function(c){
_11[c]=true;
});
if("_stateClasses" in this){
_1.forEach(this._stateClasses,function(c){
delete _11[c];
});
}
_1.forEach(_d,function(c){
_11[c]=true;
});
var _12=[];
for(var c in _11){
_12.push(c);
}
tn.className=_12.join(" ");
this._stateClasses=_d;
},_subnodeCssMouseEvent:function(_13,_14,evt){
if(this.disabled||this.readOnly){
return;
}
function _15(_16){
_4.toggle(_13,_14+"Hover",_16);
};
function _17(_18){
_4.toggle(_13,_14+"Active",_18);
};
function _19(_1a){
_4.toggle(_13,_14+"Focused",_1a);
};
switch(evt.type){
case "mouseover":
_15(true);
break;
case "mouseout":
_15(false);
_17(false);
break;
case "mousedown":
case "touchstart":
_17(true);
break;
case "mouseup":
case "touchend":
_17(false);
break;
case "focus":
case "focusin":
_19(true);
break;
case "blur":
case "focusout":
_19(false);
break;
}
},_trackMouseState:function(_1b,_1c){
_1b._cssState=_1c;
}});
_7(function(){
function _1d(evt){
if(!_3.isDescendant(evt.relatedTarget,evt.target)){
for(var _1e=evt.target;_1e&&_1e!=evt.relatedTarget;_1e=_1e.parentNode){
if(_1e._cssState){
var _1f=_9.getEnclosingWidget(_1e);
if(_1f){
if(_1e==_1f.domNode){
_1f._cssMouseEvent(evt);
}else{
_1f._subnodeCssMouseEvent(_1e,_1e._cssState,evt);
}
}
}
}
}
};
function _20(evt){
evt.target=evt.srcElement;
_1d(evt);
};
var _21=_8.body(),_22=(_5("touch")?[]:["mouseover","mouseout"]).concat(["mousedown","touchstart","mouseup","touchend"]);
_1.forEach(_22,function(_23){
if(_21.addEventListener){
_21.addEventListener(_23,_1d,true);
}else{
_21.attachEvent("on"+_23,_20);
}
});
on(_21,"focusin, focusout",function(evt){
var _24=evt.target;
if(_24._cssState&&!_24.getAttribute("widgetId")){
var _25=_9.getEnclosingWidget(_24);
_25._subnodeCssMouseEvent(_24,_24._cssState,evt);
}
});
});
return _a;
});

View File

@ -0,0 +1,324 @@
define("dijit/_CssStateMixin", [
"dojo/_base/array", // array.forEach array.map
"dojo/_base/declare", // declare
"dojo/dom", // dom.isDescendant()
"dojo/dom-class", // domClass.toggle
"dojo/has",
"dojo/_base/lang", // lang.hitch
"dojo/on",
"dojo/ready",
"dojo/_base/window", // win.body
"./registry"
], function(array, declare, dom, domClass, has, lang, on, ready, win, registry){
// module:
// dijit/_CssStateMixin
var CssStateMixin = declare("dijit._CssStateMixin", [], {
// summary:
// Mixin for widgets to set CSS classes on the widget DOM nodes depending on hover/mouse press/focus
// state changes, and also higher-level state changes such becoming disabled or selected.
//
// description:
// By mixing this class into your widget, and setting the this.baseClass attribute, it will automatically
// maintain CSS classes on the widget root node (this.domNode) depending on hover,
// active, focus, etc. state. Ex: with a baseClass of dijitButton, it will apply the classes
// dijitButtonHovered and dijitButtonActive, as the user moves the mouse over the widget and clicks it.
//
// It also sets CSS like dijitButtonDisabled based on widget semantic state.
//
// By setting the cssStateNodes attribute, a widget can also track events on subnodes (like buttons
// within the widget).
// cssStateNodes: [protected] Object
// List of sub-nodes within the widget that need CSS classes applied on mouse hover/press and focus
//
// Each entry in the hash is a an attachpoint names (like "upArrowButton") mapped to a CSS class names
// (like "dijitUpArrowButton"). Example:
// | {
// | "upArrowButton": "dijitUpArrowButton",
// | "downArrowButton": "dijitDownArrowButton"
// | }
// The above will set the CSS class dijitUpArrowButton to the this.upArrowButton DOMNode when it
// is hovered, etc.
cssStateNodes: {},
// hovering: [readonly] Boolean
// True if cursor is over this widget
hovering: false,
// active: [readonly] Boolean
// True if mouse was pressed while over this widget, and hasn't been released yet
active: false,
_applyAttributes: function(){
// This code would typically be in postCreate(), but putting in _applyAttributes() for
// performance: so the class changes happen before DOM is inserted into the document.
// Change back to postCreate() in 2.0. See #11635.
this.inherited(arguments);
// Monitoring changes to disabled, readonly, etc. state, and update CSS class of root node
array.forEach(["disabled", "readOnly", "checked", "selected", "focused", "state", "hovering", "active", "_opened"], function(attr){
this.watch(attr, lang.hitch(this, "_setStateClass"));
}, this);
// Track hover and active mouse events on widget root node, plus possibly on subnodes
for(var ap in this.cssStateNodes){
this._trackMouseState(this[ap], this.cssStateNodes[ap]);
}
this._trackMouseState(this.domNode, this.baseClass);
// Set state initially; there's probably no hover/active/focus state but widget might be
// disabled/readonly/checked/selected so we want to set CSS classes for those conditions.
this._setStateClass();
},
_cssMouseEvent: function(/*Event*/ event){
// summary:
// Handler for CSS event on this.domNode. Sets hovering and active properties depending on mouse state,
// which triggers _setStateClass() to set appropriate CSS classes for this.domNode.
if(!this.disabled){
switch(event.type){
case "mouseover":
this._set("hovering", true);
this._set("active", this._mouseDown);
break;
case "mouseout":
this._set("hovering", false);
this._set("active", false);
break;
case "mousedown":
case "touchstart":
this._set("active", true);
break;
case "mouseup":
case "touchend":
this._set("active", false);
break;
}
}
},
_setStateClass: function(){
// summary:
// Update the visual state of the widget by setting the css classes on this.domNode
// (or this.stateNode if defined) by combining this.baseClass with
// various suffixes that represent the current widget state(s).
//
// description:
// In the case where a widget has multiple
// states, it sets the class based on all possible
// combinations. For example, an invalid form widget that is being hovered
// will be "dijitInput dijitInputInvalid dijitInputHover dijitInputInvalidHover".
//
// The widget may have one or more of the following states, determined
// by this.state, this.checked, this.valid, and this.selected:
//
// - Error - ValidationTextBox sets this.state to "Error" if the current input value is invalid
// - Incomplete - ValidationTextBox sets this.state to "Incomplete" if the current input value is not finished yet
// - Checked - ex: a checkmark or a ToggleButton in a checked state, will have this.checked==true
// - Selected - ex: currently selected tab will have this.selected==true
//
// In addition, it may have one or more of the following states,
// based on this.disabled and flags set in _onMouse (this.active, this.hovering) and from focus manager (this.focused):
//
// - Disabled - if the widget is disabled
// - Active - if the mouse (or space/enter key?) is being pressed down
// - Focused - if the widget has focus
// - Hover - if the mouse is over the widget
// Compute new set of classes
var newStateClasses = this.baseClass.split(" ");
function multiply(modifier){
newStateClasses = newStateClasses.concat(array.map(newStateClasses, function(c){ return c+modifier; }), "dijit"+modifier);
}
if(!this.isLeftToRight()){
// For RTL mode we need to set an addition class like dijitTextBoxRtl.
multiply("Rtl");
}
var checkedState = this.checked == "mixed" ? "Mixed" : (this.checked ? "Checked" : "");
if(this.checked){
multiply(checkedState);
}
if(this.state){
multiply(this.state);
}
if(this.selected){
multiply("Selected");
}
if(this._opened){
multiply("Opened");
}
if(this.disabled){
multiply("Disabled");
}else if(this.readOnly){
multiply("ReadOnly");
}else{
if(this.active){
multiply("Active");
}else if(this.hovering){
multiply("Hover");
}
}
if(this.focused){
multiply("Focused");
}
// Remove old state classes and add new ones.
// For performance concerns we only write into domNode.className once.
var tn = this.stateNode || this.domNode,
classHash = {}; // set of all classes (state and otherwise) for node
array.forEach(tn.className.split(" "), function(c){ classHash[c] = true; });
if("_stateClasses" in this){
array.forEach(this._stateClasses, function(c){ delete classHash[c]; });
}
array.forEach(newStateClasses, function(c){ classHash[c] = true; });
var newClasses = [];
for(var c in classHash){
newClasses.push(c);
}
tn.className = newClasses.join(" ");
this._stateClasses = newStateClasses;
},
_subnodeCssMouseEvent: function(node, clazz, evt){
// summary:
// Handler for hover/active mouse event on widget's subnode
if(this.disabled || this.readOnly){
return;
}
function hover(isHovering){
domClass.toggle(node, clazz+"Hover", isHovering);
}
function active(isActive){
domClass.toggle(node, clazz+"Active", isActive);
}
function focused(isFocused){
domClass.toggle(node, clazz+"Focused", isFocused);
}
switch(evt.type){
case "mouseover":
hover(true);
break;
case "mouseout":
hover(false);
active(false);
break;
case "mousedown":
case "touchstart":
active(true);
break;
case "mouseup":
case "touchend":
active(false);
break;
case "focus":
case "focusin":
focused(true);
break;
case "blur":
case "focusout":
focused(false);
break;
}
},
_trackMouseState: function(/*DomNode*/ node, /*String*/ clazz){
// summary:
// Track mouse/focus events on specified node and set CSS class on that node to indicate
// current state. Usually not called directly, but via cssStateNodes attribute.
// description:
// Given class=foo, will set the following CSS class on the node
//
// - fooActive: if the user is currently pressing down the mouse button while over the node
// - fooHover: if the user is hovering the mouse over the node, but not pressing down a button
// - fooFocus: if the node is focused
//
// Note that it won't set any classes if the widget is disabled.
// node: DomNode
// Should be a sub-node of the widget, not the top node (this.domNode), since the top node
// is handled specially and automatically just by mixing in this class.
// clazz: String
// CSS class name (ex: dijitSliderUpArrow)
// Flag for listener code below to call this._cssMouseEvent() or this._subnodeCssMouseEvent()
// when node is hovered/active
node._cssState = clazz;
}
});
ready(function(){
// Document level listener to catch hover etc. events on widget root nodes and subnodes.
// Note that when the mouse is moved quickly, a single onmouseenter event could signal that multiple widgets
// have been hovered or unhovered (try test_Accordion.html)
function handler(evt){
// Poor man's event propagation. Don't propagate event to ancestors of evt.relatedTarget,
// to avoid processing mouseout events moving from a widget's domNode to a descendant node;
// such events shouldn't be interpreted as a mouseleave on the widget.
if(!dom.isDescendant(evt.relatedTarget, evt.target)){
for(var node = evt.target; node && node != evt.relatedTarget; node = node.parentNode){
// Process any nodes with _cssState property. They are generally widget root nodes,
// but could also be sub-nodes within a widget
if(node._cssState){
var widget = registry.getEnclosingWidget(node);
if(widget){
if(node == widget.domNode){
// event on the widget's root node
widget._cssMouseEvent(evt);
}else{
// event on widget's sub-node
widget._subnodeCssMouseEvent(node, node._cssState, evt);
}
}
}
}
}
}
function ieHandler(evt){
evt.target = evt.srcElement;
handler(evt);
}
// Use addEventListener() (and attachEvent() on IE) to catch the relevant events even if other handlers
// (on individual nodes) call evt.stopPropagation() or event.stopEvent().
// Currently typematic.js is doing that, not sure why.
// Don't monitor mouseover/mouseout on mobile because iOS generates "phantom" mouseover/mouseout events when
// drag-scrolling, at the point in the viewport where the drag originated. Test the Tree in api viewer.
var body = win.body(),
types = (has("touch") ? [] : ["mouseover", "mouseout"]).concat(["mousedown", "touchstart", "mouseup", "touchend"]);
array.forEach(types, function(type){
if(body.addEventListener){
body.addEventListener(type, handler, true); // W3C
}else{
body.attachEvent("on"+type, ieHandler); // IE
}
});
// Track focus events on widget sub-nodes that have been registered via _trackMouseState().
// However, don't track focus events on the widget root nodes, because focus is tracked via the
// focus manager (and it's not really tracking focus, but rather tracking that focus is on one of the widget's
// nodes or a subwidget's node or a popup node, etc.)
// Remove for 2.0 (if focus CSS needed, just use :focus pseudo-selector).
on(body, "focusin, focusout", function(evt){
var node = evt.target;
if(node._cssState && !node.getAttribute("widgetId")){
var widget = registry.getEnclosingWidget(node);
widget._subnodeCssMouseEvent(node, node._cssState, evt);
}
});
});
return CssStateMixin;
});

View File

@ -0,0 +1,14 @@
//>>built
define("dijit/_DialogMixin",["dojo/_base/declare","./a11y"],function(_1,_2){
return _1("dijit._DialogMixin",null,{execute:function(){
},onCancel:function(){
},onExecute:function(){
},_onSubmit:function(){
this.onExecute();
this.execute(this.get("value"));
},_getFocusItems:function(){
var _3=_2._getTabNavigable(this.containerNode);
this._firstFocusItem=_3.lowest||_3.first||this.closeButtonNode||this.domNode;
this._lastFocusItem=_3.last||_3.highest||this._firstFocusItem;
}});
});

View File

@ -0,0 +1,70 @@
define("dijit/_DialogMixin", [
"dojo/_base/declare", // declare
"./a11y" // _getTabNavigable
], function(declare, a11y){
// module:
// dijit/_DialogMixin
return declare("dijit._DialogMixin", null, {
// summary:
// This provides functions useful to Dialog and TooltipDialog
execute: function(/*Object*/ /*===== formContents =====*/){
// summary:
// Callback when the user hits the submit button.
// Override this method to handle Dialog execution.
// description:
// After the user has pressed the submit button, the Dialog
// first calls onExecute() to notify the container to hide the
// dialog and restore focus to wherever it used to be.
//
// *Then* this method is called.
// type:
// callback
},
onCancel: function(){
// summary:
// Called when user has pressed the Dialog's cancel button, to notify container.
// description:
// Developer shouldn't override or connect to this method;
// it's a private communication device between the TooltipDialog
// and the thing that opened it (ex: `dijit/form/DropDownButton`)
// type:
// protected
},
onExecute: function(){
// summary:
// Called when user has pressed the dialog's OK button, to notify container.
// description:
// Developer shouldn't override or connect to this method;
// it's a private communication device between the TooltipDialog
// and the thing that opened it (ex: `dijit/form/DropDownButton`)
// type:
// protected
},
_onSubmit: function(){
// summary:
// Callback when user hits submit button
// type:
// protected
this.onExecute(); // notify container that we are about to execute
this.execute(this.get('value'));
},
_getFocusItems: function(){
// summary:
// Finds focusable items in dialog,
// and sets this._firstFocusItem and this._lastFocusItem
// tags:
// protected
var elems = a11y._getTabNavigable(this.containerNode);
this._firstFocusItem = elems.lowest || elems.first || this.closeButtonNode || this.domNode;
this._lastFocusItem = elems.last || elems.highest || this._firstFocusItem;
}
});
});

View File

@ -0,0 +1,11 @@
//>>built
define("dijit/_FocusMixin",["./focus","./_WidgetBase","dojo/_base/declare","dojo/_base/lang"],function(_1,_2,_3,_4){
_4.extend(_2,{focused:false,onFocus:function(){
},onBlur:function(){
},_onFocus:function(){
this.onFocus();
},_onBlur:function(){
this.onBlur();
}});
return _3("dijit._FocusMixin",null,{_focusManager:_1});
});

View File

@ -0,0 +1,66 @@
define("dijit/_FocusMixin", [
"./focus",
"./_WidgetBase",
"dojo/_base/declare", // declare
"dojo/_base/lang" // lang.extend
], function(focus, _WidgetBase, declare, lang){
// module:
// dijit/_FocusMixin
// We don't know where _FocusMixin will occur in the inheritance chain, but we need the _onFocus()/_onBlur() below
// to be last in the inheritance chain, so mixin to _WidgetBase.
lang.extend(_WidgetBase, {
// focused: [readonly] Boolean
// This widget or a widget it contains has focus, or is "active" because
// it was recently clicked.
focused: false,
onFocus: function(){
// summary:
// Called when the widget becomes "active" because
// it or a widget inside of it either has focus, or has recently
// been clicked.
// tags:
// callback
},
onBlur: function(){
// summary:
// Called when the widget stops being "active" because
// focus moved to something outside of it, or the user
// clicked somewhere outside of it, or the widget was
// hidden.
// tags:
// callback
},
_onFocus: function(){
// summary:
// This is where widgets do processing for when they are active,
// such as changing CSS classes. See onFocus() for more details.
// tags:
// protected
this.onFocus();
},
_onBlur: function(){
// summary:
// This is where widgets do processing for when they stop being active,
// such as changing CSS classes. See onBlur() for more details.
// tags:
// protected
this.onBlur();
}
});
return declare("dijit._FocusMixin", null, {
// summary:
// Mixin to widget to provide _onFocus() and _onBlur() methods that
// fire when a widget or its descendants get/lose focus
// flag that I want _onFocus()/_onBlur() notifications from focus manager
_focusManager: focus
});
});

View File

@ -0,0 +1,223 @@
//>>built
define("dijit/_HasDropDown",["dojo/_base/declare","dojo/_base/Deferred","dojo/_base/event","dojo/dom","dojo/dom-attr","dojo/dom-class","dojo/dom-geometry","dojo/dom-style","dojo/has","dojo/keys","dojo/_base/lang","dojo/on","dojo/window","./registry","./focus","./popup","./_FocusMixin"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,on,_c,_d,_e,_f,_10){
return _1("dijit._HasDropDown",_10,{_buttonNode:null,_arrowWrapperNode:null,_popupStateNode:null,_aroundNode:null,dropDown:null,autoWidth:true,forceWidth:false,maxHeight:0,dropDownPosition:["below","above"],_stopClickEvents:true,_onDropDownMouseDown:function(e){
if(this.disabled||this.readOnly){
return;
}
e.preventDefault();
this._docHandler=this.connect(this.ownerDocument,"mouseup","_onDropDownMouseUp");
this.toggleDropDown();
},_onDropDownMouseUp:function(e){
if(e&&this._docHandler){
this.disconnect(this._docHandler);
}
var _11=this.dropDown,_12=false;
if(e&&this._opened){
var c=_7.position(this._buttonNode,true);
if(!(e.pageX>=c.x&&e.pageX<=c.x+c.w)||!(e.pageY>=c.y&&e.pageY<=c.y+c.h)){
var t=e.target;
while(t&&!_12){
if(_6.contains(t,"dijitPopup")){
_12=true;
}else{
t=t.parentNode;
}
}
if(_12){
t=e.target;
if(_11.onItemClick){
var _13;
while(t&&!(_13=_d.byNode(t))){
t=t.parentNode;
}
if(_13&&_13.onClick&&_13.getParent){
_13.getParent().onItemClick(_13,e);
}
}
return;
}
}
}
if(this._opened){
if(_11.focus&&_11.autoFocus!==false){
this._focusDropDownTimer=this.defer(function(){
_11.focus();
delete this._focusDropDownTimer;
});
}
}else{
this.defer("focus");
}
if(_9("touch")){
this._justGotMouseUp=true;
this.defer(function(){
this._justGotMouseUp=false;
});
}
},_onDropDownClick:function(e){
if(_9("touch")&&!this._justGotMouseUp){
this._onDropDownMouseDown(e);
this._onDropDownMouseUp(e);
}
if(this._stopClickEvents){
_3.stop(e);
}
},buildRendering:function(){
this.inherited(arguments);
this._buttonNode=this._buttonNode||this.focusNode||this.domNode;
this._popupStateNode=this._popupStateNode||this.focusNode||this._buttonNode;
var _14={"after":this.isLeftToRight()?"Right":"Left","before":this.isLeftToRight()?"Left":"Right","above":"Up","below":"Down","left":"Left","right":"Right"}[this.dropDownPosition[0]]||this.dropDownPosition[0]||"Down";
_6.add(this._arrowWrapperNode||this._buttonNode,"dijit"+_14+"ArrowButton");
},postCreate:function(){
this.inherited(arguments);
var _15=this.focusNode||this.domNode;
this.own(on(this._buttonNode,"mousedown",_b.hitch(this,"_onDropDownMouseDown")),on(this._buttonNode,"click",_b.hitch(this,"_onDropDownClick")),on(_15,"keydown",_b.hitch(this,"_onKey")),on(_15,"keyup",_b.hitch(this,"_onKeyUp")));
},destroy:function(){
if(this.dropDown){
if(!this.dropDown._destroyed){
this.dropDown.destroyRecursive();
}
delete this.dropDown;
}
this.inherited(arguments);
},_onKey:function(e){
if(this.disabled||this.readOnly){
return;
}
var d=this.dropDown,_16=e.target;
if(d&&this._opened&&d.handleKey){
if(d.handleKey(e)===false){
_3.stop(e);
return;
}
}
if(d&&this._opened&&e.keyCode==_a.ESCAPE){
this.closeDropDown();
_3.stop(e);
}else{
if(!this._opened&&(e.keyCode==_a.DOWN_ARROW||((e.keyCode==_a.ENTER||e.keyCode==_a.SPACE)&&((_16.tagName||"").toLowerCase()!=="input"||(_16.type&&_16.type.toLowerCase()!=="text"))))){
this._toggleOnKeyUp=true;
_3.stop(e);
}
}
},_onKeyUp:function(){
if(this._toggleOnKeyUp){
delete this._toggleOnKeyUp;
this.toggleDropDown();
var d=this.dropDown;
if(d&&d.focus){
this.defer(_b.hitch(d,"focus"),1);
}
}
},_onBlur:function(){
var _17=_e.curNode&&this.dropDown&&_4.isDescendant(_e.curNode,this.dropDown.domNode);
this.closeDropDown(_17);
this.inherited(arguments);
},isLoaded:function(){
return true;
},loadDropDown:function(_18){
_18();
},loadAndOpenDropDown:function(){
var d=new _2(),_19=_b.hitch(this,function(){
this.openDropDown();
d.resolve(this.dropDown);
});
if(!this.isLoaded()){
this.loadDropDown(_19);
}else{
_19();
}
return d;
},toggleDropDown:function(){
if(this.disabled||this.readOnly){
return;
}
if(!this._opened){
this.loadAndOpenDropDown();
}else{
this.closeDropDown();
}
},openDropDown:function(){
var _1a=this.dropDown,_1b=_1a.domNode,_1c=this._aroundNode||this.domNode,_1d=this;
if(!this._preparedNode){
this._preparedNode=true;
if(_1b.style.width){
this._explicitDDWidth=true;
}
if(_1b.style.height){
this._explicitDDHeight=true;
}
}
if(this.maxHeight||this.forceWidth||this.autoWidth){
var _1e={display:"",visibility:"hidden"};
if(!this._explicitDDWidth){
_1e.width="";
}
if(!this._explicitDDHeight){
_1e.height="";
}
_8.set(_1b,_1e);
var _1f=this.maxHeight;
if(_1f==-1){
var _20=_c.getBox(this.ownerDocument),_21=_7.position(_1c,false);
_1f=Math.floor(Math.max(_21.y,_20.h-(_21.y+_21.h)));
}
_f.moveOffScreen(_1a);
if(_1a.startup&&!_1a._started){
_1a.startup();
}
var mb=_7.getMarginSize(_1b);
var _22=(_1f&&mb.h>_1f);
_8.set(_1b,{overflowX:"visible",overflowY:_22?"auto":"visible"});
if(_22){
mb.h=_1f;
if("w" in mb){
mb.w+=16;
}
}else{
delete mb.h;
}
if(this.forceWidth){
mb.w=_1c.offsetWidth;
}else{
if(this.autoWidth){
mb.w=Math.max(mb.w,_1c.offsetWidth);
}else{
delete mb.w;
}
}
if(_b.isFunction(_1a.resize)){
_1a.resize(mb);
}else{
_7.setMarginBox(_1b,mb);
}
}
var _23=_f.open({parent:this,popup:_1a,around:_1c,orient:this.dropDownPosition,onExecute:function(){
_1d.closeDropDown(true);
},onCancel:function(){
_1d.closeDropDown(true);
},onClose:function(){
_5.set(_1d._popupStateNode,"popupActive",false);
_6.remove(_1d._popupStateNode,"dijitHasDropDownOpen");
_1d._set("_opened",false);
}});
_5.set(this._popupStateNode,"popupActive","true");
_6.add(this._popupStateNode,"dijitHasDropDownOpen");
this._set("_opened",true);
this.domNode.setAttribute("aria-expanded","true");
return _23;
},closeDropDown:function(_24){
if(this._focusDropDownTimer){
this._focusDropDownTimer.remove();
delete this._focusDropDownTimer;
}
if(this._opened){
this.domNode.setAttribute("aria-expanded","false");
if(_24){
this.focus();
}
_f.close(this.dropDown);
this._opened=false;
}
}});
});

View File

@ -0,0 +1,509 @@
define("dijit/_HasDropDown", [
"dojo/_base/declare", // declare
"dojo/_base/Deferred",
"dojo/_base/event", // event.stop
"dojo/dom", // dom.isDescendant
"dojo/dom-attr", // domAttr.set
"dojo/dom-class", // domClass.add domClass.contains domClass.remove
"dojo/dom-geometry", // domGeometry.marginBox domGeometry.position
"dojo/dom-style", // domStyle.set
"dojo/has", // has("touch")
"dojo/keys", // keys.DOWN_ARROW keys.ENTER keys.ESCAPE
"dojo/_base/lang", // lang.hitch lang.isFunction
"dojo/on",
"dojo/window", // winUtils.getBox
"./registry", // registry.byNode()
"./focus",
"./popup",
"./_FocusMixin"
], function(declare, Deferred, event,dom, domAttr, domClass, domGeometry, domStyle, has, keys, lang, on,
winUtils, registry, focus, popup, _FocusMixin){
// module:
// dijit/_HasDropDown
return declare("dijit._HasDropDown", _FocusMixin, {
// summary:
// Mixin for widgets that need drop down ability.
// _buttonNode: [protected] DomNode
// The button/icon/node to click to display the drop down.
// Can be set via a data-dojo-attach-point assignment.
// If missing, then either focusNode or domNode (if focusNode is also missing) will be used.
_buttonNode: null,
// _arrowWrapperNode: [protected] DomNode
// Will set CSS class dijitUpArrow, dijitDownArrow, dijitRightArrow etc. on this node depending
// on where the drop down is set to be positioned.
// Can be set via a data-dojo-attach-point assignment.
// If missing, then _buttonNode will be used.
_arrowWrapperNode: null,
// _popupStateNode: [protected] DomNode
// The node to set the popupActive class on.
// Can be set via a data-dojo-attach-point assignment.
// If missing, then focusNode or _buttonNode (if focusNode is missing) will be used.
_popupStateNode: null,
// _aroundNode: [protected] DomNode
// The node to display the popup around.
// Can be set via a data-dojo-attach-point assignment.
// If missing, then domNode will be used.
_aroundNode: null,
// dropDown: [protected] Widget
// The widget to display as a popup. This widget *must* be
// defined before the startup function is called.
dropDown: null,
// autoWidth: [protected] Boolean
// Set to true to make the drop down at least as wide as this
// widget. Set to false if the drop down should just be its
// default width
autoWidth: true,
// forceWidth: [protected] Boolean
// Set to true to make the drop down exactly as wide as this
// widget. Overrides autoWidth.
forceWidth: false,
// maxHeight: [protected] Integer
// The max height for our dropdown.
// Any dropdown taller than this will have scrollbars.
// Set to 0 for no max height, or -1 to limit height to available space in viewport
maxHeight: 0,
// dropDownPosition: [const] String[]
// This variable controls the position of the drop down.
// It's an array of strings with the following values:
//
// - before: places drop down to the left of the target node/widget, or to the right in
// the case of RTL scripts like Hebrew and Arabic
// - after: places drop down to the right of the target node/widget, or to the left in
// the case of RTL scripts like Hebrew and Arabic
// - above: drop down goes above target node
// - below: drop down goes below target node
//
// The list is positions is tried, in order, until a position is found where the drop down fits
// within the viewport.
//
dropDownPosition: ["below","above"],
// _stopClickEvents: Boolean
// When set to false, the click events will not be stopped, in
// case you want to use them in your subclass
_stopClickEvents: true,
_onDropDownMouseDown: function(/*Event*/ e){
// summary:
// Callback when the user mousedown's on the arrow icon
if(this.disabled || this.readOnly){ return; }
// Prevent default to stop things like text selection, but don't stop propagation, so that:
// 1. TimeTextBox etc. can focus the <input> on mousedown
// 2. dropDownButtonActive class applied by _CssStateMixin (on button depress)
// 3. user defined onMouseDown handler fires
e.preventDefault();
this._docHandler = this.connect(this.ownerDocument, "mouseup", "_onDropDownMouseUp");
this.toggleDropDown();
},
_onDropDownMouseUp: function(/*Event?*/ e){
// summary:
// Callback when the user lifts their mouse after mouse down on the arrow icon.
// If the drop down is a simple menu and the mouse is over the menu, we execute it, otherwise, we focus our
// drop down widget. If the event is missing, then we are not
// a mouseup event.
//
// This is useful for the common mouse movement pattern
// with native browser `<select>` nodes:
//
// 1. mouse down on the select node (probably on the arrow)
// 2. move mouse to a menu item while holding down the mouse button
// 3. mouse up. this selects the menu item as though the user had clicked it.
if(e && this._docHandler){
this.disconnect(this._docHandler);
}
var dropDown = this.dropDown, overMenu = false;
if(e && this._opened){
// This code deals with the corner-case when the drop down covers the original widget,
// because it's so large. In that case mouse-up shouldn't select a value from the menu.
// Find out if our target is somewhere in our dropdown widget,
// but not over our _buttonNode (the clickable node)
var c = domGeometry.position(this._buttonNode, true);
if(!(e.pageX >= c.x && e.pageX <= c.x + c.w) ||
!(e.pageY >= c.y && e.pageY <= c.y + c.h)){
var t = e.target;
while(t && !overMenu){
if(domClass.contains(t, "dijitPopup")){
overMenu = true;
}else{
t = t.parentNode;
}
}
if(overMenu){
t = e.target;
if(dropDown.onItemClick){
var menuItem;
while(t && !(menuItem = registry.byNode(t))){
t = t.parentNode;
}
if(menuItem && menuItem.onClick && menuItem.getParent){
menuItem.getParent().onItemClick(menuItem, e);
}
}
return;
}
}
}
if(this._opened){
if(dropDown.focus && dropDown.autoFocus !== false){
// Focus the dropdown widget - do it on a delay so that we
// don't steal back focus from the dropdown.
this._focusDropDownTimer = this.defer(function(){
dropDown.focus();
delete this._focusDropDownTimer;
});
}
}else{
// The drop down arrow icon probably can't receive focus, but widget itself should get focus.
// defer() needed to make it work on IE (test DateTextBox)
this.defer("focus");
}
if(has("touch")){
this._justGotMouseUp = true;
this.defer(function(){
this._justGotMouseUp = false;
});
}
},
_onDropDownClick: function(/*Event*/ e){
if(has("touch") && !this._justGotMouseUp){
// If there was no preceding mousedown/mouseup (like on android), then simulate them to
// toggle the drop down.
//
// The if(has("touch") is necessary since IE and desktop safari get spurious onclick events
// when there are nested tables (specifically, clicking on a table that holds a dijit/form/Select,
// but not on the Select itself, causes an onclick event on the Select)
this._onDropDownMouseDown(e);
this._onDropDownMouseUp(e);
}
// The drop down was already opened on mousedown/keydown; just need to call stopEvent().
if(this._stopClickEvents){
event.stop(e);
}
},
buildRendering: function(){
this.inherited(arguments);
this._buttonNode = this._buttonNode || this.focusNode || this.domNode;
this._popupStateNode = this._popupStateNode || this.focusNode || this._buttonNode;
// Add a class to the "dijitDownArrowButton" type class to _buttonNode so theme can set direction of arrow
// based on where drop down will normally appear
var defaultPos = {
"after" : this.isLeftToRight() ? "Right" : "Left",
"before" : this.isLeftToRight() ? "Left" : "Right",
"above" : "Up",
"below" : "Down",
"left" : "Left",
"right" : "Right"
}[this.dropDownPosition[0]] || this.dropDownPosition[0] || "Down";
domClass.add(this._arrowWrapperNode || this._buttonNode, "dijit" + defaultPos + "ArrowButton");
},
postCreate: function(){
// summary:
// set up nodes and connect our mouse and keyboard events
this.inherited(arguments);
var keyboardEventNode = this.focusNode || this.domNode;
this.own(
on(this._buttonNode, "mousedown", lang.hitch(this, "_onDropDownMouseDown")),
on(this._buttonNode, "click", lang.hitch(this, "_onDropDownClick")),
on(keyboardEventNode, "keydown", lang.hitch(this, "_onKey")),
on(keyboardEventNode, "keyup", lang.hitch(this, "_onKeyUp"))
);
},
destroy: function(){
if(this.dropDown){
// Destroy the drop down, unless it's already been destroyed. This can happen because
// the drop down is a direct child of <body> even though it's logically my child.
if(!this.dropDown._destroyed){
this.dropDown.destroyRecursive();
}
delete this.dropDown;
}
this.inherited(arguments);
},
_onKey: function(/*Event*/ e){
// summary:
// Callback when the user presses a key while focused on the button node
if(this.disabled || this.readOnly){ return; }
var d = this.dropDown, target = e.target;
if(d && this._opened && d.handleKey){
if(d.handleKey(e) === false){
/* false return code means that the drop down handled the key */
event.stop(e);
return;
}
}
if(d && this._opened && e.keyCode == keys.ESCAPE){
this.closeDropDown();
event.stop(e);
}else if(!this._opened &&
(e.keyCode == keys.DOWN_ARROW ||
( (e.keyCode == keys.ENTER || e.keyCode == keys.SPACE) &&
//ignore enter and space if the event is for a text input
((target.tagName || "").toLowerCase() !== 'input' ||
(target.type && target.type.toLowerCase() !== 'text'))))){
// Toggle the drop down, but wait until keyup so that the drop down doesn't
// get a stray keyup event, or in the case of key-repeat (because user held
// down key for too long), stray keydown events
this._toggleOnKeyUp = true;
event.stop(e);
}
},
_onKeyUp: function(){
if(this._toggleOnKeyUp){
delete this._toggleOnKeyUp;
this.toggleDropDown();
var d = this.dropDown; // drop down may not exist until toggleDropDown() call
if(d && d.focus){
this.defer(lang.hitch(d, "focus"), 1);
}
}
},
_onBlur: function(){
// summary:
// Called magically when focus has shifted away from this widget and it's dropdown
// Don't focus on button if the user has explicitly focused on something else (happens
// when user clicks another control causing the current popup to close)..
// But if focus is inside of the drop down then reset focus to me, because IE doesn't like
// it when you display:none a node with focus.
var focusMe = focus.curNode && this.dropDown && dom.isDescendant(focus.curNode, this.dropDown.domNode);
this.closeDropDown(focusMe);
this.inherited(arguments);
},
isLoaded: function(){
// summary:
// Returns true if the dropdown exists and it's data is loaded. This can
// be overridden in order to force a call to loadDropDown().
// tags:
// protected
return true;
},
loadDropDown: function(/*Function*/ loadCallback){
// summary:
// Creates the drop down if it doesn't exist, loads the data
// if there's an href and it hasn't been loaded yet, and then calls
// the given callback.
// tags:
// protected
// TODO: for 2.0, change API to return a Deferred, instead of calling loadCallback?
loadCallback();
},
loadAndOpenDropDown: function(){
// summary:
// Creates the drop down if it doesn't exist, loads the data
// if there's an href and it hasn't been loaded yet, and
// then opens the drop down. This is basically a callback when the
// user presses the down arrow button to open the drop down.
// returns: Deferred
// Deferred for the drop down widget that
// fires when drop down is created and loaded
// tags:
// protected
var d = new Deferred(),
afterLoad = lang.hitch(this, function(){
this.openDropDown();
d.resolve(this.dropDown);
});
if(!this.isLoaded()){
this.loadDropDown(afterLoad);
}else{
afterLoad();
}
return d;
},
toggleDropDown: function(){
// summary:
// Callback when the user presses the down arrow button or presses
// the down arrow key to open/close the drop down.
// Toggle the drop-down widget; if it is up, close it, if not, open it
// tags:
// protected
if(this.disabled || this.readOnly){ return; }
if(!this._opened){
this.loadAndOpenDropDown();
}else{
this.closeDropDown();
}
},
openDropDown: function(){
// summary:
// Opens the dropdown for this widget. To be called only when this.dropDown
// has been created and is ready to display (ie, it's data is loaded).
// returns:
// return value of dijit/popup.open()
// tags:
// protected
var dropDown = this.dropDown,
ddNode = dropDown.domNode,
aroundNode = this._aroundNode || this.domNode,
self = this;
// Prepare our popup's height and honor maxHeight if it exists.
// TODO: isn't maxHeight dependent on the return value from dijit/popup.open(),
// ie, dependent on how much space is available (BK)
if(!this._preparedNode){
this._preparedNode = true;
// Check if we have explicitly set width and height on the dropdown widget dom node
if(ddNode.style.width){
this._explicitDDWidth = true;
}
if(ddNode.style.height){
this._explicitDDHeight = true;
}
}
// Code for resizing dropdown (height limitation, or increasing width to match my width)
if(this.maxHeight || this.forceWidth || this.autoWidth){
var myStyle = {
display: "",
visibility: "hidden"
};
if(!this._explicitDDWidth){
myStyle.width = "";
}
if(!this._explicitDDHeight){
myStyle.height = "";
}
domStyle.set(ddNode, myStyle);
// Figure out maximum height allowed (if there is a height restriction)
var maxHeight = this.maxHeight;
if(maxHeight == -1){
// limit height to space available in viewport either above or below my domNode
// (whichever side has more room)
var viewport = winUtils.getBox(this.ownerDocument),
position = domGeometry.position(aroundNode, false);
maxHeight = Math.floor(Math.max(position.y, viewport.h - (position.y + position.h)));
}
// Attach dropDown to DOM and make make visibility:hidden rather than display:none
// so we call startup() and also get the size
popup.moveOffScreen(dropDown);
if(dropDown.startup && !dropDown._started){
dropDown.startup(); // this has to be done after being added to the DOM
}
// Get size of drop down, and determine if vertical scroll bar needed. If no scroll bar needed,
// use overflow:visible rather than overflow:hidden so off-by-one errors don't hide drop down border.
var mb = domGeometry.getMarginSize(ddNode);
var overHeight = (maxHeight && mb.h > maxHeight);
domStyle.set(ddNode, {
overflowX: "visible",
overflowY: overHeight ? "auto" : "visible"
});
if(overHeight){
mb.h = maxHeight;
if("w" in mb){
mb.w += 16; // room for vertical scrollbar
}
}else{
delete mb.h;
}
// Adjust dropdown width to match or be larger than my width
if(this.forceWidth){
mb.w = aroundNode.offsetWidth;
}else if(this.autoWidth){
mb.w = Math.max(mb.w, aroundNode.offsetWidth);
}else{
delete mb.w;
}
// And finally, resize the dropdown to calculated height and width
if(lang.isFunction(dropDown.resize)){
dropDown.resize(mb);
}else{
domGeometry.setMarginBox(ddNode, mb);
}
}
var retVal = popup.open({
parent: this,
popup: dropDown,
around: aroundNode,
orient: this.dropDownPosition,
onExecute: function(){
self.closeDropDown(true);
},
onCancel: function(){
self.closeDropDown(true);
},
onClose: function(){
domAttr.set(self._popupStateNode, "popupActive", false);
domClass.remove(self._popupStateNode, "dijitHasDropDownOpen");
self._set("_opened", false); // use set() because _CssStateMixin is watching
}
});
domAttr.set(this._popupStateNode, "popupActive", "true");
domClass.add(this._popupStateNode, "dijitHasDropDownOpen");
this._set("_opened", true); // use set() because _CssStateMixin is watching
this.domNode.setAttribute("aria-expanded", "true");
return retVal;
},
closeDropDown: function(/*Boolean*/ focus){
// summary:
// Closes the drop down on this widget
// focus:
// If true, refocuses the button widget
// tags:
// protected
if(this._focusDropDownTimer){
this._focusDropDownTimer.remove();
delete this._focusDropDownTimer;
}
if(this._opened){
this.domNode.setAttribute("aria-expanded", "false");
if(focus){ this.focus(); }
popup.close(this.dropDown);
this._opened = false;
}
}
});
});

View File

@ -0,0 +1,95 @@
//>>built
define("dijit/_KeyNavContainer",["dojo/_base/kernel","./_Container","./_FocusMixin","dojo/_base/array","dojo/keys","dojo/_base/declare","dojo/_base/event","dojo/dom-attr","dojo/_base/lang"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9){
return _6("dijit._KeyNavContainer",[_3,_2],{tabIndex:"0",connectKeyNavHandlers:function(_a,_b){
var _c=(this._keyNavCodes={});
var _d=_9.hitch(this,"focusPrev");
var _e=_9.hitch(this,"focusNext");
_4.forEach(_a,function(_f){
_c[_f]=_d;
});
_4.forEach(_b,function(_10){
_c[_10]=_e;
});
_c[_5.HOME]=_9.hitch(this,"focusFirstChild");
_c[_5.END]=_9.hitch(this,"focusLastChild");
this.connect(this.domNode,"onkeypress","_onContainerKeypress");
this.connect(this.domNode,"onfocus","_onContainerFocus");
},startupKeyNavChildren:function(){
_1.deprecated("startupKeyNavChildren() call no longer needed","","2.0");
},startup:function(){
this.inherited(arguments);
_4.forEach(this.getChildren(),_9.hitch(this,"_startupChild"));
},addChild:function(_11,_12){
this.inherited(arguments);
this._startupChild(_11);
},focus:function(){
this.focusFirstChild();
},focusFirstChild:function(){
this.focusChild(this._getFirstFocusableChild());
},focusLastChild:function(){
this.focusChild(this._getLastFocusableChild());
},focusNext:function(){
this.focusChild(this._getNextFocusableChild(this.focusedChild,1));
},focusPrev:function(){
this.focusChild(this._getNextFocusableChild(this.focusedChild,-1),true);
},focusChild:function(_13,_14){
if(!_13){
return;
}
if(this.focusedChild&&_13!==this.focusedChild){
this._onChildBlur(this.focusedChild);
}
_13.set("tabIndex",this.tabIndex);
_13.focus(_14?"end":"start");
this._set("focusedChild",_13);
},_startupChild:function(_15){
_15.set("tabIndex","-1");
this.connect(_15,"_onFocus",function(){
_15.set("tabIndex",this.tabIndex);
});
this.connect(_15,"_onBlur",function(){
_15.set("tabIndex","-1");
});
},_onContainerFocus:function(evt){
if(evt.target!==this.domNode||this.focusedChild){
return;
}
this.focusFirstChild();
_8.set(this.domNode,"tabIndex","-1");
},_onBlur:function(evt){
if(this.tabIndex){
_8.set(this.domNode,"tabIndex",this.tabIndex);
}
this.focusedChild=null;
this.inherited(arguments);
},_onContainerKeypress:function(evt){
if(evt.ctrlKey||evt.altKey){
return;
}
var _16=this._keyNavCodes[evt.charOrCode];
if(_16){
_16();
_7.stop(evt);
}
},_onChildBlur:function(){
},_getFirstFocusableChild:function(){
return this._getNextFocusableChild(null,1);
},_getLastFocusableChild:function(){
return this._getNextFocusableChild(null,-1);
},_getNextFocusableChild:function(_17,dir){
if(_17){
_17=this._getSiblingOfChild(_17,dir);
}
var _18=this.getChildren();
for(var i=0;i<_18.length;i++){
if(!_17){
_17=_18[(dir>0)?0:(_18.length-1)];
}
if(_17.isFocusable()){
return _17;
}
_17=this._getSiblingOfChild(_17,dir);
}
return null;
}});
});

View File

@ -0,0 +1,257 @@
define("dijit/_KeyNavContainer", [
"dojo/_base/kernel", // kernel.deprecated
"./_Container",
"./_FocusMixin",
"dojo/_base/array", // array.forEach
"dojo/keys", // keys.END keys.HOME
"dojo/_base/declare", // declare
"dojo/_base/event", // event.stop
"dojo/dom-attr", // domAttr.set
"dojo/_base/lang" // lang.hitch
], function(kernel, _Container, _FocusMixin, array, keys, declare, event, domAttr, lang){
// module:
// dijit/_KeyNavContainer
return declare("dijit._KeyNavContainer", [_FocusMixin, _Container], {
// summary:
// A _Container with keyboard navigation of its children.
// description:
// To use this mixin, call connectKeyNavHandlers() in
// postCreate().
// It provides normalized keyboard and focusing code for Container
// widgets.
/*=====
// focusedChild: [protected] Widget
// The currently focused child widget, or null if there isn't one
focusedChild: null,
=====*/
// tabIndex: String
// Tab index of the container; same as HTML tabIndex attribute.
// Note then when user tabs into the container, focus is immediately
// moved to the first item in the container.
tabIndex: "0",
connectKeyNavHandlers: function(/*keys[]*/ prevKeyCodes, /*keys[]*/ nextKeyCodes){
// summary:
// Call in postCreate() to attach the keyboard handlers
// to the container.
// preKeyCodes: keys[]
// Key codes for navigating to the previous child.
// nextKeyCodes: keys[]
// Key codes for navigating to the next child.
// tags:
// protected
// TODO: call this automatically from my own postCreate()
var keyCodes = (this._keyNavCodes = {});
var prev = lang.hitch(this, "focusPrev");
var next = lang.hitch(this, "focusNext");
array.forEach(prevKeyCodes, function(code){ keyCodes[code] = prev; });
array.forEach(nextKeyCodes, function(code){ keyCodes[code] = next; });
keyCodes[keys.HOME] = lang.hitch(this, "focusFirstChild");
keyCodes[keys.END] = lang.hitch(this, "focusLastChild");
this.connect(this.domNode, "onkeypress", "_onContainerKeypress");
this.connect(this.domNode, "onfocus", "_onContainerFocus");
},
startupKeyNavChildren: function(){
kernel.deprecated("startupKeyNavChildren() call no longer needed", "", "2.0");
},
startup: function(){
this.inherited(arguments);
array.forEach(this.getChildren(), lang.hitch(this, "_startupChild"));
},
addChild: function(/*dijit/_WidgetBase*/ widget, /*int?*/ insertIndex){
this.inherited(arguments);
this._startupChild(widget);
},
focus: function(){
// summary:
// Default focus() implementation: focus the first child.
this.focusFirstChild();
},
focusFirstChild: function(){
// summary:
// Focus the first focusable child in the container.
// tags:
// protected
this.focusChild(this._getFirstFocusableChild());
},
focusLastChild: function(){
// summary:
// Focus the last focusable child in the container.
// tags:
// protected
this.focusChild(this._getLastFocusableChild());
},
focusNext: function(){
// summary:
// Focus the next widget
// tags:
// protected
this.focusChild(this._getNextFocusableChild(this.focusedChild, 1));
},
focusPrev: function(){
// summary:
// Focus the last focusable node in the previous widget
// (ex: go to the ComboButton icon section rather than button section)
// tags:
// protected
this.focusChild(this._getNextFocusableChild(this.focusedChild, -1), true);
},
focusChild: function(/*dijit/_WidgetBase*/ widget, /*Boolean*/ last){
// summary:
// Focus specified child widget.
// widget:
// Reference to container's child widget
// last:
// If true and if widget has multiple focusable nodes, focus the
// last one instead of the first one
// tags:
// protected
if(!widget){ return; }
if(this.focusedChild && widget !== this.focusedChild){
this._onChildBlur(this.focusedChild); // used by _MenuBase
}
widget.set("tabIndex", this.tabIndex); // for IE focus outline to appear, must set tabIndex before focs
widget.focus(last ? "end" : "start");
this._set("focusedChild", widget);
},
_startupChild: function(/*dijit/_WidgetBase*/ widget){
// summary:
// Setup for each child widget
// description:
// Sets tabIndex=-1 on each child, so that the tab key will
// leave the container rather than visiting each child.
// tags:
// private
widget.set("tabIndex", "-1");
this.connect(widget, "_onFocus", function(){
// Set valid tabIndex so tabbing away from widget goes to right place, see #10272
widget.set("tabIndex", this.tabIndex);
});
this.connect(widget, "_onBlur", function(){
widget.set("tabIndex", "-1");
});
},
_onContainerFocus: function(evt){
// summary:
// Handler for when the container gets focus
// description:
// Initially the container itself has a tabIndex, but when it gets
// focus, switch focus to first child...
// tags:
// private
// Note that we can't use _onFocus() because switching focus from the
// _onFocus() handler confuses the focus.js code
// (because it causes _onFocusNode() to be called recursively)
// Also, _onFocus() would fire when focus went directly to a child widget due to mouse click.
// Ignore spurious focus events:
// 1. focus on a child widget bubbles on FF
// 2. on IE, clicking the scrollbar of a select dropdown moves focus from the focused child item to me
if(evt.target !== this.domNode || this.focusedChild){ return; }
this.focusFirstChild();
// and then set the container's tabIndex to -1,
// (don't remove as that breaks Safari 4)
// so that tab or shift-tab will go to the fields after/before
// the container, rather than the container itself
domAttr.set(this.domNode, "tabIndex", "-1");
},
_onBlur: function(evt){
// When focus is moved away the container, and its descendant (popup) widgets,
// then restore the container's tabIndex so that user can tab to it again.
// Note that using _onBlur() so that this doesn't happen when focus is shifted
// to one of my child widgets (typically a popup)
if(this.tabIndex){
domAttr.set(this.domNode, "tabIndex", this.tabIndex);
}
this.focusedChild = null;
this.inherited(arguments);
},
_onContainerKeypress: function(evt){
// summary:
// When a key is pressed, if it's an arrow key etc. then
// it's handled here.
// tags:
// private
if(evt.ctrlKey || evt.altKey){ return; }
var func = this._keyNavCodes[evt.charOrCode];
if(func){
func();
event.stop(evt);
}
},
_onChildBlur: function(/*dijit/_WidgetBase*/ /*===== widget =====*/){
// summary:
// Called when focus leaves a child widget to go
// to a sibling widget.
// Used by MenuBase.js (TODO: move code there)
// tags:
// protected
},
_getFirstFocusableChild: function(){
// summary:
// Returns first child that can be focused
return this._getNextFocusableChild(null, 1); // dijit/_WidgetBase
},
_getLastFocusableChild: function(){
// summary:
// Returns last child that can be focused
return this._getNextFocusableChild(null, -1); // dijit/_WidgetBase
},
_getNextFocusableChild: function(child, dir){
// summary:
// Returns the next or previous focusable child, compared
// to "child"
// child: Widget
// The current widget
// dir: Integer
// - 1 = after
// - -1 = before
if(child){
child = this._getSiblingOfChild(child, dir);
}
var children = this.getChildren();
for(var i=0; i < children.length; i++){
if(!child){
child = children[(dir>0) ? 0 : (children.length-1)];
}
if(child.isFocusable()){
return child; // dijit/_WidgetBase
}
child = this._getSiblingOfChild(child, dir);
}
// no focusable child found
return null; // dijit/_WidgetBase
}
});
});

View File

@ -0,0 +1,175 @@
//>>built
define("dijit/_MenuBase",["dojo/_base/array","dojo/_base/declare","dojo/dom","dojo/dom-attr","dojo/dom-class","dojo/_base/lang","dojo/mouse","dojo/on","dojo/window","./a11yclick","./popup","./registry","./_Widget","./_KeyNavContainer","./_TemplatedMixin"],function(_1,_2,_3,_4,_5,_6,_7,on,_8,_9,pm,_a,_b,_c,_d){
return _2("dijit._MenuBase",[_b,_d,_c],{parentMenu:null,popupDelay:500,autoFocus:false,childSelector:function(_e){
var _f=_a.byNode(_e);
return _e.parentNode==this.containerNode&&_f&&_f.focus;
},postCreate:function(){
var _10=this,_11=typeof this.childSelector=="string"?this.childSelector:_6.hitch(this,"childSelector");
this.own(on(this.containerNode,on.selector(_11,_7.enter),function(){
_10.onItemHover(_a.byNode(this));
}),on(this.containerNode,on.selector(_11,_7.leave),function(){
_10.onItemUnhover(_a.byNode(this));
}),on(this.containerNode,on.selector(_11,_9),function(evt){
_10.onItemClick(_a.byNode(this),evt);
evt.stopPropagation();
evt.preventDefault();
}));
this.inherited(arguments);
},onExecute:function(){
},onCancel:function(){
},_moveToPopup:function(evt){
if(this.focusedChild&&this.focusedChild.popup&&!this.focusedChild.disabled){
this.onItemClick(this.focusedChild,evt);
}else{
var _12=this._getTopMenu();
if(_12&&_12._isMenuBar){
_12.focusNext();
}
}
},_onPopupHover:function(){
if(this.currentPopup&&this.currentPopup._pendingClose_timer){
var _13=this.currentPopup.parentMenu;
if(_13.focusedChild){
_13.focusedChild._setSelected(false);
}
_13.focusedChild=this.currentPopup.from_item;
_13.focusedChild._setSelected(true);
this._stopPendingCloseTimer(this.currentPopup);
}
},onItemHover:function(_14){
if(this.isActive){
this.focusChild(_14);
if(this.focusedChild.popup&&!this.focusedChild.disabled&&!this.hover_timer){
this.hover_timer=this.defer("_openPopup",this.popupDelay);
}
}
if(this.focusedChild){
this.focusChild(_14);
}
this._hoveredChild=_14;
_14._set("hovering",true);
},_onChildBlur:function(_15){
this._stopPopupTimer();
_15._setSelected(false);
var _16=_15.popup;
if(_16){
this._stopPendingCloseTimer(_16);
_16._pendingClose_timer=this.defer(function(){
_16._pendingClose_timer=null;
if(_16.parentMenu){
_16.parentMenu.currentPopup=null;
}
pm.close(_16);
},this.popupDelay);
}
},onItemUnhover:function(_17){
if(this.isActive){
this._stopPopupTimer();
}
if(this._hoveredChild==_17){
this._hoveredChild=null;
}
_17._set("hovering",false);
},_stopPopupTimer:function(){
if(this.hover_timer){
this.hover_timer=this.hover_timer.remove();
}
},_stopPendingCloseTimer:function(_18){
if(_18._pendingClose_timer){
_18._pendingClose_timer=_18._pendingClose_timer.remove();
}
},_stopFocusTimer:function(){
if(this._focus_timer){
this._focus_timer=this._focus_timer.remove();
}
},_getTopMenu:function(){
for(var top=this;top.parentMenu;top=top.parentMenu){
}
return top;
},onItemClick:function(_19,evt){
if(typeof this.isShowingNow=="undefined"){
this._markActive();
}
this.focusChild(_19);
if(_19.disabled){
return false;
}
if(_19.popup){
this._openPopup(evt.type=="keypress");
}else{
this.onExecute();
_19._onClick?_19._onClick(evt):_19.onClick(evt);
}
},_openPopup:function(_1a){
this._stopPopupTimer();
var _1b=this.focusedChild;
if(!_1b){
return;
}
var _1c=_1b.popup;
if(!_1c.isShowingNow){
if(this.currentPopup){
this._stopPendingCloseTimer(this.currentPopup);
pm.close(this.currentPopup);
}
_1c.parentMenu=this;
_1c.from_item=_1b;
var _1d=this;
pm.open({parent:this,popup:_1c,around:_1b.domNode,orient:this._orient||["after","before"],onCancel:function(){
_1d.focusChild(_1b);
_1d._cleanUp();
_1b._setSelected(true);
_1d.focusedChild=_1b;
},onExecute:_6.hitch(this,"_cleanUp")});
this.currentPopup=_1c;
_1c.connect(_1c.domNode,"onmouseenter",_6.hitch(_1d,"_onPopupHover"));
}
if(_1a&&_1c.focus){
_1c._focus_timer=this.defer(_6.hitch(_1c,function(){
this._focus_timer=null;
this.focus();
}));
}
},_markActive:function(){
this.isActive=true;
_5.replace(this.domNode,"dijitMenuActive","dijitMenuPassive");
},onOpen:function(){
this.isShowingNow=true;
this._markActive();
},_markInactive:function(){
this.isActive=false;
_5.replace(this.domNode,"dijitMenuPassive","dijitMenuActive");
},onClose:function(){
this._stopFocusTimer();
this._markInactive();
this.isShowingNow=false;
this.parentMenu=null;
},_closeChild:function(){
this._stopPopupTimer();
if(this.currentPopup){
if(_1.indexOf(this._focusManager.activeStack,this.id)>=0){
_4.set(this.focusedChild.focusNode,"tabIndex",this.tabIndex);
this.focusedChild.focusNode.focus();
}
pm.close(this.currentPopup);
this.currentPopup=null;
}
if(this.focusedChild){
this.focusedChild._setSelected(false);
this.onItemUnhover(this.focusedChild);
this.focusedChild=null;
}
},_onItemFocus:function(_1e){
if(this._hoveredChild&&this._hoveredChild!=_1e){
this.onItemUnhover(this._hoveredChild);
}
},_onBlur:function(){
this._cleanUp();
this.inherited(arguments);
},_cleanUp:function(){
this._closeChild();
if(typeof this.isShowingNow=="undefined"){
this._markInactive();
}
}});
});

View File

@ -0,0 +1,429 @@
define("dijit/_MenuBase", [
"dojo/_base/array", // array.indexOf
"dojo/_base/declare", // declare
"dojo/dom", // dom.isDescendant domClass.replace
"dojo/dom-attr",
"dojo/dom-class", // domClass.replace
"dojo/_base/lang", // lang.hitch
"dojo/mouse", // mouse.enter, mouse.leave
"dojo/on",
"dojo/window",
"./a11yclick",
"./popup",
"./registry",
"./_Widget",
"./_KeyNavContainer",
"./_TemplatedMixin"
], function(array, declare, dom, domAttr, domClass, lang, mouse, on, winUtils,
a11yclick, pm, registry, _Widget, _KeyNavContainer, _TemplatedMixin){
// module:
// dijit/_MenuBase
return declare("dijit._MenuBase",
[_Widget, _TemplatedMixin, _KeyNavContainer],
{
// summary:
// Base class for Menu and MenuBar
// parentMenu: [readonly] Widget
// pointer to menu that displayed me
parentMenu: null,
// popupDelay: Integer
// number of milliseconds before hovering (without clicking) causes the popup to automatically open.
popupDelay: 500,
// autoFocus: Boolean
// A toggle to control whether or not a Menu gets focused when opened as a drop down from a MenuBar
// or DropDownButton/ComboButton. Note though that it always get focused when opened via the keyboard.
autoFocus: false,
childSelector: function(/*DOMNode*/ node){
// summary:
// Selector (passed to on.selector()) used to identify MenuItem child widgets, but exclude inert children
// like MenuSeparator. If subclass overrides to a string (ex: "> *"), the subclass must require dojo/query.
// tags:
// protected
var widget = registry.byNode(node);
return node.parentNode == this.containerNode && widget && widget.focus;
},
postCreate: function(){
var self = this,
matches = typeof this.childSelector == "string" ? this.childSelector : lang.hitch(this, "childSelector");
this.own(
on(this.containerNode, on.selector(matches, mouse.enter), function(){
self.onItemHover(registry.byNode(this));
}),
on(this.containerNode, on.selector(matches, mouse.leave), function(){
self.onItemUnhover(registry.byNode(this));
}),
on(this.containerNode, on.selector(matches, a11yclick), function(evt){
self.onItemClick(registry.byNode(this), evt);
evt.stopPropagation();
evt.preventDefault();
})
);
this.inherited(arguments);
},
onExecute: function(){
// summary:
// Attach point for notification about when a menu item has been executed.
// This is an internal mechanism used for Menus to signal to their parent to
// close them, because they are about to execute the onClick handler. In
// general developers should not attach to or override this method.
// tags:
// protected
},
onCancel: function(/*Boolean*/ /*===== closeAll =====*/){
// summary:
// Attach point for notification about when the user cancels the current menu
// This is an internal mechanism used for Menus to signal to their parent to
// close them. In general developers should not attach to or override this method.
// tags:
// protected
},
_moveToPopup: function(/*Event*/ evt){
// summary:
// This handles the right arrow key (left arrow key on RTL systems),
// which will either open a submenu, or move to the next item in the
// ancestor MenuBar
// tags:
// private
if(this.focusedChild && this.focusedChild.popup && !this.focusedChild.disabled){
this.onItemClick(this.focusedChild, evt);
}else{
var topMenu = this._getTopMenu();
if(topMenu && topMenu._isMenuBar){
topMenu.focusNext();
}
}
},
_onPopupHover: function(/*Event*/ /*===== evt =====*/){
// summary:
// This handler is called when the mouse moves over the popup.
// tags:
// private
// if the mouse hovers over a menu popup that is in pending-close state,
// then stop the close operation.
// This can't be done in onItemHover since some popup targets don't have MenuItems (e.g. ColorPicker)
if(this.currentPopup && this.currentPopup._pendingClose_timer){
var parentMenu = this.currentPopup.parentMenu;
// highlight the parent menu item pointing to this popup
if(parentMenu.focusedChild){
parentMenu.focusedChild._setSelected(false);
}
parentMenu.focusedChild = this.currentPopup.from_item;
parentMenu.focusedChild._setSelected(true);
// cancel the pending close
this._stopPendingCloseTimer(this.currentPopup);
}
},
onItemHover: function(/*MenuItem*/ item){
// summary:
// Called when cursor is over a MenuItem.
// tags:
// protected
// Don't do anything unless user has "activated" the menu by:
// 1) clicking it
// 2) opening it from a parent menu (which automatically focuses it)
if(this.isActive){
this.focusChild(item);
if(this.focusedChild.popup && !this.focusedChild.disabled && !this.hover_timer){
this.hover_timer = this.defer("_openPopup", this.popupDelay);
}
}
// if the user is mixing mouse and keyboard navigation,
// then the menu may not be active but a menu item has focus,
// but it's not the item that the mouse just hovered over.
// To avoid both keyboard and mouse selections, use the latest.
if(this.focusedChild){
this.focusChild(item);
}
this._hoveredChild = item;
item._set("hovering", true);
},
_onChildBlur: function(item){
// summary:
// Called when a child MenuItem becomes inactive because focus
// has been removed from the MenuItem *and* it's descendant menus.
// tags:
// private
this._stopPopupTimer();
item._setSelected(false);
// Close all popups that are open and descendants of this menu
var itemPopup = item.popup;
if(itemPopup){
this._stopPendingCloseTimer(itemPopup);
itemPopup._pendingClose_timer = this.defer(function(){
itemPopup._pendingClose_timer = null;
if(itemPopup.parentMenu){
itemPopup.parentMenu.currentPopup = null;
}
pm.close(itemPopup); // this calls onClose
}, this.popupDelay);
}
},
onItemUnhover: function(/*MenuItem*/ item){
// summary:
// Callback fires when mouse exits a MenuItem
// tags:
// protected
if(this.isActive){
this._stopPopupTimer();
}
if(this._hoveredChild == item){ this._hoveredChild = null; }
item._set("hovering", false);
},
_stopPopupTimer: function(){
// summary:
// Cancels the popup timer because the user has stop hovering
// on the MenuItem, etc.
// tags:
// private
if(this.hover_timer){
this.hover_timer = this.hover_timer.remove();
}
},
_stopPendingCloseTimer: function(/*dijit/_WidgetBase*/ popup){
// summary:
// Cancels the pending-close timer because the close has been preempted
// tags:
// private
if(popup._pendingClose_timer){
popup._pendingClose_timer = popup._pendingClose_timer.remove();
}
},
_stopFocusTimer: function(){
// summary:
// Cancels the pending-focus timer because the menu was closed before focus occured
// tags:
// private
if(this._focus_timer){
this._focus_timer = this._focus_timer.remove();
}
},
_getTopMenu: function(){
// summary:
// Returns the top menu in this chain of Menus
// tags:
// private
for(var top=this; top.parentMenu; top=top.parentMenu);
return top;
},
onItemClick: function(/*dijit/_WidgetBase*/ item, /*Event*/ evt){
// summary:
// Handle clicks on an item.
// tags:
// private
// this can't be done in _onFocus since the _onFocus events occurs asynchronously
if(typeof this.isShowingNow == 'undefined'){ // non-popup menu
this._markActive();
}
this.focusChild(item);
if(item.disabled){ return false; }
if(item.popup){
this._openPopup(evt.type == "keypress");
}else{
// before calling user defined handler, close hierarchy of menus
// and restore focus to place it was when menu was opened
this.onExecute();
// user defined handler for click
item._onClick ? item._onClick(evt) : item.onClick(evt);
}
},
_openPopup: function(/*Boolean*/ focus){
// summary:
// Open the popup to the side of/underneath the current menu item, and optionally focus first item
// tags:
// protected
this._stopPopupTimer();
var from_item = this.focusedChild;
if(!from_item){ return; } // the focused child lost focus since the timer was started
var popup = from_item.popup;
if(!popup.isShowingNow){
if(this.currentPopup){
this._stopPendingCloseTimer(this.currentPopup);
pm.close(this.currentPopup);
}
popup.parentMenu = this;
popup.from_item = from_item; // helps finding the parent item that should be focused for this popup
var self = this;
pm.open({
parent: this,
popup: popup,
around: from_item.domNode,
orient: this._orient || ["after", "before"],
onCancel: function(){ // called when the child menu is canceled
// set isActive=false (_closeChild vs _cleanUp) so that subsequent hovering will NOT open child menus
// which seems aligned with the UX of most applications (e.g. notepad, wordpad, paint shop pro)
self.focusChild(from_item); // put focus back on my node
self._cleanUp(); // close the submenu (be sure this is done _after_ focus is moved)
from_item._setSelected(true); // oops, _cleanUp() deselected the item
self.focusedChild = from_item; // and unset focusedChild
},
onExecute: lang.hitch(this, "_cleanUp")
});
this.currentPopup = popup;
// detect mouseovers to handle lazy mouse movements that temporarily focus other menu items
popup.connect(popup.domNode, "onmouseenter", lang.hitch(self, "_onPopupHover")); // cleaned up when the popped-up widget is destroyed on close
}
if(focus && popup.focus){
// If user is opening the popup via keyboard (right arrow, or down arrow for MenuBar), then focus the popup.
// If the cursor happens to collide with the popup, it will generate an onmouseover event
// even though the mouse wasn't moved. Use defer() to call popup.focus so that
// our focus() call overrides the onmouseover event, rather than vice-versa. (#8742)
popup._focus_timer = this.defer(lang.hitch(popup, function(){
this._focus_timer = null;
this.focus();
}));
}
},
_markActive: function(){
// summary:
// Mark this menu's state as active.
// Called when this Menu gets focus from:
//
// 1. clicking it (mouse or via space/arrow key)
// 2. being opened by a parent menu.
//
// This is not called just from mouse hover.
// Focusing a menu via TAB does NOT automatically set isActive
// since TAB is a navigation operation and not a selection one.
// For Windows apps, pressing the ALT key focuses the menubar
// menus (similar to TAB navigation) but the menu is not active
// (ie no dropdown) until an item is clicked.
this.isActive = true;
domClass.replace(this.domNode, "dijitMenuActive", "dijitMenuPassive");
},
onOpen: function(/*Event*/ /*===== e =====*/){
// summary:
// Callback when this menu is opened.
// This is called by the popup manager as notification that the menu
// was opened.
// tags:
// private
this.isShowingNow = true;
this._markActive();
},
_markInactive: function(){
// summary:
// Mark this menu's state as inactive.
this.isActive = false; // don't do this in _onBlur since the state is pending-close until we get here
domClass.replace(this.domNode, "dijitMenuPassive", "dijitMenuActive");
},
onClose: function(){
// summary:
// Callback when this menu is closed.
// This is called by the popup manager as notification that the menu
// was closed.
// tags:
// private
this._stopFocusTimer();
this._markInactive();
this.isShowingNow = false;
this.parentMenu = null;
},
_closeChild: function(){
// summary:
// Called when submenu is clicked or focus is lost. Close hierarchy of menus.
// tags:
// private
this._stopPopupTimer();
if(this.currentPopup){
// If focus is on a descendant MenuItem then move focus to me,
// because IE doesn't like it when you display:none a node with focus,
// and also so keyboard users don't lose control.
// Likely, immediately after a user defined onClick handler will move focus somewhere
// else, like a Dialog.
if(array.indexOf(this._focusManager.activeStack, this.id) >= 0){
domAttr.set(this.focusedChild.focusNode, "tabIndex", this.tabIndex);
this.focusedChild.focusNode.focus();
}
// Close all popups that are open and descendants of this menu
pm.close(this.currentPopup);
this.currentPopup = null;
}
if(this.focusedChild){ // unhighlight the focused item
this.focusedChild._setSelected(false);
this.onItemUnhover(this.focusedChild);
this.focusedChild = null;
}
},
_onItemFocus: function(/*MenuItem*/ item){
// summary:
// Called when child of this Menu gets focus from:
//
// 1. clicking it
// 2. tabbing into it
// 3. being opened by a parent menu.
//
// This is not called just from mouse hover.
if(this._hoveredChild && this._hoveredChild != item){
this.onItemUnhover(this._hoveredChild); // any previous mouse movement is trumped by focus selection
}
},
_onBlur: function(){
// summary:
// Called when focus is moved away from this Menu and it's submenus.
// tags:
// protected
this._cleanUp();
this.inherited(arguments);
},
_cleanUp: function(){
// summary:
// Called when the user is done with this menu. Closes hierarchy of menus.
// tags:
// private
this._closeChild(); // don't call this.onClose since that's incorrect for MenuBar's that never close
if(typeof this.isShowingNow == 'undefined'){ // non-popup menu doesn't call onClose
this._markInactive();
}
}
});
});

View File

@ -0,0 +1,8 @@
//>>built
define("dijit/_OnDijitClickMixin",["dojo/on","dojo/_base/array","dojo/keys","dojo/_base/declare","dojo/has","dojo/_base/unload","dojo/_base/window","./a11yclick"],function(on,_1,_2,_3,_4,_5,_6,_7){
var _8=_3("dijit._OnDijitClickMixin",null,{connect:function(_9,_a,_b){
return this.inherited(arguments,[_9,_a=="ondijitclick"?_7:_a,_b]);
}});
_8.a11yclick=_7;
return _8;
});

View File

@ -0,0 +1,50 @@
define("dijit/_OnDijitClickMixin", [
"dojo/on",
"dojo/_base/array", // array.forEach
"dojo/keys", // keys.ENTER keys.SPACE
"dojo/_base/declare", // declare
"dojo/has", // has("dom-addeventlistener")
"dojo/_base/unload", // unload.addOnWindowUnload
"dojo/_base/window", // win.doc.addEventListener win.doc.attachEvent win.doc.detachEvent
"./a11yclick"
], function(on, array, keys, declare, has, unload, win, a11yclick){
// module:
// dijit/_OnDijitClickMixin
var ret = declare("dijit._OnDijitClickMixin", null, {
connect: function(
/*Object|null*/ obj,
/*String|Function*/ event,
/*String|Function*/ method){
// summary:
// Connects specified obj/event to specified method of this object
// and registers for disconnect() on widget destroy.
// description:
// Provide widget-specific analog to connect.connect, except with the
// implicit use of this widget as the target object.
// This version of connect also provides a special "ondijitclick"
// event which triggers on a click or space or enter keyup.
// Events connected with `this.connect` are disconnected upon
// destruction.
// returns:
// A handle that can be passed to `disconnect` in order to disconnect before
// the widget is destroyed.
// example:
// | var btn = new Button();
// | // when foo.bar() is called, call the listener we're going to
// | // provide in the scope of btn
// | btn.connect(foo, "bar", function(){
// | console.debug(this.toString());
// | });
// tags:
// protected
return this.inherited(arguments, [obj, event == "ondijitclick" ? a11yclick : event, method]);
}
});
ret.a11yclick = a11yclick; // back compat
return ret;
});

View File

@ -0,0 +1,92 @@
//>>built
define("dijit/_PaletteMixin",["dojo/_base/declare","dojo/dom-attr","dojo/dom-class","dojo/dom-construct","dojo/_base/event","dojo/keys","dojo/_base/lang","./_CssStateMixin","./focus","./typematic"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a){
return _1("dijit._PaletteMixin",[_8],{defaultTimeout:500,timeoutChangeRate:0.9,value:"",_selectedCell:-1,tabIndex:"0",cellClass:"dijitPaletteCell",dyeClass:null,summary:"",_setSummaryAttr:"paletteTableNode",_dyeFactory:function(_b){
var _c=typeof this.dyeClass=="string"?_7.getObject(this.dyeClass):this.dyeClass;
return new _c(_b);
},_preparePalette:function(_d,_e){
this._cells=[];
var _f=this._blankGif;
this.connect(this.gridNode,"ondijitclick","_onCellClick");
for(var row=0;row<_d.length;row++){
var _10=_4.create("tr",{tabIndex:"-1"},this.gridNode);
for(var col=0;col<_d[row].length;col++){
var _11=_d[row][col];
if(_11){
var _12=this._dyeFactory(_11,row,col,_e[_11]);
var _13=_4.create("td",{"class":this.cellClass,tabIndex:"-1",title:_e[_11],role:"gridcell"},_10);
_12.fillCell(_13,_f);
_13.idx=this._cells.length;
this._cells.push({node:_13,dye:_12});
}
}
}
this._xDim=_d[0].length;
this._yDim=_d.length;
var _14={UP_ARROW:-this._xDim,DOWN_ARROW:this._xDim,RIGHT_ARROW:this.isLeftToRight()?1:-1,LEFT_ARROW:this.isLeftToRight()?-1:1};
for(var key in _14){
this.own(_a.addKeyListener(this.domNode,{charOrCode:_6[key],ctrlKey:false,altKey:false,shiftKey:false},this,function(){
var _15=_14[key];
return function(_16){
this._navigateByKey(_15,_16);
};
}(),this.timeoutChangeRate,this.defaultTimeout));
}
},postCreate:function(){
this.inherited(arguments);
this._setCurrent(this._cells[0].node);
},focus:function(){
_9.focus(this._currentFocus);
},_onCellClick:function(evt){
var _17=evt.target;
while(_17.tagName!="TD"){
if(!_17.parentNode||_17==this.gridNode){
return;
}
_17=_17.parentNode;
}
var _18=this._getDye(_17).getValue();
this._setCurrent(_17);
_9.focus(_17);
this._setValueAttr(_18,true);
_5.stop(evt);
},_setCurrent:function(_19){
if("_currentFocus" in this){
_2.set(this._currentFocus,"tabIndex","-1");
}
this._currentFocus=_19;
if(_19){
_2.set(_19,"tabIndex",this.tabIndex);
}
},_setValueAttr:function(_1a,_1b){
if(this._selectedCell>=0){
_3.remove(this._cells[this._selectedCell].node,this.cellClass+"Selected");
}
this._selectedCell=-1;
if(_1a){
for(var i=0;i<this._cells.length;i++){
if(_1a==this._cells[i].dye.getValue()){
this._selectedCell=i;
_3.add(this._cells[i].node,this.cellClass+"Selected");
break;
}
}
}
this._set("value",this._selectedCell>=0?_1a:null);
if(_1b||_1b===undefined){
this.onChange(_1a);
}
},onChange:function(){
},_navigateByKey:function(_1c,_1d){
if(_1d==-1){
return;
}
var _1e=this._currentFocus.idx+_1c;
if(_1e<this._cells.length&&_1e>-1){
var _1f=this._cells[_1e].node;
this._setCurrent(_1f);
this.defer(_7.hitch(_9,"focus",_1f));
}
},_getDye:function(_20){
return this._cells[_20.idx].dye;
}});
});

View File

@ -0,0 +1,340 @@
define("dijit/_PaletteMixin", [
"dojo/_base/declare", // declare
"dojo/dom-attr", // domAttr.set
"dojo/dom-class", // domClass.add domClass.remove
"dojo/dom-construct", // domConstruct.create domConstruct.place
"dojo/_base/event", // event.stop
"dojo/keys", // keys
"dojo/_base/lang", // lang.getObject
"./_CssStateMixin",
"./focus",
"./typematic"
], function(declare, domAttr, domClass, domConstruct, event, keys, lang, _CssStateMixin, focus, typematic){
// module:
// dijit/_PaletteMixin
return declare("dijit._PaletteMixin", [_CssStateMixin], {
// summary:
// A keyboard accessible palette, for picking a color/emoticon/etc.
// description:
// A mixin for a grid showing various entities, so the user can pick a certain entity.
// defaultTimeout: Number
// Number of milliseconds before a held key or button becomes typematic
defaultTimeout: 500,
// timeoutChangeRate: Number
// Fraction of time used to change the typematic timer between events
// 1.0 means that each typematic event fires at defaultTimeout intervals
// Less than 1.0 means that each typematic event fires at an increasing faster rate
timeoutChangeRate: 0.90,
// value: String
// Currently selected color/emoticon/etc.
value: "",
// _selectedCell: [private] Integer
// Index of the currently selected cell. Initially, none selected
_selectedCell: -1,
/*=====
// _currentFocus: [private] DomNode
// The currently focused cell (if the palette itself has focus), or otherwise
// the cell to be focused when the palette itself gets focus.
// Different from value, which represents the selected (i.e. clicked) cell.
_currentFocus: null,
=====*/
/*=====
// _xDim: [protected] Integer
// This is the number of cells horizontally across.
_xDim: null,
=====*/
/*=====
// _yDim: [protected] Integer
// This is the number of cells vertically down.
_yDim: null,
=====*/
// tabIndex: String
// Widget tab index.
tabIndex: "0",
// cellClass: [protected] String
// CSS class applied to each cell in the palette
cellClass: "dijitPaletteCell",
// dyeClass: [protected] Constructor
// Constructor for Object created for each cell of the palette.
// dyeClass should implements dijit.Dye interface
dyeClass: null,
// summary: String
// Localized summary for the palette table
summary: '',
_setSummaryAttr: "paletteTableNode",
_dyeFactory: function(value /*===== , row, col, title =====*/){
// summary:
// Return instance of dijit.Dye for specified cell of palette
// tags:
// extension
// Remove string support for 2.0
var dyeClassObj = typeof this.dyeClass == "string" ? lang.getObject(this.dyeClass) : this.dyeClass;
return new dyeClassObj(value);
},
_preparePalette: function(choices, titles) {
// summary:
// Subclass must call _preparePalette() from postCreate(), passing in the tooltip
// for each cell
// choices: String[][]
// id's for each cell of the palette, used to create Dye JS object for each cell
// titles: String[]
// Localized tooltip for each cell
this._cells = [];
var url = this._blankGif;
this.connect(this.gridNode, "ondijitclick", "_onCellClick");
for(var row=0; row < choices.length; row++){
var rowNode = domConstruct.create("tr", {tabIndex: "-1"}, this.gridNode);
for(var col=0; col < choices[row].length; col++){
var value = choices[row][col];
if(value){
var cellObject = this._dyeFactory(value, row, col, titles[value]);
var cellNode = domConstruct.create("td", {
"class": this.cellClass,
tabIndex: "-1",
title: titles[value],
role: "gridcell"
}, rowNode);
// prepare cell inner structure
cellObject.fillCell(cellNode, url);
cellNode.idx = this._cells.length;
// save cell info into _cells
this._cells.push({node:cellNode, dye:cellObject});
}
}
}
this._xDim = choices[0].length;
this._yDim = choices.length;
// Now set all events
// The palette itself is navigated to with the tab key on the keyboard
// Keyboard navigation within the Palette is with the arrow keys
// Spacebar selects the cell.
// For the up key the index is changed by negative the x dimension.
var keyIncrementMap = {
UP_ARROW: -this._xDim,
// The down key the index is increase by the x dimension.
DOWN_ARROW: this._xDim,
// Right and left move the index by 1.
RIGHT_ARROW: this.isLeftToRight() ? 1 : -1,
LEFT_ARROW: this.isLeftToRight() ? -1 : 1
};
for(var key in keyIncrementMap){
this.own(
typematic.addKeyListener(
this.domNode,
{charOrCode:keys[key], ctrlKey:false, altKey:false, shiftKey:false},
this,
function(){
var increment = keyIncrementMap[key];
return function(count){ this._navigateByKey(increment, count); };
}(),
this.timeoutChangeRate,
this.defaultTimeout
)
);
}
},
postCreate: function(){
this.inherited(arguments);
// Set initial navigable node.
this._setCurrent(this._cells[0].node);
},
focus: function(){
// summary:
// Focus this widget. Puts focus on the most recently focused cell.
// The cell already has tabIndex set, just need to set CSS and focus it
focus.focus(this._currentFocus);
},
_onCellClick: function(/*Event*/ evt){
// summary:
// Handler for click, enter key & space key. Selects the cell.
// evt:
// The event.
// tags:
// private
var target = evt.target;
// Find TD associated with click event. For ColorPalette user likely clicked IMG inside of TD
while(target.tagName != "TD"){
if(!target.parentNode || target == this.gridNode){ // probably can never happen, but just in case
return;
}
target = target.parentNode;
}
var value = this._getDye(target).getValue();
// First focus the clicked cell, and then send onChange() notification.
// onChange() (via _setValueAttr) must be after the focus call, because
// it may trigger a refocus to somewhere else (like the Editor content area), and that
// second focus should win.
this._setCurrent(target);
focus.focus(target);
this._setValueAttr(value, true);
event.stop(evt);
},
_setCurrent: function(/*DomNode*/ node){
// summary:
// Sets which node is the focused cell.
// description:
// At any point in time there's exactly one
// cell with tabIndex != -1. If focus is inside the palette then
// focus is on that cell.
//
// After calling this method, arrow key handlers and mouse click handlers
// should focus the cell in a setTimeout().
// tags:
// protected
if("_currentFocus" in this){
// Remove tabIndex on old cell
domAttr.set(this._currentFocus, "tabIndex", "-1");
}
// Set tabIndex of new cell
this._currentFocus = node;
if(node){
domAttr.set(node, "tabIndex", this.tabIndex);
}
},
_setValueAttr: function(value, priorityChange){
// summary:
// This selects a cell. It triggers the onChange event.
// value: String
// Value of the cell to select
// tags:
// protected
// priorityChange: Boolean?
// Optional parameter used to tell the select whether or not to fire
// onChange event.
// clear old selected cell
if(this._selectedCell >= 0){
domClass.remove(this._cells[this._selectedCell].node, this.cellClass + "Selected");
}
this._selectedCell = -1;
// search for cell matching specified value
if(value){
for(var i = 0; i < this._cells.length; i++){
if(value == this._cells[i].dye.getValue()){
this._selectedCell = i;
domClass.add(this._cells[i].node, this.cellClass + "Selected");
break;
}
}
}
// record new value, or null if no matching cell
this._set("value", this._selectedCell >= 0 ? value : null);
if(priorityChange || priorityChange === undefined){
this.onChange(value);
}
},
onChange: function(/*===== value =====*/){
// summary:
// Callback when a cell is selected.
// value: String
// Value corresponding to cell.
},
_navigateByKey: function(increment, typeCount){
// summary:
// This is the callback for typematic.
// It changes the focus and the highlighed cell.
// increment:
// How much the key is navigated.
// typeCount:
// How many times typematic has fired.
// tags:
// private
// typecount == -1 means the key is released.
if(typeCount == -1){ return; }
var newFocusIndex = this._currentFocus.idx + increment;
if(newFocusIndex < this._cells.length && newFocusIndex > -1){
var focusNode = this._cells[newFocusIndex].node;
this._setCurrent(focusNode);
// Actually focus the node, for the benefit of screen readers.
// Use defer because IE doesn't like changing focus inside of an event handler
this.defer(lang.hitch(focus, "focus", focusNode));
}
},
_getDye: function(/*DomNode*/ cell){
// summary:
// Get JS object for given cell DOMNode
return this._cells[cell.idx].dye;
}
});
/*=====
declare("dijit.Dye",
null,
{
// summary:
// Interface for the JS Object associated with a palette cell (i.e. DOMNode)
constructor: function(alias, row, col){
// summary:
// Initialize according to value or alias like "white"
// alias: String
},
getValue: function(){
// summary:
// Return "value" of cell; meaning of "value" varies by subclass.
// description:
// For example color hex value, emoticon ascii value etc, entity hex value.
},
fillCell: function(cell, blankGif){
// summary:
// Add cell DOMNode inner structure
// cell: DomNode
// The surrounding cell
// blankGif: String
// URL for blank cell image
}
}
);
=====*/
});

View File

@ -0,0 +1,27 @@
//>>built
define("dijit/_Templated",["./_WidgetBase","./_TemplatedMixin","./_WidgetsInTemplateMixin","dojo/_base/array","dojo/_base/declare","dojo/_base/lang","dojo/_base/kernel"],function(_1,_2,_3,_4,_5,_6,_7){
_6.extend(_1,{waiRole:"",waiState:""});
return _5("dijit._Templated",[_2,_3],{widgetsInTemplate:false,constructor:function(){
_7.deprecated(this.declaredClass+": dijit._Templated deprecated, use dijit._TemplatedMixin and if necessary dijit._WidgetsInTemplateMixin","","2.0");
},_attachTemplateNodes:function(_8,_9){
this.inherited(arguments);
var _a=_6.isArray(_8)?_8:(_8.all||_8.getElementsByTagName("*"));
var x=_6.isArray(_8)?0:-1;
for(;x<_a.length;x++){
var _b=(x==-1)?_8:_a[x];
var _c=_9(_b,"waiRole");
if(_c){
_b.setAttribute("role",_c);
}
var _d=_9(_b,"waiState");
if(_d){
_4.forEach(_d.split(/\s*,\s*/),function(_e){
if(_e.indexOf("-")!=-1){
var _f=_e.split("-");
_b.setAttribute("aria-"+_f[0],_f[1]);
}
});
}
}
}});
});

View File

@ -0,0 +1,64 @@
define("dijit/_Templated", [
"./_WidgetBase",
"./_TemplatedMixin",
"./_WidgetsInTemplateMixin",
"dojo/_base/array", // array.forEach
"dojo/_base/declare", // declare
"dojo/_base/lang", // lang.extend lang.isArray
"dojo/_base/kernel" // kernel.deprecated
], function(_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, array, declare, lang, kernel){
// module:
// dijit/_Templated
// These arguments can be specified for widgets which are used in templates.
// Since any widget can be specified as sub widgets in template, mix it
// into the base widget class. (This is a hack, but it's effective.)
// Remove for 2.0. Also, hide from API doc parser.
lang.extend(_WidgetBase, /*===== {} || =====*/ {
waiRole: "",
waiState:""
});
return declare("dijit._Templated", [_TemplatedMixin, _WidgetsInTemplateMixin], {
// summary:
// Deprecated mixin for widgets that are instantiated from a template.
// Widgets should use _TemplatedMixin plus if necessary _WidgetsInTemplateMixin instead.
// widgetsInTemplate: [protected] Boolean
// Should we parse the template to find widgets that might be
// declared in markup inside it? False by default.
widgetsInTemplate: false,
constructor: function(){
kernel.deprecated(this.declaredClass + ": dijit._Templated deprecated, use dijit._TemplatedMixin and if necessary dijit._WidgetsInTemplateMixin", "", "2.0");
},
_attachTemplateNodes: function(rootNode, getAttrFunc){
this.inherited(arguments);
// Do deprecated waiRole and waiState
var nodes = lang.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*"));
var x = lang.isArray(rootNode) ? 0 : -1;
for(; x<nodes.length; x++){
var baseNode = (x == -1) ? rootNode : nodes[x];
// waiRole, waiState
var role = getAttrFunc(baseNode, "waiRole");
if(role){
baseNode.setAttribute("role", role);
}
var values = getAttrFunc(baseNode, "waiState");
if(values){
array.forEach(values.split(/\s*,\s*/), function(stateValue){
if(stateValue.indexOf('-') != -1){
var pair = stateValue.split('-');
baseNode.setAttribute("aria-"+pair[0], pair[1]);
}
});
}
}
}
});
});

View File

@ -0,0 +1,140 @@
//>>built
define("dijit/_TemplatedMixin",["dojo/_base/lang","dojo/touch","./_WidgetBase","dojo/string","dojo/cache","dojo/_base/array","dojo/_base/declare","dojo/dom-construct","dojo/sniff","dojo/_base/unload"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a){
var _b=_7("dijit._TemplatedMixin",null,{templateString:null,templatePath:null,_skipNodeCache:false,_earlyTemplatedStartup:false,constructor:function(){
this._attachPoints=[];
this._attachEvents=[];
},_stringRepl:function(_c){
var _d=this.declaredClass,_e=this;
return _4.substitute(_c,this,function(_f,key){
if(key.charAt(0)=="!"){
_f=_1.getObject(key.substr(1),false,_e);
}
if(typeof _f=="undefined"){
throw new Error(_d+" template:"+key);
}
if(_f==null){
return "";
}
return key.charAt(0)=="!"?_f:_f.toString().replace(/"/g,"&quot;");
},this);
},buildRendering:function(){
if(!this.templateString){
this.templateString=_5(this.templatePath,{sanitize:true});
}
var _10=_b.getCachedTemplate(this.templateString,this._skipNodeCache,this.ownerDocument);
var _11;
if(_1.isString(_10)){
_11=_8.toDom(this._stringRepl(_10),this.ownerDocument);
if(_11.nodeType!=1){
throw new Error("Invalid template: "+_10);
}
}else{
_11=_10.cloneNode(true);
}
this.domNode=_11;
this.inherited(arguments);
this._attachTemplateNodes(_11,function(n,p){
return n.getAttribute(p);
});
this._beforeFillContent();
this._fillContent(this.srcNodeRef);
},_beforeFillContent:function(){
},_fillContent:function(_12){
var _13=this.containerNode;
if(_12&&_13){
while(_12.hasChildNodes()){
_13.appendChild(_12.firstChild);
}
}
},_attachTemplateNodes:function(_14,_15){
var _16=_1.isArray(_14)?_14:(_14.all||_14.getElementsByTagName("*"));
var x=_1.isArray(_14)?0:-1;
for(;x<0||_16[x];x++){
var _17=(x==-1)?_14:_16[x];
if(this.widgetsInTemplate&&(_15(_17,"dojoType")||_15(_17,"data-dojo-type"))){
continue;
}
var _18=_15(_17,"dojoAttachPoint")||_15(_17,"data-dojo-attach-point");
if(_18){
var _19,_1a=_18.split(/\s*,\s*/);
while((_19=_1a.shift())){
if(_1.isArray(this[_19])){
this[_19].push(_17);
}else{
this[_19]=_17;
}
this._attachPoints.push(_19);
}
}
var _1b=_15(_17,"dojoAttachEvent")||_15(_17,"data-dojo-attach-event");
if(_1b){
var _1c,_1d=_1b.split(/\s*,\s*/);
var _1e=_1.trim;
while((_1c=_1d.shift())){
if(_1c){
var _1f=null;
if(_1c.indexOf(":")!=-1){
var _20=_1c.split(":");
_1c=_1e(_20[0]);
_1f=_1e(_20[1]);
}else{
_1c=_1e(_1c);
}
if(!_1f){
_1f=_1c;
}
this._attachEvents.push(this.connect(_17,_2[_1c]||_1c,_1f));
}
}
}
}
},destroyRendering:function(){
_6.forEach(this._attachPoints,function(_21){
delete this[_21];
},this);
this._attachPoints=[];
_6.forEach(this._attachEvents,this.disconnect,this);
this._attachEvents=[];
this.inherited(arguments);
}});
_b._templateCache={};
_b.getCachedTemplate=function(_22,_23,doc){
var _24=_b._templateCache;
var key=_22;
var _25=_24[key];
if(_25){
try{
if(!_25.ownerDocument||_25.ownerDocument==(doc||document)){
return _25;
}
}
catch(e){
}
_8.destroy(_25);
}
_22=_4.trim(_22);
if(_23||_22.match(/\$\{([^\}]+)\}/g)){
return (_24[key]=_22);
}else{
var _26=_8.toDom(_22,doc);
if(_26.nodeType!=1){
throw new Error("Invalid template: "+_22);
}
return (_24[key]=_26);
}
};
if(_9("ie")){
_a.addOnWindowUnload(function(){
var _27=_b._templateCache;
for(var key in _27){
var _28=_27[key];
if(typeof _28=="object"){
_8.destroy(_28);
}
delete _27[key];
}
});
}
_1.extend(_3,{dojoAttachEvent:"",dojoAttachPoint:""});
return _b;
});

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