Merge remote-tracking branch 'upstream/master'

master
Richard Beales 12 years ago
commit 7c97d17aaf

@ -24,6 +24,7 @@ div.cdmHeader span.updated {
font-weight : normal; font-weight : normal;
font-size : 11px; font-size : 11px;
white-space : nowrap; white-space : nowrap;
vertical-align : middle;
} }
div.cdmHeader input { div.cdmHeader input {

@ -109,10 +109,10 @@ class API extends Handler {
function getFeeds() { function getFeeds() {
$cat_id = db_escape_string($_REQUEST["cat_id"]); $cat_id = db_escape_string($_REQUEST["cat_id"]);
$unread_only = (bool)db_escape_string($_REQUEST["unread_only"]); $unread_only = sql_bool_to_bool($_REQUEST["unread_only"]);
$limit = (int) db_escape_string($_REQUEST["limit"]); $limit = (int) db_escape_string($_REQUEST["limit"]);
$offset = (int) db_escape_string($_REQUEST["offset"]); $offset = (int) db_escape_string($_REQUEST["offset"]);
$include_nested = (bool)db_escape_string($_REQUEST["include_nested"]); $include_nested = sql_bool_to_bool($_REQUEST["include_nested"]);
$feeds = $this->api_get_feeds($this->link, $cat_id, $unread_only, $limit, $offset, $include_nested); $feeds = $this->api_get_feeds($this->link, $cat_id, $unread_only, $limit, $offset, $include_nested);
@ -120,8 +120,8 @@ class API extends Handler {
} }
function getCategories() { function getCategories() {
$unread_only = (bool)db_escape_string($_REQUEST["unread_only"]); $unread_only = sql_bool_to_bool($_REQUEST["unread_only"]);
$enable_nested = (bool)db_escape_string($_REQUEST["enable_nested"]); $enable_nested = sql_bool_to_bool($_REQUEST["enable_nested"]);
// TODO do not return empty categories, return Uncategorized and standard virtual cats // TODO do not return empty categories, return Uncategorized and standard virtual cats
@ -180,14 +180,14 @@ class API extends Handler {
$offset = (int)db_escape_string($_REQUEST["skip"]); $offset = (int)db_escape_string($_REQUEST["skip"]);
$filter = db_escape_string($_REQUEST["filter"]); $filter = db_escape_string($_REQUEST["filter"]);
$is_cat = (bool)db_escape_string($_REQUEST["is_cat"]); $is_cat = sql_bool_to_bool($_REQUEST["is_cat"]);
$show_excerpt = (bool)db_escape_string($_REQUEST["show_excerpt"]); $show_excerpt = sql_bool_to_bool($_REQUEST["show_excerpt"]);
$show_content = (bool)db_escape_string($_REQUEST["show_content"]); $show_content = sql_bool_to_bool($_REQUEST["show_content"]);
/* all_articles, unread, adaptive, marked, updated */ /* all_articles, unread, adaptive, marked, updated */
$view_mode = db_escape_string($_REQUEST["view_mode"]); $view_mode = db_escape_string($_REQUEST["view_mode"]);
$include_attachments = (bool)db_escape_string($_REQUEST["include_attachments"]); $include_attachments = sql_bool_to_bool($_REQUEST["include_attachments"]);
$since_id = (int)db_escape_string($_REQUEST["since_id"]); $since_id = (int)db_escape_string($_REQUEST["since_id"]);
$include_nested = (bool)db_escape_string($_REQUEST["include_nested"]); $include_nested = sql_bool_to_bool($_REQUEST["include_nested"]);
$sanitize_content = true; $sanitize_content = true;
/* do not rely on params below */ /* do not rely on params below */
@ -219,12 +219,15 @@ class API extends Handler {
switch ($field_raw) { switch ($field_raw) {
case 0: case 0:
$field = "marked"; $field = "marked";
$additional_fields = ",last_marked = NOW()";
break; break;
case 1: case 1:
$field = "published"; $field = "published";
$additional_fields = ",last_published = NOW()";
break; break;
case 2: case 2:
$field = "unread"; $field = "unread";
$additional_fields = ",last_read = NOW()";
break; break;
case 3: case 3:
$field = "note"; $field = "note";
@ -248,14 +251,7 @@ class API extends Handler {
$article_ids = join(", ", $article_ids); $article_ids = join(", ", $article_ids);
if ($field == "unread") { $result = db_query($this->link, "UPDATE ttrss_user_entries SET $field = $set_to $additional_fields WHERE ref_id IN ($article_ids) AND owner_uid = " . $_SESSION["uid"]);
$result = db_query($this->link, "UPDATE ttrss_user_entries SET $field = $set_to,
last_read = NOW()
WHERE ref_id IN ($article_ids) AND owner_uid = " . $_SESSION["uid"]);
} else {
$result = db_query($this->link, "UPDATE ttrss_user_entries SET $field = $set_to
WHERE ref_id IN ($article_ids) AND owner_uid = " . $_SESSION["uid"]);
}
$num_updated = db_affected_rows($this->link, $result); $num_updated = db_affected_rows($this->link, $result);
@ -268,6 +264,17 @@ class API extends Handler {
} }
} }
if ($num_updated > 0 && $field == "published") {
if (PUBSUBHUBBUB_HUB) {
$rss_link = get_self_url_prefix() .
"/public.php?op=rss&id=-2&key=" .
get_feed_access_key($this->link, -2, false);
$p = new Publisher(PUBSUBHUBBUB_HUB);
$pubsub_result = $p->publish_update($rss_link);
}
}
print $this->wrap(self::STATUS_OK, array("status" => "OK", print $this->wrap(self::STATUS_OK, array("status" => "OK",
"updated" => $num_updated)); "updated" => $num_updated));

@ -446,10 +446,10 @@ class Feeds extends Handler_Protected {
$reply['content'] .= "<span class=\"hlUpdated\">"; $reply['content'] .= "<span class=\"hlUpdated\">";
if (@$line["feed_title"]) { if (@$line["feed_title"]) {
$reply['content'] .= "<span class=\"hlFeed\"> $reply['content'] .= "<div class=\"hlFeed\">
<a href=\"#\" onclick=\"viewfeed($feed_id)\">". <a href=\"#\" onclick=\"viewfeed($feed_id)\">".
$line["feed_title"]."</a><br/> $line["feed_title"]."</a>
</span>"; </div>";
} }
$reply['content'] .= "$updated_fmt</span>"; $reply['content'] .= "$updated_fmt</span>";

@ -372,7 +372,7 @@ class Pref_Filters extends Handler_Protected {
WHERE id = ".(int)$rule["filter_type"]); WHERE id = ".(int)$rule["filter_type"]);
$match_on = db_fetch_result($result, 0, "description"); $match_on = db_fetch_result($result, 0, "description");
return T_sprintf("%s on %s in %s", $rule["reg_exp"], $match_on, $feed); return T_sprintf("%s on %s in %s", strip_tags($rule["reg_exp"]), $match_on, $feed);
} }
function printRuleName() { function printRuleName() {

@ -140,7 +140,8 @@ class RPC extends Handler_Protected {
$mark = "false"; $mark = "false";
} }
$result = db_query($this->link, "UPDATE ttrss_user_entries SET marked = $mark $result = db_query($this->link, "UPDATE ttrss_user_entries SET marked = $mark,
last_marked = NOW()
WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]); WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]);
print json_encode(array("message" => "UPDATE_COUNTERS")); print json_encode(array("message" => "UPDATE_COUNTERS"));
@ -219,7 +220,7 @@ class RPC extends Handler_Protected {
} }
$result = db_query($this->link, "UPDATE ttrss_user_entries SET $result = db_query($this->link, "UPDATE ttrss_user_entries SET
published = $pub, last_read = NOW() published = $pub, last_published = NOW()
WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]); WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]);
$pubsub_result = false; $pubsub_result = false;
@ -779,15 +780,15 @@ class RPC extends Handler_Protected {
if ($cmode == 0) { if ($cmode == 0) {
db_query($link, "UPDATE ttrss_user_entries SET db_query($link, "UPDATE ttrss_user_entries SET
marked = false,last_read = NOW() marked = false, last_marked = NOW()
WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]); WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
} else if ($cmode == 1) { } else if ($cmode == 1) {
db_query($link, "UPDATE ttrss_user_entries SET db_query($link, "UPDATE ttrss_user_entries SET
marked = true marked = true, last_marked = NOW()
WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]); WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
} else { } else {
db_query($link, "UPDATE ttrss_user_entries SET db_query($link, "UPDATE ttrss_user_entries SET
marked = NOT marked,last_read = NOW() marked = NOT marked,last_marked = NOW()
WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]); WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
} }
} }
@ -804,15 +805,15 @@ class RPC extends Handler_Protected {
if ($cmode == 0) { if ($cmode == 0) {
db_query($link, "UPDATE ttrss_user_entries SET db_query($link, "UPDATE ttrss_user_entries SET
published = false,last_read = NOW() published = false,last_published = NOW()
WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]); WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
} else if ($cmode == 1) { } else if ($cmode == 1) {
db_query($link, "UPDATE ttrss_user_entries SET db_query($link, "UPDATE ttrss_user_entries SET
published = true,last_read = NOW() published = true,last_published = NOW()
WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]); WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
} else { } else {
db_query($link, "UPDATE ttrss_user_entries SET db_query($link, "UPDATE ttrss_user_entries SET
published = NOT published,last_read = NOW() published = NOT published,last_published = NOW()
WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]); WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
} }

@ -1,6 +1,6 @@
<?php <?php
define('EXPECTED_CONFIG_VERSION', 26); define('EXPECTED_CONFIG_VERSION', 26);
define('SCHEMA_VERSION', 104); define('SCHEMA_VERSION', 105);
$fetch_last_error = false; $fetch_last_error = false;
$pluginhost = false; $pluginhost = false;
@ -852,7 +852,7 @@
} }
function sql_bool_to_bool($s) { function sql_bool_to_bool($s) {
if ($s == "t" || $s == "1" || $s == "true") { if ($s == "t" || $s == "1" || strtolower($s) == "true") {
return true; return true;
} else { } else {
return false; return false;
@ -2310,6 +2310,8 @@
$vfeed_query_part = "ttrss_feeds.title AS feed_title,"; $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
$allow_archived = true; $allow_archived = true;
if (!$override_order) $override_order = "last_marked DESC, updated DESC";
} else if ($feed == -2) { // published virtual feed OR labels category } else if ($feed == -2) { // published virtual feed OR labels category
if (!$cat_view) { if (!$cat_view) {
@ -2317,7 +2319,7 @@
$vfeed_query_part = "ttrss_feeds.title AS feed_title,"; $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
$allow_archived = true; $allow_archived = true;
if (!$override_order) $override_order = "last_read DESC, updated DESC"; if (!$override_order) $override_order = "last_published DESC, updated DESC";
} else { } else {
$vfeed_query_part = "ttrss_feeds.title AS feed_title,"; $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
@ -2450,6 +2452,7 @@
comments, comments,
int_id, int_id,
unread,feed_id,marked,published,link,last_read,orig_feed_id, unread,feed_id,marked,published,link,last_read,orig_feed_id,
last_marked, last_published,
".SUBSTRING_FOR_DATE."(last_read,1,19) as last_read_noms, ".SUBSTRING_FOR_DATE."(last_read,1,19) as last_read_noms,
$vfeed_query_part $vfeed_query_part
$content_query_part $content_query_part
@ -2492,6 +2495,7 @@
"label_cache," . "label_cache," .
"link," . "link," .
"last_read," . "last_read," .
"last_marked, last_published, " .
SUBSTRING_FOR_DATE . "(last_read,1,19) as last_read_noms," . SUBSTRING_FOR_DATE . "(last_read,1,19) as last_read_noms," .
$since_id_part . $since_id_part .
$vfeed_query_part . $vfeed_query_part .
@ -2551,10 +2555,6 @@
$res = trim($str); if (!$res) return ''; $res = trim($str); if (!$res) return '';
$config = array('safe' => 1, 'deny_attribute' => 'style, width, height, class, id', 'comment' => 1, 'cdata' => 1, 'balance' => 0);
$spec = 'img=width,height';
$res = htmLawed($res, $config, $spec);
if (get_pref($link, "STRIP_IMAGES", $owner)) { if (get_pref($link, "STRIP_IMAGES", $owner)) {
$res = preg_replace('/<img[^>]+>/is', '', $res); $res = preg_replace('/<img[^>]+>/is', '', $res);
} }
@ -2595,9 +2595,16 @@
} }
} }
$node = $doc->getElementsByTagName('body')->item(0); //$node = $doc->getElementsByTagName('body')->item(0);
$doc->removeChild($doc->firstChild); //remove doctype
$res = $doc->saveHTML();
return $doc->saveXML($node); $config = array('safe' => 1, 'deny_attribute' => 'style, width, height, class, id', 'comment' => 1, 'cdata' => 1, 'balance' => 0);
$spec = 'img=width,height';
$res = htmLawed($res, $config, $spec);
return $res;
} }
function check_for_update($link) { function check_for_update($link) {
@ -3900,4 +3907,32 @@
return in_array($interface, class_implements($class)); return in_array($interface, class_implements($class));
} }
function get_minified_js($files) {
require_once 'lib/jshrink/Minifier.php';
$rv = '';
foreach ($files as $js) {
if (!isset($_GET['debug'])) {
$cached_file = CACHE_DIR . "/js/$js.js";
if (file_exists($cached_file) &&
is_readable($cached_file) &&
filemtime($cached_file) >= filemtime("js/$js.js")) {
$rv .= file_get_contents($cached_file);
} else {
$minified = JShrink\Minifier::minify(file_get_contents("js/$js.js"));
file_put_contents($cached_file, $minified);
$rv .= $minified;
}
} else {
$rv .= file_get_contents("js/$js.js");
}
}
return $rv;
}
?> ?>

@ -1,4 +1,4 @@
<?php # This file has been generated at: Sun Feb 17 13:58:53 MSK 2013 <?php # This file has been generated at: Sun Mar 17 19:37:50 MSK 2013
__("Title"); __("Title");
__("Title or Content"); __("Title or Content");
@ -54,7 +54,7 @@ __('Automatically expand articles in combined mode');
__('Purge unread articles'); __('Purge unread articles');
__('Show special feeds when hiding read feeds'); __('Show special feeds when hiding read feeds');
__('Group headlines in virtual feeds'); __('Group headlines in virtual feeds');
__('Do not show images in articles'); __('Hide images in articles');
__('Enable external API'); __('Enable external API');
__('User timezone'); __('User timezone');
__('Customize stylesheet'); __('Customize stylesheet');

@ -766,12 +766,17 @@
} }
} }
$last_marked = ($marked == 'true') ? 'NOW()' : 'NULL';
$last_published = ($published == 'true') ? 'NOW()' : 'NULL';
$result = db_query($link, $result = db_query($link,
"INSERT INTO ttrss_user_entries "INSERT INTO ttrss_user_entries
(ref_id, owner_uid, feed_id, unread, last_read, marked, (ref_id, owner_uid, feed_id, unread, last_read, marked,
published, score, tag_cache, label_cache, uuid) published, score, tag_cache, label_cache, uuid,
last_marked, last_published)
VALUES ('$ref_id', '$owner_uid', '$feed', $unread, VALUES ('$ref_id', '$owner_uid', '$feed', $unread,
$last_read_qpart, $marked, $published, '$score', '', '', '')"); $last_read_qpart, $marked, $published, '$score', '', '',
'', $last_marked, $last_published)");
if (PUBSUBHUBBUB_HUB && $published == 'true') { if (PUBSUBHUBBUB_HUB && $published == 'true') {
$rss_link = get_self_url_prefix() . $rss_link = get_self_url_prefix() .

@ -36,6 +36,10 @@
array_push($errors, "Data export cache is not writable (chmod -R 777 ".CACHE_DIR."/export)"); array_push($errors, "Data export cache is not writable (chmod -R 777 ".CACHE_DIR."/export)");
} }
if (!is_writable(CACHE_DIR . "/js")) {
array_push($errors, "Javascript cache is not writable (chmod -R 777 ".CACHE_DIR."/js)");
}
if (GENERATED_CONFIG_CHECK != EXPECTED_CONFIG_VERSION) { if (GENERATED_CONFIG_CHECK != EXPECTED_CONFIG_VERSION) {
array_push($errors, array_push($errors,
"Configuration option checker sanity_config.php is outdated, please recreate it using ./utils/regen_config_checks.sh"); "Configuration option checker sanity_config.php is outdated, please recreate it using ./utils/regen_config_checks.sh");
@ -117,6 +121,10 @@
array_push($errors, "PHP support for ctype functions are required by HTMLPurifier."); array_push($errors, "PHP support for ctype functions are required by HTMLPurifier.");
} }
if (!function_exists("iconv")) {
array_push($errors, "PHP support for iconv is required to handle multiple charsets.");
}
if (ini_get("safe_mode")) { if (ini_get("safe_mode")) {
array_push($errors, "PHP safe mode setting is not supported."); array_push($errors, "PHP safe mode setting is not supported.");
} }

@ -62,8 +62,15 @@
<?php print_user_stylesheet($link) ?> <?php print_user_stylesheet($link) ?>
<script type="text/javascript"> <style type="text/css">
</script> <?php
foreach ($pluginhost->get_plugins() as $n => $p) {
if (method_exists($p, "get_css")) {
echo $p->get_css();
}
}
?>
</style>
<link rel="shortcut icon" type="image/png" href="images/favicon.png"/> <link rel="shortcut icon" type="image/png" href="images/favicon.png"/>
@ -78,23 +85,19 @@
<script type="text/javascript"> <script type="text/javascript">
<?php <?php
require 'lib/jsmin.php'; require 'lib/jshrink/Minifier.php';
global $pluginhost; global $pluginhost;
foreach ($pluginhost->get_plugins() as $n => $p) { foreach ($pluginhost->get_plugins() as $n => $p) {
if (method_exists($p, "get_js")) { if (method_exists($p, "get_js")) {
echo JSMin::minify($p->get_js()); echo JShrink\Minifier::minify($p->get_js());
} }
} }
foreach (array("tt-rss", "functions", "feedlist", "viewfeed", "FeedTree") as $js) { print get_minified_js(array("tt-rss",
if (!isset($_GET['debug'])) { "functions", "feedlist", "viewfeed", "FeedTree"));
echo JSMin::minify(file_get_contents("js/$js.js"));
} else {
echo file_get_contents("js/$js.js");
}
}
?> ?>
</script> </script>

@ -964,6 +964,8 @@ function createNewRuleElement(parentNode, replaceNode) {
try { try {
var form = document.forms["filter_new_rule_form"]; var form = document.forms["filter_new_rule_form"];
form.reg_exp.value = form.reg_exp.value.replace(/(<([^>]+)>)/ig,"");
var query = "backend.php?op=pref-filters&method=printrulename&rule="+ var query = "backend.php?op=pref-filters&method=printrulename&rule="+
param_escape(dojo.formToJson(form)); param_escape(dojo.formToJson(form));

@ -1,2 +1,2 @@
//>>built //>>built
define("dijit/BackgroundIframe",["require",".","dojo/_base/config","dojo/dom-construct","dojo/dom-style","dojo/_base/lang","dojo/on","dojo/_base/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;}); 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;});

@ -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;
});

@ -1,2 +1,2 @@
//>>built //>>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/_base/sniff","./CalendarLite","./_Widget","./_CssStateMixin","./_TemplatedMixin","./form/DropDownButton","./hccss"],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);},buildRendering:function(){this.inherited(arguments);this.connect(this.domNode,"onkeypress","_onKeyPress");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){this._setCurrentFocusAttr(this.dateFuncObj.add(this.currentFocus,"month",_13-this.currentFocus.getMonth()));},_onDayMouseOver:function(evt){var _14=_6.contains(evt.target,"dijitCalendarDateLabel")?evt.target.parentNode:evt.target;if(_14&&((_14.dijitDateValue&&!_6.contains(_14,"dijitCalendarDisabledDate"))||_14==this.previousYearLabelNode||_14==this.nextYearLabelNode)){_6.add(_14,"dijitCalendarHoveredDate");this._currentNode=_14;}},_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 _15=evt.target.parentNode;if(_15&&_15.dijitDateValue&&!_6.contains(_15,"dijitCalendarDisabledDate")){_6.add(_15,"dijitCalendarActiveDate");this._currentNode=_15;}},_onDayMouseUp:function(evt){var _16=evt.target.parentNode;if(_16&&_16.dijitDateValue){_6.remove(_16,"dijitCalendarActiveDate");}},handleKey:function(evt){var _17=-1,_18,_19=this.currentFocus;switch(evt.charOrCode){case _9.RIGHT_ARROW:_17=1;case _9.LEFT_ARROW:_18="day";if(!this.isLeftToRight()){_17*=-1;}break;case _9.DOWN_ARROW:_17=1;case _9.UP_ARROW:_18="week";break;case _9.PAGE_DOWN:_17=1;case _9.PAGE_UP:_18=evt.ctrlKey||evt.altKey?"year":"month";break;case _9.END:_19=this.dateFuncObj.add(_19,"month",1);_18="day";case _9.HOME:_19=new this.dateClassObj(_19);_19.setDate(1);break;case _9.ENTER:case " ":this.set("value",this.currentFocus);break;default:return true;}if(_18){_19=this.dateFuncObj.add(_19,_18,_17);}this._setCurrentFocusAttr(_19);return false;},_onKeyPress:function(evt){if(!this.handleKey(evt)){_7.stop(evt);}},onValueSelected:function(){},onChange:function(_1a){this.onValueSelected(_1a);},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(_1b){var _1c=this.dateLocaleModule.getNames("months","wide","standAlone",this.lang,_1b);this.dropDown.set("months",_1c);this.containerNode.innerHTML=(_b("ie")==6?"":"<div class='dijitSpacer'>"+this.dropDown.domNode.innerHTML+"</div>")+"<div class='dijitCalendarMonthLabel dijitCalendarCurrentMonthLabel'>"+_1c[_1b.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(_1d){this.domNode.innerHTML=_1.map(_1d,function(_1e,idx){return _1e?"<div class='dijitCalendarMonthLabel' month='"+idx+"'>"+_1e+"</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;}); 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;});

@ -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;
});

File diff suppressed because one or more lines are too long

@ -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;
});

@ -1,2 +1,2 @@
//>>built //>>built
require({cache:{"url:dijit/templates/CheckedMenuItem.html":"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitemcheckbox\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\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);this._set("checked",_5);},iconClass:"",onChange:function(){},_onClick:function(e){if(!this.disabled){this.set("checked",!this.checked);this.onChange(this.checked);}this.inherited(arguments);}});}); 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);}});});

@ -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);
}
});
});

@ -1,2 +1,2 @@
//>>built //>>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","dojo/i18n","dojo/_base/Color","dojo/_base/declare","dojo/dom-class","dojo/dom-construct","dojo/_base/window","dojo/string","dojo/i18n!dojo/nls/colors","dojo/colors"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c){var _d=_8("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(_e,_f,col){return new this._dyeClass(_e,_f,col);},buildRendering:function(){this.inherited(arguments);this._dyeClass=_8(_d._Color,{hc:_9.contains(_b.body(),"dijit_a11y"),palette:this.palette});this._preparePalette(this._palettes[this.palette],_6.getLocalization("dojo","colors",this.lang));}});_d._Color=_8("dijit._Color",_7,{template:"<span class='dijitInline dijitPaletteImg'>"+"<img src='${blankGif}' alt='${alt}' 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}' 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(_10,row,col){this._alias=_10;this._row=row;this._col=col;this.setColor(_7.named[_10]);},getValue:function(){return this.toHex();},fillCell:function(_11,_12){var _13=_c.substitute(this.hc?this.hcTemplate:this.template,{color:this.toHex(),blankGif:_12,alt:this._alias,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(_13,_11);}});return _d;}); 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;});

@ -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;
});

@ -1,2 +1,2 @@
//>>built //>>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);}});this.mixins=this.mixins.length?_1.map(this.mixins,function(_11){return _4.getObject(_11);}):[_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);});}});}); 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);});}});});

@ -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);
});
}
});
});

@ -0,0 +1,2 @@
//>>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;}});});

@ -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
}
});
});

File diff suppressed because one or more lines are too long

@ -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;
});

@ -1,2 +1,2 @@
//>>built //>>built
define("dijit/DialogUnderlay",["dojo/_base/declare","dojo/dom-attr","dojo/_base/window","dojo/window","./_Widget","./_TemplatedMixin","./BackgroundIframe"],function(_1,_2,_3,_4,_5,_6,_7){return _1("dijit.DialogUnderlay",[_5,_6],{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(_8){this.node.className="dijitDialogUnderlay "+_8;this._set("class",_8);},postCreate:function(){_3.body().appendChild(this.domNode);},layout:function(){var is=this.node.style,os=this.domNode.style;os.display="none";var _9=_4.getBox();os.top=_9.t+"px";os.left=_9.l+"px";is.width=_9.w+"px";is.height=_9.h+"px";os.display="block";},show:function(){this.domNode.style.display="block";this.layout();this.bgIframe=new _7(this.domNode);},hide:function(){this.bgIframe.destroy();delete this.bgIframe;this.domNode.style.display="none";}});}); 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";}});});

@ -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";
}
});
});

@ -1,2 +1,2 @@
//>>built //>>built
require({cache:{"url:dijit/templates/Menu.html":"<table class=\"dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable\" role=\"menu\" tabIndex=\"${tabIndex}\" 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(){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;}}});}); 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;}}});});

@ -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;
}
}
});
});

File diff suppressed because one or more lines are too long

@ -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;
});

File diff suppressed because one or more lines are too long

@ -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;
});

@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
The "New" BSD License: The "New" BSD License:
********************** **********************
Copyright (c) 2005-2011, The Dojo Foundation Copyright (c) 2005-2012, The Dojo Foundation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

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

@ -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);
}
});
});

@ -1,2 +1,2 @@
//>>built //>>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(){var l=this.isLeftToRight();this.connectKeyNavHandlers(l?[_3.LEFT_ARROW]:[_3.RIGHT_ARROW],l?[_3.RIGHT_ARROW]:[_3.LEFT_ARROW]);this._orient=["below"];},focusChild:function(_6){var _7=this.focusedChild,_8=_7&&_7.popup&&_7.popup.isShowingNow;this.inherited(arguments);if(_8&&_6.popup&&!_6.disabled){this._openPopup();}},_onKeyPress:function(_9){if(_9.ctrlKey||_9.altKey){return;}switch(_9.charOrCode){case _3.DOWN_ARROW:this._moveToPopup(_9);_2.stop(_9);}},onItemClick:function(_a,_b){if(_a.popup&&_a.popup.isShowingNow){_a.popup.onCancel();}else{this.inherited(arguments);}}});}); 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);}}});});

@ -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);
}
}
});
});

@ -1,2 +1,2 @@
//>>built //>>built
require({cache:{"url:dijit/templates/MenuBarItem.html":"<div class=\"dijitReset dijitInline dijitMenuItem dijitMenuItemLabel\" data-dojo-attach-point=\"focusNode\" role=\"menuitem\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\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;}); 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;});

@ -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;
});

@ -1,2 +1,2 @@
//>>built //>>built
require({cache:{"url:dijit/templates/MenuItem.html":"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitem\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\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/event","dojo/_base/kernel","dojo/_base/sniff","./_Widget","./_TemplatedMixin","./_Contained","./_CssStateMixin","dojo/text!./templates/MenuItem.html"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c){return _1("dijit.MenuItem",[_8,_9,_a,_b],{templateString:_c,baseClass:"dijitMenuItem",label:"",_setLabelAttr:{node:"containerNode",type:"innerHTML"},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);},_onHover:function(){this.getParent().onItemHover(this);},_onUnhover:function(){this.getParent().onItemUnhover(this);this._set("hovering",false);},_onClick:function(_f){this.getParent().onItemClick(this,_f);_5.stop(_f);},onClick:function(){},focus:function(){try{if(_7("ie")==8){this.containerNode.focus();}this.focusNode.focus();}catch(e){}},_onFocus:function(){this._setSelected(true);this.getParent()._onItemFocus(this);this.inherited(arguments);},_setSelected:function(_10){_4.toggle(this.domNode,"dijitMenuItemSelected",_10);},setLabel:function(_11){_6.deprecated("dijit.MenuItem.setLabel() is deprecated. Use set('label', ...) instead.","","2.0");this.set("label",_11);},setDisabled:function(_12){_6.deprecated("dijit.Menu.setDisabled() is deprecated. Use set('disabled', bool) instead.","","2.0");this.set("disabled",_12);},_setDisabledAttr:function(_13){this.focusNode.setAttribute("aria-disabled",_13?"true":"false");this._set("disabled",_13);},_setAccelKeyAttr:function(_14){this.accelKeyNode.style.display=_14?"":"none";this.accelKeyNode.innerHTML=_14;_3.set(this.containerNode,"colSpan",_14?"1":"2");this._set("accelKey",_14);}});}); 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);}}});});

@ -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);
}
}
});
});

@ -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
}
});
});

@ -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)
});
});

@ -1,2 +1,2 @@
//>>built //>>built
define("dijit/PopupMenuItem",["dojo/_base/declare","dojo/dom-style","dojo/query","dojo/_base/window","./registry","./MenuItem","./hccss"],function(_1,_2,_3,_4,_5,_6){return _1("dijit.PopupMenuItem",_6,{_fillContent:function(){if(this.srcNodeRef){var _7=_3("*",this.srcNodeRef);this.inherited(arguments,[_7[0]]);this.dropDownContainer=this.srcNodeRef;}},startup:function(){if(this._started){return;}this.inherited(arguments);if(!this.popup){var _8=_3("[widgetId]",this.dropDownContainer)[0];this.popup=_5.byNode(_8);}_4.body().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(_9){if(this.popup){if(!this.popup._destroyed){this.popup.destroyRecursive(_9);}delete this.popup;}this.inherited(arguments);}});}); 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);}});});

@ -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);
}
});
});

@ -1,2 +1,2 @@
//>>built //>>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(!("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");ap.removeAttribute("aria-valuemin");ap.removeAttribute("aria-valuemax");}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-describedby",this.labelNode.id);ap.setAttribute("aria-valuenow",this.progress);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(){}});}); 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(){}});});

@ -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
}
});
});

@ -1,2 +1,2 @@
//>>built //>>built
require({cache:{"url:dijit/templates/TitlePane.html":"<div>\n\t<div data-dojo-attach-event=\"onclick:_onTitleClick, onkeypress:_onTitleKey\"\n\t\t\tclass=\"dijitTitlePaneTitle\" data-dojo-attach-point=\"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\">\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.arrowNodeInner.innerHTML=_12?"-":"+";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");_4.set(this.focusNode,"tabIndex",this.tabIndex);}else{_4.remove(this.focusNode,"tabIndex");}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.charOrCode==_a.ENTER||e.charOrCode==" "){if(this.toggleable){this.toggle();}_7.stop(e);}else{if(e.charOrCode==_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);}});}); 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);}});});

@ -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);
}
});
});

@ -1,2 +1,2 @@
//>>built //>>built
define("dijit/Toolbar",["require","dojo/_base/declare","dojo/_base/kernel","dojo/keys","dojo/ready","./_Widget","./_KeyNavContainer","./_TemplatedMixin"],function(_1,_2,_3,_4,_5,_6,_7,_8){if(!_3.isAsync){_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]);}});}); 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]);}});});

@ -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]
);
}
});
});

@ -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;
}
});
});

File diff suppressed because one or more lines are too long

@ -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;
});

@ -1,2 +1,2 @@
//>>built //>>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\"></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","."],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="dijitTooltipAB"+(_10.charAt(1)=="L"?"Left":"Right")+" dijitTooltip"+(_10.charAt(0)=="T"?"Below":"Above");_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);this._onShow();},onClose:function(){this.onHide();},_onKey:function(evt){var _12=evt.target;if(evt.charOrCode===_4.TAB){this._getFocusItems(this.containerNode);}var _13=(this._firstFocusItem==this._lastFocusItem);if(evt.charOrCode==_4.ESCAPE){setTimeout(_5.hitch(this,"onCancel"),0);_3.stop(evt);}else{if(_12==this._firstFocusItem&&evt.shiftKey&&evt.charOrCode===_4.TAB){if(!_13){_6.focus(this._lastFocusItem);}_3.stop(evt);}else{if(_12==this._lastFocusItem&&evt.charOrCode===_4.TAB&&!evt.shiftKey){if(!_13){_6.focus(this._firstFocusItem);}_3.stop(evt);}else{if(evt.charOrCode===_4.TAB){evt.stopPropagation();}}}}}});}); 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();}}}}}});});

@ -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();
}
}
});
});

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -0,0 +1,2 @@
//>>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;});

@ -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;
});

@ -1,2 +1,2 @@
//>>built //>>built
define("dijit/WidgetSet",["dojo/_base/array","dojo/_base/declare","dojo/_base/window","./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;}); 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;});

@ -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;
});

@ -1,2 +1,2 @@
//>>built //>>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;}}});return _1;}); 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;});

@ -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;
});

@ -1,2 +1,2 @@
//>>built //>>built
define("dijit/_Calendar",["dojo/_base/kernel","./Calendar","."],function(_1,_2,_3){_1.deprecated("dijit._Calendar is deprecated","dijit._Calendar moved to dijit.Calendar",2);_3._Calendar=_2;}); 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;});

@ -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;
});

@ -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
}
});
});

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

@ -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
}
});
});

@ -1,2 +1,2 @@
//>>built //>>built
define("dijit/_CssStateMixin",["dojo/touch","dojo/_base/array","dojo/_base/declare","dojo/dom-class","dojo/_base/lang","dojo/_base/window"],function(_1,_2,_3,_4,_5,_6){return _3("dijit._CssStateMixin",[],{cssStateNodes:{},hovering:false,active:false,_applyAttributes:function(){this.inherited(arguments);_2.forEach(["onmouseenter","onmouseleave",_1.press],function(e){this.connect(this.domNode,e,"_cssMouseEvent");},this);_2.forEach(["disabled","readOnly","checked","selected","focused","state","hovering","active"],function(_7){this.watch(_7,_5.hitch(this,"_setStateClass"));},this);for(var ap in this.cssStateNodes){this._trackMouseState(this[ap],this.cssStateNodes[ap]);}this._setStateClass();},_cssMouseEvent:function(_8){if(!this.disabled){switch(_8.type){case "mouseenter":case "mouseover":this._set("hovering",true);this._set("active",this._mouseDown);break;case "mouseleave":case "mouseout":this._set("hovering",false);this._set("active",false);break;case "mousedown":case "touchpress":this._set("active",true);this._mouseDown=true;var _9=this.connect(_6.body(),_1.release,function(){this._mouseDown=false;this._set("active",false);this.disconnect(_9);});break;}}},_setStateClass:function(){var _a=this.baseClass.split(" ");function _b(_c){_a=_a.concat(_2.map(_a,function(c){return c+_c;}),"dijit"+_c);};if(!this.isLeftToRight()){_b("Rtl");}var _d=this.checked=="mixed"?"Mixed":(this.checked?"Checked":"");if(this.checked){_b(_d);}if(this.state){_b(this.state);}if(this.selected){_b("Selected");}if(this.disabled){_b("Disabled");}else{if(this.readOnly){_b("ReadOnly");}else{if(this.active){_b("Active");}else{if(this.hovering){_b("Hover");}}}}if(this.focused){_b("Focused");}var tn=this.stateNode||this.domNode,_e={};_2.forEach(tn.className.split(" "),function(c){_e[c]=true;});if("_stateClasses" in this){_2.forEach(this._stateClasses,function(c){delete _e[c];});}_2.forEach(_a,function(c){_e[c]=true;});var _f=[];for(var c in _e){_f.push(c);}tn.className=_f.join(" ");this._stateClasses=_a;},_trackMouseState:function(_10,_11){var _12=false,_13=false,_14=false;var _15=this,cn=_5.hitch(this,"connect",_10);function _16(){var _17=("disabled" in _15&&_15.disabled)||("readonly" in _15&&_15.readonly);_4.toggle(_10,_11+"Hover",_12&&!_13&&!_17);_4.toggle(_10,_11+"Active",_13&&!_17);_4.toggle(_10,_11+"Focused",_14&&!_17);};cn("onmouseenter",function(){_12=true;_16();});cn("onmouseleave",function(){_12=false;_13=false;_16();});cn(_1.press,function(){_13=true;_16();});cn(_1.release,function(){_13=false;_16();});cn("onfocus",function(){_14=true;_16();});cn("onblur",function(){_14=false;_16();});this.watch("disabled",_16);this.watch("readOnly",_16);}});}); 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;});

@ -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;
});

@ -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;
}
});
});

@ -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
});
});

File diff suppressed because one or more lines are too long

@ -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;
}
}
});
});

@ -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
}
});
});

@ -1,2 +1,2 @@
//>>built //>>built
define("dijit/_MenuBase",["./popup","dojo/window","./_Widget","./_KeyNavContainer","./_TemplatedMixin","dojo/_base/declare","dojo/dom","dojo/dom-attr","dojo/dom-class","dojo/_base/lang","dojo/_base/array"],function(pm,_1,_2,_3,_4,_5,_6,_7,_8,_9,_a){return _5("dijit._MenuBase",[_2,_4,_3],{parentMenu:null,popupDelay:500,onExecute:function(){},onCancel:function(){},_moveToPopup:function(_b){if(this.focusedChild&&this.focusedChild.popup&&!this.focusedChild.disabled){this.focusedChild._onClick(_b);}else{var _c=this._getTopMenu();if(_c&&_c._isMenuBar){_c.focusNext();}}},_onPopupHover:function(){if(this.currentPopup&&this.currentPopup._pendingClose_timer){var _d=this.currentPopup.parentMenu;if(_d.focusedChild){_d.focusedChild._setSelected(false);}_d.focusedChild=this.currentPopup.from_item;_d.focusedChild._setSelected(true);this._stopPendingCloseTimer(this.currentPopup);}},onItemHover:function(_e){if(this.isActive){this.focusChild(_e);if(this.focusedChild.popup&&!this.focusedChild.disabled&&!this.hover_timer){this.hover_timer=setTimeout(_9.hitch(this,"_openPopup"),this.popupDelay);}}if(this.focusedChild){this.focusChild(_e);}this._hoveredChild=_e;},_onChildBlur:function(_f){this._stopPopupTimer();_f._setSelected(false);var _10=_f.popup;if(_10){this._stopPendingCloseTimer(_10);_10._pendingClose_timer=setTimeout(function(){_10._pendingClose_timer=null;if(_10.parentMenu){_10.parentMenu.currentPopup=null;}pm.close(_10);},this.popupDelay);}},onItemUnhover:function(_11){if(this.isActive){this._stopPopupTimer();}if(this._hoveredChild==_11){this._hoveredChild=null;}},_stopPopupTimer:function(){if(this.hover_timer){clearTimeout(this.hover_timer);this.hover_timer=null;}},_stopPendingCloseTimer:function(_12){if(_12._pendingClose_timer){clearTimeout(_12._pendingClose_timer);_12._pendingClose_timer=null;}},_stopFocusTimer:function(){if(this._focus_timer){clearTimeout(this._focus_timer);this._focus_timer=null;}},_getTopMenu:function(){for(var top=this;top.parentMenu;top=top.parentMenu){}return top;},onItemClick:function(_13,evt){if(typeof this.isShowingNow=="undefined"){this._markActive();}this.focusChild(_13);if(_13.disabled){return false;}if(_13.popup){this._openPopup();}else{this.onExecute();_13.onClick(evt);}},_openPopup:function(){this._stopPopupTimer();var _14=this.focusedChild;if(!_14){return;}var _15=_14.popup;if(_15.isShowingNow){return;}if(this.currentPopup){this._stopPendingCloseTimer(this.currentPopup);pm.close(this.currentPopup);}_15.parentMenu=this;_15.from_item=_14;var _16=this;pm.open({parent:this,popup:_15,around:_14.domNode,orient:this._orient||["after","before"],onCancel:function(){_16.focusChild(_14);_16._cleanUp();_14._setSelected(true);_16.focusedChild=_14;},onExecute:_9.hitch(this,"_cleanUp")});this.currentPopup=_15;_15.connect(_15.domNode,"onmouseenter",_9.hitch(_16,"_onPopupHover"));if(_15.focus){_15._focus_timer=setTimeout(_9.hitch(_15,function(){this._focus_timer=null;this.focus();}),0);}},_markActive:function(){this.isActive=true;_8.replace(this.domNode,"dijitMenuActive","dijitMenuPassive");},onOpen:function(){this.isShowingNow=true;this._markActive();},_markInactive:function(){this.isActive=false;_8.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(_a.indexOf(this._focusManager.activeStack,this.id)>=0){_7.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.focusedChild._onUnhover();this.focusedChild=null;}},_onItemFocus:function(_17){if(this._hoveredChild&&this._hoveredChild!=_17){this._hoveredChild._onUnhover();}},_onBlur:function(){this._cleanUp();this.inherited(arguments);},_cleanUp:function(){this._closeChild();if(typeof this.isShowingNow=="undefined"){this._markInactive();}}});}); 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();}}});});

@ -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();
}
}
});
});

@ -1,2 +1,2 @@
//>>built //>>built
define("dijit/_OnDijitClickMixin",["dojo/on","dojo/_base/array","dojo/keys","dojo/_base/declare","dojo/_base/sniff","dojo/_base/unload","dojo/_base/window"],function(on,_1,_2,_3,_4,_5,_6){var _7=null;if(_4("ie")){(function(){var _8=function(_9){_7=_9.srcElement;};_6.doc.attachEvent("onkeydown",_8);_5.addOnWindowUnload(function(){_6.doc.detachEvent("onkeydown",_8);});})();}else{_6.doc.addEventListener("keydown",function(_a){_7=_a.target;},true);}var _b=function(_c,_d){if(/input|button/i.test(_c.nodeName)){return on(_c,"click",_d);}else{function _e(e){return (e.keyCode==_2.ENTER||e.keyCode==_2.SPACE)&&!e.ctrlKey&&!e.shiftKey&&!e.altKey&&!e.metaKey;};var _f=[on(_c,"keypress",function(e){if(_e(e)){_7=e.target;e.preventDefault();}}),on(_c,"keyup",function(e){if(_e(e)&&e.target==_7){_7=null;_d.call(this,e);}}),on(_c,"click",function(e){_d.call(this,e);})];return {remove:function(){_1.forEach(_f,function(h){h.remove();});}};}};return _3("dijit._OnDijitClickMixin",null,{connect:function(obj,_10,_11){return this.inherited(arguments,[obj,_10=="ondijitclick"?_b:_10,_11]);}});}); 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;});

@ -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;
});

@ -1,2 +1,2 @@
//>>built //>>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:"",summary:"",_setSummaryAttr:"paletteTableNode",_dyeFactory:function(_b){var _c=_7.getObject(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);var _13=_4.create("td",{"class":this.cellClass,tabIndex:"-1",title:_e[_11],role:"gridcell"});_12.fillCell(_13,_f);_4.place(_13,_10);_13.index=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._connects.push(_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.index+_1c;if(_1e<this._cells.length&&_1e>-1){var _1f=this._cells[_1e].node;this._setCurrent(_1f);setTimeout(_7.hitch(dijit,"focus",_1f),0);}},_getDye:function(_20){return this._cells[_20.index].dye;}});}); 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;}});});

@ -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
}
}
);
=====*/
});

@ -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]);
}
});
}
}
}
});
});

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

@ -0,0 +1,309 @@
define("dijit/_TemplatedMixin", [
"dojo/_base/lang", // lang.getObject
"dojo/touch",
"./_WidgetBase",
"dojo/string", // string.substitute string.trim
"dojo/cache", // dojo.cache
"dojo/_base/array", // array.forEach
"dojo/_base/declare", // declare
"dojo/dom-construct", // domConstruct.destroy, domConstruct.toDom
"dojo/sniff", // has("ie")
"dojo/_base/unload" // unload.addOnWindowUnload
], function(lang, touch, _WidgetBase, string, cache, array, declare, domConstruct, has, unload) {
// module:
// dijit/_TemplatedMixin
var _TemplatedMixin = declare("dijit._TemplatedMixin", null, {
// summary:
// Mixin for widgets that are instantiated from a template
// templateString: [protected] String
// A string that represents the widget template.
// Use in conjunction with dojo.cache() to load from a file.
templateString: null,
// templatePath: [protected deprecated] String
// Path to template (HTML file) for this widget relative to dojo.baseUrl.
// Deprecated: use templateString with require([... "dojo/text!..."], ...) instead
templatePath: null,
// skipNodeCache: [protected] Boolean
// If using a cached widget template nodes poses issues for a
// particular widget class, it can set this property to ensure
// that its template is always re-built from a string
_skipNodeCache: false,
// _earlyTemplatedStartup: Boolean
// A fallback to preserve the 1.0 - 1.3 behavior of children in
// templates having their startup called before the parent widget
// fires postCreate. Defaults to 'false', causing child widgets to
// have their .startup() called immediately before a parent widget
// .startup(), but always after the parent .postCreate(). Set to
// 'true' to re-enable to previous, arguably broken, behavior.
_earlyTemplatedStartup: false,
/*=====
// _attachPoints: [private] String[]
// List of widget attribute names associated with data-dojo-attach-point=... in the
// template, ex: ["containerNode", "labelNode"]
_attachPoints: [],
// _attachEvents: [private] Handle[]
// List of connections associated with data-dojo-attach-event=... in the
// template
_attachEvents: [],
=====*/
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._attachPoints = [];
this._attachEvents = [];
},
_stringRepl: function(tmpl){
// summary:
// Does substitution of ${foo} type properties in template string
// tags:
// private
var className = this.declaredClass, _this = this;
// Cache contains a string because we need to do property replacement
// do the property replacement
return string.substitute(tmpl, this, function(value, key){
if(key.charAt(0) == '!'){ value = lang.getObject(key.substr(1), false, _this); }
if(typeof value == "undefined"){ throw new Error(className+" template:"+key); } // a debugging aide
if(value == null){ return ""; }
// Substitution keys beginning with ! will skip the transform step,
// in case a user wishes to insert unescaped markup, e.g. ${!foo}
return key.charAt(0) == "!" ? value :
// Safer substitution, see heading "Attribute values" in
// http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
value.toString().replace(/"/g,"&quot;"); //TODO: add &amp? use encodeXML method?
}, this);
},
buildRendering: function(){
// summary:
// Construct the UI for this widget from a template, setting this.domNode.
// tags:
// protected
if(!this.templateString){
this.templateString = cache(this.templatePath, {sanitize: true});
}
// Lookup cached version of template, and download to cache if it
// isn't there already. Returns either a DomNode or a string, depending on
// whether or not the template contains ${foo} replacement parameters.
var cached = _TemplatedMixin.getCachedTemplate(this.templateString, this._skipNodeCache, this.ownerDocument);
var node;
if(lang.isString(cached)){
node = domConstruct.toDom(this._stringRepl(cached), this.ownerDocument);
if(node.nodeType != 1){
// Flag common problems such as templates with multiple top level nodes (nodeType == 11)
throw new Error("Invalid template: " + cached);
}
}else{
// if it's a node, all we have to do is clone it
node = cached.cloneNode(true);
}
this.domNode = node;
// Call down to _Widget.buildRendering() to get base classes assigned
// TODO: change the baseClass assignment to _setBaseClassAttr
this.inherited(arguments);
// recurse through the node, looking for, and attaching to, our
// attachment points and events, which should be defined on the template node.
this._attachTemplateNodes(node, function(n,p){ return n.getAttribute(p); });
this._beforeFillContent(); // hook for _WidgetsInTemplateMixin
this._fillContent(this.srcNodeRef);
},
_beforeFillContent: function(){
},
_fillContent: function(/*DomNode*/ source){
// summary:
// Relocate source contents to templated container node.
// this.containerNode must be able to receive children, or exceptions will be thrown.
// tags:
// protected
var dest = this.containerNode;
if(source && dest){
while(source.hasChildNodes()){
dest.appendChild(source.firstChild);
}
}
},
_attachTemplateNodes: function(rootNode, getAttrFunc){
// summary:
// Iterate through the template and attach functions and nodes accordingly.
// Alternately, if rootNode is an array of widgets, then will process data-dojo-attach-point
// etc. for those widgets.
// description:
// Map widget properties and functions to the handlers specified in
// the dom node and it's descendants. This function iterates over all
// nodes and looks for these properties:
//
// - dojoAttachPoint/data-dojo-attach-point
// - dojoAttachEvent/data-dojo-attach-event
// rootNode: DomNode|Widget[]
// the node to search for properties. All children will be searched.
// getAttrFunc: Function
// a function which will be used to obtain property for a given
// DomNode/Widget
// tags:
// private
var nodes = lang.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*"));
var x = lang.isArray(rootNode) ? 0 : -1;
for(; x < 0 || nodes[x]; x++){ // don't access nodes.length on IE, see #14346
var baseNode = (x == -1) ? rootNode : nodes[x];
if(this.widgetsInTemplate && (getAttrFunc(baseNode, "dojoType") || getAttrFunc(baseNode, "data-dojo-type"))){
continue;
}
// Process data-dojo-attach-point
var attachPoint = getAttrFunc(baseNode, "dojoAttachPoint") || getAttrFunc(baseNode, "data-dojo-attach-point");
if(attachPoint){
var point, points = attachPoint.split(/\s*,\s*/);
while((point = points.shift())){
if(lang.isArray(this[point])){
this[point].push(baseNode);
}else{
this[point]=baseNode;
}
this._attachPoints.push(point);
}
}
// Process data-dojo-attach-event
var attachEvent = getAttrFunc(baseNode, "dojoAttachEvent") || getAttrFunc(baseNode, "data-dojo-attach-event");
if(attachEvent){
// NOTE: we want to support attributes that have the form
// "domEvent: nativeEvent; ..."
var event, events = attachEvent.split(/\s*,\s*/);
var trim = lang.trim;
while((event = events.shift())){
if(event){
var thisFunc = null;
if(event.indexOf(":") != -1){
// oh, if only JS had tuple assignment
var funcNameArr = event.split(":");
event = trim(funcNameArr[0]);
thisFunc = trim(funcNameArr[1]);
}else{
event = trim(event);
}
if(!thisFunc){
thisFunc = event;
}
// Map "press", "move" and "release" to keys.touch, keys.move, keys.release
this._attachEvents.push(this.connect(baseNode, touch[event] || event, thisFunc));
}
}
}
}
},
destroyRendering: function(){
// Delete all attach points to prevent IE6 memory leaks.
array.forEach(this._attachPoints, function(point){
delete this[point];
}, this);
this._attachPoints = [];
// And same for event handlers
array.forEach(this._attachEvents, this.disconnect, this);
this._attachEvents = [];
this.inherited(arguments);
}
});
// key is templateString; object is either string or DOM tree
_TemplatedMixin._templateCache = {};
_TemplatedMixin.getCachedTemplate = function(templateString, alwaysUseString, doc){
// summary:
// Static method to get a template based on the templatePath or
// templateString key
// templateString: String
// The template
// alwaysUseString: Boolean
// Don't cache the DOM tree for this template, even if it doesn't have any variables
// doc: Document?
// The target document. Defaults to document global if unspecified.
// returns: Mixed
// Either string (if there are ${} variables that need to be replaced) or just
// a DOM tree (if the node can be cloned directly)
// is it already cached?
var tmplts = _TemplatedMixin._templateCache;
var key = templateString;
var cached = tmplts[key];
if(cached){
try{
// if the cached value is an innerHTML string (no ownerDocument) or a DOM tree created within the
// current document, then use the current cached value
if(!cached.ownerDocument || cached.ownerDocument == (doc || document)){
// string or node of the same document
return cached;
}
}catch(e){ /* squelch */ } // IE can throw an exception if cached.ownerDocument was reloaded
domConstruct.destroy(cached);
}
templateString = string.trim(templateString);
if(alwaysUseString || templateString.match(/\$\{([^\}]+)\}/g)){
// there are variables in the template so all we can do is cache the string
return (tmplts[key] = templateString); //String
}else{
// there are no variables in the template so we can cache the DOM tree
var node = domConstruct.toDom(templateString, doc);
if(node.nodeType != 1){
throw new Error("Invalid template: " + templateString);
}
return (tmplts[key] = node); //Node
}
};
if(has("ie")){
unload.addOnWindowUnload(function(){
var cache = _TemplatedMixin._templateCache;
for(var key in cache){
var value = cache[key];
if(typeof value == "object"){ // value is either a string or a DOM node template
domConstruct.destroy(value);
}
delete cache[key];
}
});
}
// 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, /*===== {} || =====*/ {
dojoAttachEvent: "",
dojoAttachPoint: ""
});
return _TemplatedMixin;
});

File diff suppressed because one or more lines are too long

@ -0,0 +1,525 @@
require({cache:{
'url:dijit/templates/TimePicker.html':"<div id=\"widget_${id}\" class=\"dijitMenu\"\n ><div data-dojo-attach-point=\"upArrow\" class=\"dijitButtonNode dijitUpArrowButton\" data-dojo-attach-event=\"onmouseenter:_buttonMouse,onmouseleave:_buttonMouse\"\n\t\t><div class=\"dijitReset dijitInline dijitArrowButtonInner\" role=\"presentation\">&#160;</div\n\t\t><div class=\"dijitArrowButtonChar\">&#9650;</div></div\n ><div data-dojo-attach-point=\"timeMenu,focusNode\" data-dojo-attach-event=\"onclick:_onOptionSelected,onmouseover,onmouseout\"></div\n ><div data-dojo-attach-point=\"downArrow\" class=\"dijitButtonNode dijitDownArrowButton\" data-dojo-attach-event=\"onmouseenter:_buttonMouse,onmouseleave:_buttonMouse\"\n\t\t><div class=\"dijitReset dijitInline dijitArrowButtonInner\" role=\"presentation\">&#160;</div\n\t\t><div class=\"dijitArrowButtonChar\">&#9660;</div></div\n></div>\n"}});
define("dijit/_TimePicker", [
"dojo/_base/array", // array.forEach
"dojo/date", // date.compare
"dojo/date/locale", // locale.format
"dojo/date/stamp", // stamp.fromISOString stamp.toISOString
"dojo/_base/declare", // declare
"dojo/dom-class", // domClass.add domClass.contains domClass.toggle
"dojo/dom-construct", // domConstruct.create
"dojo/_base/event", // event.stop
"dojo/_base/kernel", // deprecated
"dojo/keys", // keys
"dojo/_base/lang", // lang.mixin
"dojo/sniff", // has(...)
"dojo/query", // query
"dojo/mouse", // mouse.wheel
"./typematic",
"./_Widget",
"./_TemplatedMixin",
"./form/_FormValueWidget",
"dojo/text!./templates/TimePicker.html"
], function(array, ddate, locale, stamp, declare, domClass, domConstruct, event, kernel, keys, lang, has, query, mouse,
typematic, _Widget, _TemplatedMixin, _FormValueWidget, template){
// module:
// dijit/_TimePicker
var TimePicker = declare("dijit._TimePicker", [_Widget, _TemplatedMixin], {
// summary:
// A graphical time picker.
// This widget is used internally by other widgets and is not available
// as a standalone widget due to lack of accessibility support.
templateString: template,
// baseClass: [protected] String
// The root className to use for the various states of this widget
baseClass: "dijitTimePicker",
// clickableIncrement: String
// ISO-8601 string representing the amount by which
// every clickable element in the time picker increases.
// Set in local time, without a time zone.
// Example: `T00:15:00` creates 15 minute increments
// Must divide dijit/_TimePicker.visibleIncrement evenly
clickableIncrement: "T00:15:00",
// visibleIncrement: String
// ISO-8601 string representing the amount by which
// every element with a visible time in the time picker increases.
// Set in local time, without a time zone.
// Example: `T01:00:00` creates text in every 1 hour increment
visibleIncrement: "T01:00:00",
// visibleRange: String
// ISO-8601 string representing the range of this TimePicker.
// The TimePicker will only display times in this range.
// Example: `T05:00:00` displays 5 hours of options
visibleRange: "T05:00:00",
// value: String
// Date to display.
// Defaults to current time and date.
// Can be a Date object or an ISO-8601 string.
// If you specify the GMT time zone (`-01:00`),
// the time will be converted to the local time in the local time zone.
// Otherwise, the time is considered to be in the local time zone.
// If you specify the date and isDate is true, the date is used.
// Example: if your local time zone is `GMT -05:00`,
// `T10:00:00` becomes `T10:00:00-05:00` (considered to be local time),
// `T10:00:00-01:00` becomes `T06:00:00-05:00` (4 hour difference),
// `T10:00:00Z` becomes `T05:00:00-05:00` (5 hour difference between Zulu and local time)
// `yyyy-mm-ddThh:mm:ss` is the format to set the date and time
// Example: `2007-06-01T09:00:00`
value: new Date(),
_visibleIncrement:2,
_clickableIncrement:1,
_totalIncrements:10,
// constraints: TimePicker.__Constraints
// Specifies valid range of times (start time, end time)
constraints:{},
/*=====
serialize: function(val, options){
// summary:
// User overridable function used to convert the attr('value') result to a String
// val: Date
// The current value
// options: Object?
// tags:
// protected
},
=====*/
serialize: stamp.toISOString,
/*=====
// filterString: string
// The string to filter by
filterString: "",
=====*/
setValue: function(/*Date*/ value){
// summary:
// Deprecated. Used set('value') instead.
// tags:
// deprecated
kernel.deprecated("dijit._TimePicker:setValue() is deprecated. Use set('value', ...) instead.", "", "2.0");
this.set('value', value);
},
_setValueAttr: function(/*Date*/ date){
// summary:
// Hook so set('value', ...) works.
// description:
// Set the value of the TimePicker.
// Redraws the TimePicker around the new date.
// tags:
// protected
this._set("value", date);
this._showText();
},
_setFilterStringAttr: function(val){
// summary:
// Called by TimeTextBox to filter the values shown in my list
this._set("filterString", val);
this._showText();
},
isDisabledDate: function(/*===== dateObject, locale =====*/){
// summary:
// May be overridden to disable certain dates in the TimePicker e.g. `isDisabledDate=locale.isWeekend`
// dateObject: Date
// locale: String?
// type:
// extension
return false; // Boolean
},
_getFilteredNodes: function(/*number*/ start, /*number*/ maxNum, /*Boolean*/ before, /*DOMnode*/ lastNode){
// summary:
// Returns an array of nodes with the filter applied. At most maxNum nodes
// will be returned - but fewer may be returned as well. If the
// before parameter is set to true, then it will return the elements
// before the given index
// tags:
// private
var
nodes = [],
lastValue = lastNode ? lastNode.date : this._refDate,
n,
i = start,
max = this._maxIncrement + Math.abs(i),
chk = before ? -1 : 1,
dec = before ? 1 : 0,
inc = 1 - dec;
do{
i -= dec;
n = this._createOption(i);
if(n){
if((before && n.date > lastValue) || (!before && n.date < lastValue)){
break; // don't wrap
}
nodes[before ? "unshift" : "push"](n);
lastValue = n.date;
}
i += inc;
}while(nodes.length < maxNum && (i*chk) < max);
return nodes;
},
_showText: function(){
// summary:
// Displays the relevant choices in the drop down list
// tags:
// private
var fromIso = stamp.fromISOString;
this.timeMenu.innerHTML = "";
this._clickableIncrementDate=fromIso(this.clickableIncrement);
this._visibleIncrementDate=fromIso(this.visibleIncrement);
this._visibleRangeDate=fromIso(this.visibleRange);
// get the value of the increments and the range in seconds (since 00:00:00) to find out how many divs to create
var
sinceMidnight = function(/*Date*/ date){
return date.getHours() * 60 * 60 + date.getMinutes() * 60 + date.getSeconds();
},
clickableIncrementSeconds = sinceMidnight(this._clickableIncrementDate),
visibleIncrementSeconds = sinceMidnight(this._visibleIncrementDate),
visibleRangeSeconds = sinceMidnight(this._visibleRangeDate),
// round reference date to previous visible increment
time = (this.value || this.currentFocus).getTime();
this._refDate = new Date(time - time % (clickableIncrementSeconds*1000));
this._refDate.setFullYear(1970,0,1); // match parse defaults
// assume clickable increment is the smallest unit
this._clickableIncrement = 1;
// divide the visible range by the clickable increment to get the number of divs to create
// example: 10:00:00/00:15:00 -> display 40 divs
this._totalIncrements = visibleRangeSeconds / clickableIncrementSeconds;
// divide the visible increments by the clickable increments to get how often to display the time inline
// example: 01:00:00/00:15:00 -> display the time every 4 divs
this._visibleIncrement = visibleIncrementSeconds / clickableIncrementSeconds;
// divide the number of seconds in a day by the clickable increment in seconds to get the
// absolute max number of increments.
this._maxIncrement = (60 * 60 * 24) / clickableIncrementSeconds;
var
// Find the nodes we should display based on our filter.
// Limit to 10 nodes displayed as a half-hearted attempt to stop drop down from overlapping <input>.
count = Math.min(this._totalIncrements, 10),
after = this._getFilteredNodes(0, (count >> 1) + 1, false),
moreAfter = [],
estBeforeLength = count - after.length,
before = this._getFilteredNodes(0, estBeforeLength, true, after[0]);
if(before.length < estBeforeLength && after.length > 0){
moreAfter = this._getFilteredNodes(after[after.length-1].idx + 1, estBeforeLength - before.length, false, after[after.length-1]);
}
array.forEach(before.concat(after, moreAfter), function(n){ this.timeMenu.appendChild(n); }, this);
// never show empty due to a bad filter
if(!before.length && !after.length && !moreAfter.length && this.filterString){
this.filterString = '';
this._showText();
}
},
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.constraints = {};
},
postMixInProperties: function(){
this.inherited(arguments);
this._setConstraintsAttr(this.constraints); // this needs to happen now (and later) due to codependency on _set*Attr calls
},
_setConstraintsAttr: function(/* Object */ constraints){
// brings in visibleRange, increments, etc.
lang.mixin(this, constraints);
// locale needs the lang in the constraints as locale
if(!constraints.locale){
constraints.locale = this.lang;
}
},
postCreate: function(){
// assign typematic mouse listeners to the arrow buttons
this.connect(this.timeMenu, mouse.wheel, "_mouseWheeled");
this.own(
typematic.addMouseListener(this.upArrow, this, "_onArrowUp", 33, 250),
typematic.addMouseListener(this.downArrow, this, "_onArrowDown", 33, 250)
);
this.inherited(arguments);
},
_buttonMouse: function(/*Event*/ e){
// summary:
// Handler for hover (and unhover) on up/down arrows
// tags:
// private
// in non-IE browser the "mouseenter" event will become "mouseover",
// but in IE it's still "mouseenter"
domClass.toggle(e.currentTarget, e.currentTarget == this.upArrow ? "dijitUpArrowHover" : "dijitDownArrowHover",
e.type == "mouseenter" || e.type == "mouseover");
},
_createOption: function(/*Number*/ index){
// summary:
// Creates a clickable time option
// tags:
// private
var date = new Date(this._refDate);
var incrementDate = this._clickableIncrementDate;
date.setTime(date.getTime()
+ incrementDate.getHours() * index * 3600000
+ incrementDate.getMinutes() * index * 60000
+ incrementDate.getSeconds() * index * 1000);
if(this.constraints.selector == "time"){
date.setFullYear(1970,0,1); // make sure each time is for the same date
}
var dateString = locale.format(date, this.constraints);
if(this.filterString && dateString.toLowerCase().indexOf(this.filterString) !== 0){
// Doesn't match the filter - return null
return null;
}
var div = this.ownerDocument.createElement("div");
div.className = this.baseClass+"Item";
div.date = date;
div.idx = index;
domConstruct.create('div',{
"class": this.baseClass + "ItemInner",
innerHTML: dateString
}, div);
if(index%this._visibleIncrement<1 && index%this._visibleIncrement>-1){
domClass.add(div, this.baseClass+"Marker");
}else if(!(index%this._clickableIncrement)){
domClass.add(div, this.baseClass+"Tick");
}
if(this.isDisabledDate(date)){
// set disabled
domClass.add(div, this.baseClass+"ItemDisabled");
}
if(this.value && !ddate.compare(this.value, date, this.constraints.selector)){
div.selected = true;
domClass.add(div, this.baseClass+"ItemSelected");
if(domClass.contains(div, this.baseClass+"Marker")){
domClass.add(div, this.baseClass+"MarkerSelected");
}else{
domClass.add(div, this.baseClass+"TickSelected");
}
// Initially highlight the current value. User can change highlight by up/down arrow keys
// or mouse movement.
this._highlightOption(div, true);
}
return div;
},
_onOptionSelected: function(/*Object*/ tgt){
// summary:
// Called when user clicks an option in the drop down list
// tags:
// private
var tdate = tgt.target.date || tgt.target.parentNode.date;
if(!tdate || this.isDisabledDate(tdate)){ return; }
this._highlighted_option = null;
this.set('value', tdate);
this.onChange(tdate);
},
onChange: function(/*Date*/ /*===== time =====*/){
// summary:
// Notification that a time was selected. It may be the same as the previous value.
// tags:
// public
},
_highlightOption: function(/*node*/ node, /*Boolean*/ highlight){
// summary:
// Turns on/off highlight effect on a node based on mouse out/over event
// tags:
// private
if(!node){return;}
if(highlight){
if(this._highlighted_option){
this._highlightOption(this._highlighted_option, false);
}
this._highlighted_option = node;
}else if(this._highlighted_option !== node){
return;
}else{
this._highlighted_option = null;
}
domClass.toggle(node, this.baseClass+"ItemHover", highlight);
if(domClass.contains(node, this.baseClass+"Marker")){
domClass.toggle(node, this.baseClass+"MarkerHover", highlight);
}else{
domClass.toggle(node, this.baseClass+"TickHover", highlight);
}
},
onmouseover: function(/*Event*/ e){
// summary:
// Handler for onmouseover event
// tags:
// private
this._keyboardSelected = null;
var tgr = (e.target.parentNode === this.timeMenu) ? e.target : e.target.parentNode;
// if we aren't targeting an item, then we return
if(!domClass.contains(tgr, this.baseClass+"Item")){return;}
this._highlightOption(tgr, true);
},
onmouseout: function(/*Event*/ e){
// summary:
// Handler for onmouseout event
// tags:
// private
this._keyboardSelected = null;
var tgr = (e.target.parentNode === this.timeMenu) ? e.target : e.target.parentNode;
this._highlightOption(tgr, false);
},
_mouseWheeled: function(/*Event*/ e){
// summary:
// Handle the mouse wheel events
// tags:
// private
this._keyboardSelected = null;
event.stop(e);
// we're not _measuring_ the scroll amount, just direction
this[(e.wheelDelta>0 ? "_onArrowUp" : "_onArrowDown")](); // yes, we're making a new dom node every time you mousewheel, or click
},
_onArrowUp: function(count){
// summary:
// Handler for up arrow key.
// description:
// Removes the bottom time and add one to the top
// tags:
// private
if(count === -1){
domClass.remove(this.upArrow, "dijitUpArrowActive");
return;
}else if(count === 0){
domClass.add(this.upArrow, "dijitUpArrowActive");
} // typematic end
if(!this.timeMenu.childNodes.length){ return; }
var index = this.timeMenu.childNodes[0].idx;
var divs = this._getFilteredNodes(index, 1, true, this.timeMenu.childNodes[0]);
if(divs.length){
this.timeMenu.removeChild(this.timeMenu.childNodes[this.timeMenu.childNodes.length - 1]);
this.timeMenu.insertBefore(divs[0], this.timeMenu.childNodes[0]);
}
},
_onArrowDown: function(count){
// summary:
// Handler for up arrow key.
// description:
// Remove the top time and add one to the bottom
// tags:
// private
if(count === -1){
domClass.remove(this.downArrow, "dijitDownArrowActive");
return;
}else if(count === 0){
domClass.add(this.downArrow, "dijitDownArrowActive");
} // typematic end
if(!this.timeMenu.childNodes.length){ return; }
var index = this.timeMenu.childNodes[this.timeMenu.childNodes.length - 1].idx + 1;
var divs = this._getFilteredNodes(index, 1, false, this.timeMenu.childNodes[this.timeMenu.childNodes.length - 1]);
if(divs.length){
this.timeMenu.removeChild(this.timeMenu.childNodes[0]);
this.timeMenu.appendChild(divs[0]);
}
},
handleKey: function(/*Event*/ e){
// summary:
// Called from `dijit/form/_DateTimeTextBox` to pass a keypress event
// from the `dijit/form/TimeTextBox` to be handled in this widget
// tags:
// protected
if(e.keyCode == keys.DOWN_ARROW || e.keyCode == keys.UP_ARROW){
event.stop(e);
// Figure out which option to highlight now and then highlight it
if(this._highlighted_option && !this._highlighted_option.parentNode){
this._highlighted_option = null;
}
var timeMenu = this.timeMenu,
tgt = this._highlighted_option || query("." + this.baseClass + "ItemSelected", timeMenu)[0];
if(!tgt){
tgt = timeMenu.childNodes[0];
}else if(timeMenu.childNodes.length){
if(e.keyCode == keys.DOWN_ARROW && !tgt.nextSibling){
this._onArrowDown();
}else if(e.keyCode == keys.UP_ARROW && !tgt.previousSibling){
this._onArrowUp();
}
if(e.keyCode == keys.DOWN_ARROW){
tgt = tgt.nextSibling;
}else{
tgt = tgt.previousSibling;
}
}
this._highlightOption(tgt, true);
this._keyboardSelected = tgt;
return false;
}else if(e.keyCode == keys.ENTER || e.keyCode === keys.TAB){
// mouse hover followed by TAB is NO selection
if(!this._keyboardSelected && e.keyCode === keys.TAB){
return true; // true means don't call stopEvent()
}
// Accept the currently-highlighted option as the value
if(this._highlighted_option){
this._onOptionSelected({target: this._highlighted_option});
}
// Call stopEvent() for ENTER key so that form doesn't submit,
// but not for TAB, so that TAB does switch focus
return e.keyCode === keys.TAB;
}
return undefined;
}
});
/*=====
TimePicker.__Constraints = declare(locale.__FormatOptions, {
// clickableIncrement: String
// See `dijit/_TimePicker.clickableIncrement`
clickableIncrement: "T00:15:00",
// visibleIncrement: String
// See `dijit/_TimePicker.visibleIncrement`
visibleIncrement: "T01:00:00",
// visibleRange: String
// See `dijit/_TimePicker.visibleRange`
visibleRange: "T05:00:00"
});
=====*/
return TimePicker;
});

@ -1,2 +1,2 @@
//>>built //>>built
define("dijit/_Widget",["dojo/aspect","dojo/_base/config","dojo/_base/connect","dojo/_base/declare","dojo/_base/kernel","dojo/_base/lang","dojo/query","dojo/ready","./registry","./_WidgetBase","./_OnDijitClickMixin","./_FocusMixin","dojo/uacss","./hccss"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c){function _d(){};function _e(_f){return function(obj,_10,_11,_12){if(obj&&typeof _10=="string"&&obj[_10]==_d){return obj.on(_10.substring(2).toLowerCase(),_6.hitch(_11,_12));}return _f.apply(_3,arguments);};};_1.around(_3,"connect",_e);if(_5.connect){_1.around(_5,"connect",_e);}var _13=_4("dijit._Widget",[_a,_b,_c],{onClick:_d,onDblClick:_d,onKeyDown:_d,onKeyPress:_d,onKeyUp:_d,onMouseDown:_d,onMouseMove:_d,onMouseOut:_d,onMouseOver:_d,onMouseLeave:_d,onMouseEnter:_d,onMouseUp:_d,constructor:function(_14){this._toConnect={};for(var _15 in _14){if(this[_15]===_d){this._toConnect[_15.replace(/^on/,"").toLowerCase()]=_14[_15];delete _14[_15];}}},postCreate:function(){this.inherited(arguments);for(var _16 in this._toConnect){this.on(_16,this._toConnect[_16]);}delete this._toConnect;},on:function(_17,_18){if(this[this._onMap(_17)]===_d){return _3.connect(this.domNode,_17.toLowerCase(),this,_18);}return this.inherited(arguments);},_setFocusedAttr:function(val){this._focused=val;this._set("focused",val);},setAttribute:function(_19,_1a){_5.deprecated(this.declaredClass+"::setAttribute(attr, value) is deprecated. Use set() instead.","","2.0");this.set(_19,_1a);},attr:function(_1b,_1c){if(_2.isDebug){var _1d=arguments.callee._ach||(arguments.callee._ach={}),_1e=(arguments.callee.caller||"unknown caller").toString();if(!_1d[_1e]){_5.deprecated(this.declaredClass+"::attr() is deprecated. Use get() or set() instead, called from "+_1e,"","2.0");_1d[_1e]=true;}}var _1f=arguments.length;if(_1f>=2||typeof _1b==="object"){return this.set.apply(this,arguments);}else{return this.get(_1b);}},getDescendants:function(){_5.deprecated(this.declaredClass+"::getDescendants() is deprecated. Use getChildren() instead.","","2.0");return this.containerNode?_7("[widgetId]",this.containerNode).map(_9.byNode):[];},_onShow:function(){this.onShow();},onShow:function(){},onHide:function(){},onClose:function(){return true;}});if(!_5.isAsync){_8(0,function(){var _20=["dijit/_base"];require(_20);});}return _13;}); define("dijit/_Widget",["dojo/aspect","dojo/_base/config","dojo/_base/connect","dojo/_base/declare","dojo/has","dojo/_base/kernel","dojo/_base/lang","dojo/query","dojo/ready","./registry","./_WidgetBase","./_OnDijitClickMixin","./_FocusMixin","dojo/uacss","./hccss"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c,_d){function _e(){};function _f(_10){return function(obj,_11,_12,_13){if(obj&&typeof _11=="string"&&obj[_11]==_e){return obj.on(_11.substring(2).toLowerCase(),_7.hitch(_12,_13));}return _10.apply(_3,arguments);};};_1.around(_3,"connect",_f);if(_6.connect){_1.around(_6,"connect",_f);}var _14=_4("dijit._Widget",[_b,_c,_d],{onClick:_e,onDblClick:_e,onKeyDown:_e,onKeyPress:_e,onKeyUp:_e,onMouseDown:_e,onMouseMove:_e,onMouseOut:_e,onMouseOver:_e,onMouseLeave:_e,onMouseEnter:_e,onMouseUp:_e,constructor:function(_15){this._toConnect={};for(var _16 in _15){if(this[_16]===_e){this._toConnect[_16.replace(/^on/,"").toLowerCase()]=_15[_16];delete _15[_16];}}},postCreate:function(){this.inherited(arguments);for(var _17 in this._toConnect){this.on(_17,this._toConnect[_17]);}delete this._toConnect;},on:function(_18,_19){if(this[this._onMap(_18)]===_e){return _3.connect(this.domNode,_18.toLowerCase(),this,_19);}return this.inherited(arguments);},_setFocusedAttr:function(val){this._focused=val;this._set("focused",val);},setAttribute:function(_1a,_1b){_6.deprecated(this.declaredClass+"::setAttribute(attr, value) is deprecated. Use set() instead.","","2.0");this.set(_1a,_1b);},attr:function(_1c,_1d){if(_2.isDebug){var _1e=arguments.callee._ach||(arguments.callee._ach={}),_1f=(arguments.callee.caller||"unknown caller").toString();if(!_1e[_1f]){_6.deprecated(this.declaredClass+"::attr() is deprecated. Use get() or set() instead, called from "+_1f,"","2.0");_1e[_1f]=true;}}var _20=arguments.length;if(_20>=2||typeof _1c==="object"){return this.set.apply(this,arguments);}else{return this.get(_1c);}},getDescendants:function(){_6.deprecated(this.declaredClass+"::getDescendants() is deprecated. Use getChildren() instead.","","2.0");return this.containerNode?_8("[widgetId]",this.containerNode).map(_a.byNode):[];},_onShow:function(){this.onShow();},onShow:function(){},onHide:function(){},onClose:function(){return true;}});if(_5("dijit-legacy-requires")){_9(0,function(){var _21=["dijit/_base"];require(_21);});}return _14;});

@ -0,0 +1,363 @@
define("dijit/_Widget", [
"dojo/aspect", // aspect.around
"dojo/_base/config", // config.isDebug
"dojo/_base/connect", // connect.connect
"dojo/_base/declare", // declare
"dojo/has",
"dojo/_base/kernel", // kernel.deprecated
"dojo/_base/lang", // lang.hitch
"dojo/query",
"dojo/ready",
"./registry", // registry.byNode
"./_WidgetBase",
"./_OnDijitClickMixin",
"./_FocusMixin",
"dojo/uacss", // browser sniffing (included for back-compat; subclasses may be using)
"./hccss" // high contrast mode sniffing (included to set CSS classes on <body>, module ret value unused)
], function(aspect, config, connect, declare, has, kernel, lang, query, ready,
registry, _WidgetBase, _OnDijitClickMixin, _FocusMixin){
// module:
// dijit/_Widget
function connectToDomNode(){
// summary:
// If user connects to a widget method === this function, then they will
// instead actually be connecting the equivalent event on this.domNode
}
// Trap dojo.connect() calls to connectToDomNode methods, and redirect to _Widget.on()
function aroundAdvice(originalConnect){
return function(obj, event, scope, method){
if(obj && typeof event == "string" && obj[event] == connectToDomNode){
return obj.on(event.substring(2).toLowerCase(), lang.hitch(scope, method));
}
return originalConnect.apply(connect, arguments);
};
}
aspect.around(connect, "connect", aroundAdvice);
if(kernel.connect){
aspect.around(kernel, "connect", aroundAdvice);
}
var _Widget = declare("dijit._Widget", [_WidgetBase, _OnDijitClickMixin, _FocusMixin], {
// summary:
// Old base class for widgets. New widgets should extend `dijit/_WidgetBase` instead
// description:
// Old Base class for Dijit widgets.
//
// Extends _WidgetBase, adding support for:
//
// - declaratively/programatically specifying widget initialization parameters like
// onMouseMove="foo" that call foo when this.domNode gets a mousemove event
// - ondijitclick:
// Support new data-dojo-attach-event="ondijitclick: ..." that is triggered by a mouse click or a SPACE/ENTER keypress
// - focus related functions:
// In particular, the onFocus()/onBlur() callbacks. Driven internally by
// dijit/_base/focus.js.
// - deprecated methods
// - onShow(), onHide(), onClose()
//
// Also, by loading code in dijit/_base, turns on:
//
// - browser sniffing (putting browser class like `dj_ie` on `<html>` node)
// - high contrast mode sniffing (add `dijit_a11y` class to `<body>` if machine is in high contrast mode)
////////////////// DEFERRED CONNECTS ///////////////////
onClick: connectToDomNode,
/*=====
onClick: function(event){
// summary:
// Connect to this function to receive notifications of mouse click events.
// event:
// mouse Event
// tags:
// callback
},
=====*/
onDblClick: connectToDomNode,
/*=====
onDblClick: function(event){
// summary:
// Connect to this function to receive notifications of mouse double click events.
// event:
// mouse Event
// tags:
// callback
},
=====*/
onKeyDown: connectToDomNode,
/*=====
onKeyDown: function(event){
// summary:
// Connect to this function to receive notifications of keys being pressed down.
// event:
// key Event
// tags:
// callback
},
=====*/
onKeyPress: connectToDomNode,
/*=====
onKeyPress: function(event){
// summary:
// Connect to this function to receive notifications of printable keys being typed.
// event:
// key Event
// tags:
// callback
},
=====*/
onKeyUp: connectToDomNode,
/*=====
onKeyUp: function(event){
// summary:
// Connect to this function to receive notifications of keys being released.
// event:
// key Event
// tags:
// callback
},
=====*/
onMouseDown: connectToDomNode,
/*=====
onMouseDown: function(event){
// summary:
// Connect to this function to receive notifications of when the mouse button is pressed down.
// event:
// mouse Event
// tags:
// callback
},
=====*/
onMouseMove: connectToDomNode,
/*=====
onMouseMove: function(event){
// summary:
// Connect to this function to receive notifications of when the mouse moves over nodes contained within this widget.
// event:
// mouse Event
// tags:
// callback
},
=====*/
onMouseOut: connectToDomNode,
/*=====
onMouseOut: function(event){
// summary:
// Connect to this function to receive notifications of when the mouse moves off of nodes contained within this widget.
// event:
// mouse Event
// tags:
// callback
},
=====*/
onMouseOver: connectToDomNode,
/*=====
onMouseOver: function(event){
// summary:
// Connect to this function to receive notifications of when the mouse moves onto nodes contained within this widget.
// event:
// mouse Event
// tags:
// callback
},
=====*/
onMouseLeave: connectToDomNode,
/*=====
onMouseLeave: function(event){
// summary:
// Connect to this function to receive notifications of when the mouse moves off of this widget.
// event:
// mouse Event
// tags:
// callback
},
=====*/
onMouseEnter: connectToDomNode,
/*=====
onMouseEnter: function(event){
// summary:
// Connect to this function to receive notifications of when the mouse moves onto this widget.
// event:
// mouse Event
// tags:
// callback
},
=====*/
onMouseUp: connectToDomNode,
/*=====
onMouseUp: function(event){
// summary:
// Connect to this function to receive notifications of when the mouse button is released.
// event:
// mouse Event
// tags:
// callback
},
=====*/
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
// - if this is a behavioral widget then apply behavior to that srcNodeRef
// - otherwise, replace srcNodeRef with my generated DOM tree
// extract parameters like onMouseMove that should connect directly to this.domNode
this._toConnect = {};
for(var name in params){
if(this[name] === connectToDomNode){
this._toConnect[name.replace(/^on/, "").toLowerCase()] = params[name];
delete params[name];
}
}
},
postCreate: function(){
this.inherited(arguments);
// perform connection from this.domNode to user specified handlers (ex: onMouseMove)
for(var name in this._toConnect){
this.on(name, this._toConnect[name]);
}
delete this._toConnect;
},
on: function(/*String|Function*/ type, /*Function*/ func){
if(this[this._onMap(type)] === connectToDomNode){
// Use connect.connect() rather than on() to get handling for "onmouseenter" on non-IE,
// normalization of onkeypress/onkeydown to behave like firefox, etc.
// Also, need to specify context as "this" rather than the default context of the DOMNode
// Remove in 2.0.
return connect.connect(this.domNode, type.toLowerCase(), this, func);
}
return this.inherited(arguments);
},
_setFocusedAttr: function(val){
// Remove this method in 2.0 (or sooner), just here to set _focused == focused, for back compat
// (but since it's a private variable we aren't required to keep supporting it).
this._focused = val;
this._set("focused", val);
},
////////////////// DEPRECATED METHODS ///////////////////
setAttribute: function(/*String*/ attr, /*anything*/ value){
// summary:
// Deprecated. Use set() instead.
// tags:
// deprecated
kernel.deprecated(this.declaredClass+"::setAttribute(attr, value) is deprecated. Use set() instead.", "", "2.0");
this.set(attr, value);
},
attr: function(/*String|Object*/name, /*Object?*/value){
// summary:
// Set or get properties on a widget instance.
// name:
// The property to get or set. If an object is passed here and not
// a string, its keys are used as names of attributes to be set
// and the value of the object as values to set in the widget.
// value:
// Optional. If provided, attr() operates as a setter. If omitted,
// the current value of the named property is returned.
// description:
// This method is deprecated, use get() or set() directly.
// Print deprecation warning but only once per calling function
if(config.isDebug){
var alreadyCalledHash = arguments.callee._ach || (arguments.callee._ach = {}),
caller = (arguments.callee.caller || "unknown caller").toString();
if(!alreadyCalledHash[caller]){
kernel.deprecated(this.declaredClass + "::attr() is deprecated. Use get() or set() instead, called from " +
caller, "", "2.0");
alreadyCalledHash[caller] = true;
}
}
var args = arguments.length;
if(args >= 2 || typeof name === "object"){ // setter
return this.set.apply(this, arguments);
}else{ // getter
return this.get(name);
}
},
getDescendants: function(){
// summary:
// Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
// This method should generally be avoided as it returns widgets declared in templates, which are
// supposed to be internal/hidden, but it's left here for back-compat reasons.
kernel.deprecated(this.declaredClass+"::getDescendants() is deprecated. Use getChildren() instead.", "", "2.0");
return this.containerNode ? query('[widgetId]', this.containerNode).map(registry.byNode) : []; // dijit/_WidgetBase[]
},
////////////////// MISCELLANEOUS METHODS ///////////////////
_onShow: function(){
// summary:
// Internal method called when this widget is made visible.
// See `onShow` for details.
this.onShow();
},
onShow: function(){
// summary:
// Called when this widget becomes the selected pane in a
// `dijit/layout/TabContainer`, `dijit/layout/StackContainer`,
// `dijit/layout/AccordionContainer`, etc.
//
// Also called to indicate display of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
// tags:
// callback
},
onHide: function(){
// summary:
// Called when another widget becomes the selected pane in a
// `dijit/layout/TabContainer`, `dijit/layout/StackContainer`,
// `dijit/layout/AccordionContainer`, etc.
//
// Also called to indicate hide of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
// tags:
// callback
},
onClose: function(){
// summary:
// Called when this widget is being displayed as a popup (ex: a Calendar popped
// up from a DateTextBox), and it is hidden.
// This is called from the dijit.popup code, and should not be called directly.
//
// Also used as a parameter for children of `dijit/layout/StackContainer` or subclasses.
// Callback if a user tries to close the child. Child will be closed if this function returns true.
// tags:
// extension
return true; // Boolean
}
});
// For back-compat, remove in 2.0.
if(has("dijit-legacy-requires")){
ready(0, function(){
var requires = ["dijit/_base"];
require(requires); // use indirection so modules not rolled into a build
});
}
return _Widget;
});

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -1,2 +1,2 @@
//>>built //>>built
define("dijit/_WidgetsInTemplateMixin",["dojo/_base/array","dojo/_base/declare","dojo/parser","dijit/registry"],function(_1,_2,_3,_4){return _2("dijit._WidgetsInTemplateMixin",null,{_earlyTemplatedStartup:false,widgetsInTemplate:true,_beforeFillContent:function(){if(this.widgetsInTemplate){var _5=this.domNode;var cw=(this._startupWidgets=_3.parse(_5,{noStart:!this._earlyTemplatedStartup,template:true,inherited:{dir:this.dir,lang:this.lang,textDir:this.textDir},propsThis:this,scope:"dojo"}));this._supportingWidgets=_4.findWidgets(_5);this._attachTemplateNodes(cw,function(n,p){return n[p];});}},startup:function(){_1.forEach(this._startupWidgets,function(w){if(w&&!w._started&&w.startup){w.startup();}});this.inherited(arguments);}});}); define("dijit/_WidgetsInTemplateMixin",["dojo/_base/array","dojo/_base/declare","dojo/parser"],function(_1,_2,_3){return _2("dijit._WidgetsInTemplateMixin",null,{_earlyTemplatedStartup:false,widgetsInTemplate:true,_beforeFillContent:function(){if(this.widgetsInTemplate){var _4=this.domNode;var cw=(this._startupWidgets=_3.parse(_4,{noStart:!this._earlyTemplatedStartup,template:true,inherited:{dir:this.dir,lang:this.lang,textDir:this.textDir},propsThis:this,scope:"dojo"}));if(!cw.isFulfilled()){throw new Error(this.declaredClass+": parser returned unfilled promise (probably waiting for module auto-load), "+"unsupported by _WidgetsInTemplateMixin. Must pre-load all supporting widgets before instantiation.");}this._attachTemplateNodes(cw,function(n,p){return n[p];});}},startup:function(){_1.forEach(this._startupWidgets,function(w){if(w&&!w._started&&w.startup){w.startup();}});this.inherited(arguments);}});});

@ -0,0 +1,65 @@
define("dijit/_WidgetsInTemplateMixin", [
"dojo/_base/array", // array.forEach
"dojo/_base/declare", // declare
"dojo/parser" // parser.parse
], function(array, declare, parser){
// module:
// dijit/_WidgetsInTemplateMixin
return declare("dijit._WidgetsInTemplateMixin", null, {
// summary:
// Mixin to supplement _TemplatedMixin when template contains widgets
// _earlyTemplatedStartup: Boolean
// A fallback to preserve the 1.0 - 1.3 behavior of children in
// templates having their startup called before the parent widget
// fires postCreate. Defaults to 'false', causing child widgets to
// have their .startup() called immediately before a parent widget
// .startup(), but always after the parent .postCreate(). Set to
// 'true' to re-enable to previous, arguably broken, behavior.
_earlyTemplatedStartup: false,
// widgetsInTemplate: [protected] Boolean
// Should we parse the template to find widgets that might be
// declared in markup inside it? (Remove for 2.0 and assume true)
widgetsInTemplate: true,
_beforeFillContent: function(){
if(this.widgetsInTemplate){
// Before copying over content, instantiate widgets in template
var node = this.domNode;
var cw = (this._startupWidgets = parser.parse(node, {
noStart: !this._earlyTemplatedStartup,
template: true,
inherited: {dir: this.dir, lang: this.lang, textDir: this.textDir},
propsThis: this, // so data-dojo-props of widgets in the template can reference "this" to refer to me
scope: "dojo" // even in multi-version mode templates use dojoType/data-dojo-type
}));
if(!cw.isFulfilled()){
throw new Error(this.declaredClass + ": parser returned unfilled promise (probably waiting for module auto-load), " +
"unsupported by _WidgetsInTemplateMixin. Must pre-load all supporting widgets before instantiation.");
}
// _WidgetBase::destroy() will destroy any supporting widgets under this.domNode.
// If we wanted to, we could call this.own() on anything in this._startupWidgets that was moved outside
// of this.domNode (like Dialog, which is moved to <body>).
this._attachTemplateNodes(cw, function(n,p){
return n[p];
});
}
},
startup: function(){
array.forEach(this._startupWidgets, function(w){
if(w && !w._started && w.startup){
w.startup();
}
});
this.inherited(arguments);
}
});
});

@ -1,2 +1,2 @@
//>>built //>>built
define("dijit/_base",[".","./a11y","./WidgetSet","./_base/focus","./_base/manager","./_base/place","./_base/popup","./_base/scroll","./_base/sniff","./_base/typematic","./_base/wai","./_base/window"],function(_1){return _1._base;}); define("dijit/_base",["./main","./a11y","./WidgetSet","./_base/focus","./_base/manager","./_base/place","./_base/popup","./_base/scroll","./_base/sniff","./_base/typematic","./_base/wai","./_base/window"],function(_1){return _1._base;});

@ -0,0 +1,27 @@
define("dijit/_base", [
"./main",
"./a11y", // used to be in dijit/_base/manager
"./WidgetSet", // used to be in dijit/_base/manager
"./_base/focus",
"./_base/manager",
"./_base/place",
"./_base/popup",
"./_base/scroll",
"./_base/sniff",
"./_base/typematic",
"./_base/wai",
"./_base/window"
], function(dijit){
// module:
// dijit/_base
/*=====
return {
// summary:
// Includes all the modules in dijit/_base
};
=====*/
return dijit._base;
});

@ -1,2 +1,2 @@
//>>built //>>built
define("dijit/_base/focus",["dojo/_base/array","dojo/dom","dojo/_base/lang","dojo/topic","dojo/_base/window","../focus",".."],function(_1,_2,_3,_4,_5,_6,_7){_3.mixin(_7,{_curFocus:null,_prevFocus:null,isCollapsed:function(){return _7.getBookmark().isCollapsed;},getBookmark:function(){var bm,rg,tg,_8=_5.doc.selection,cf=_6.curNode;if(_5.global.getSelection){_8=_5.global.getSelection();if(_8){if(_8.isCollapsed){tg=cf?cf.tagName:"";if(tg){tg=tg.toLowerCase();if(tg=="textarea"||(tg=="input"&&(!cf.type||cf.type.toLowerCase()=="text"))){_8={start:cf.selectionStart,end:cf.selectionEnd,node:cf,pRange:true};return {isCollapsed:(_8.end<=_8.start),mark:_8};}}bm={isCollapsed:true};if(_8.rangeCount){bm.mark=_8.getRangeAt(0).cloneRange();}}else{rg=_8.getRangeAt(0);bm={isCollapsed:false,mark:rg.cloneRange()};}}}else{if(_8){tg=cf?cf.tagName:"";tg=tg.toLowerCase();if(cf&&tg&&(tg=="button"||tg=="textarea"||tg=="input")){if(_8.type&&_8.type.toLowerCase()=="none"){return {isCollapsed:true,mark:null};}else{rg=_8.createRange();return {isCollapsed:rg.text&&rg.text.length?false:true,mark:{range:rg,pRange:true}};}}bm={};try{rg=_8.createRange();bm.isCollapsed=!(_8.type=="Text"?rg.htmlText.length:rg.length);}catch(e){bm.isCollapsed=true;return bm;}if(_8.type.toUpperCase()=="CONTROL"){if(rg.length){bm.mark=[];var i=0,_9=rg.length;while(i<_9){bm.mark.push(rg.item(i++));}}else{bm.isCollapsed=true;bm.mark=null;}}else{bm.mark=rg.getBookmark();}}else{console.warn("No idea how to store the current selection for this browser!");}}return bm;},moveToBookmark:function(_a){var _b=_5.doc,_c=_a.mark;if(_c){if(_5.global.getSelection){var _d=_5.global.getSelection();if(_d&&_d.removeAllRanges){if(_c.pRange){var n=_c.node;n.selectionStart=_c.start;n.selectionEnd=_c.end;}else{_d.removeAllRanges();_d.addRange(_c);}}else{console.warn("No idea how to restore selection for this browser!");}}else{if(_b.selection&&_c){var rg;if(_c.pRange){rg=_c.range;}else{if(_3.isArray(_c)){rg=_b.body.createControlRange();_1.forEach(_c,function(n){rg.addElement(n);});}else{rg=_b.body.createTextRange();rg.moveToBookmark(_c);}}rg.select();}}}},getFocus:function(_e,_f){var _10=!_6.curNode||(_e&&_2.isDescendant(_6.curNode,_e.domNode))?_7._prevFocus:_6.curNode;return {node:_10,bookmark:_10&&(_10==_6.curNode)&&_5.withGlobal(_f||_5.global,_7.getBookmark),openedForWindow:_f};},_activeStack:[],registerIframe:function(_11){return _6.registerIframe(_11);},unregisterIframe:function(_12){_12&&_12.remove();},registerWin:function(_13,_14){return _6.registerWin(_13,_14);},unregisterWin:function(_15){_15&&_15.remove();}});_6.focus=function(_16){if(!_16){return;}var _17="node" in _16?_16.node:_16,_18=_16.bookmark,_19=_16.openedForWindow,_1a=_18?_18.isCollapsed:false;if(_17){var _1b=(_17.tagName.toLowerCase()=="iframe")?_17.contentWindow:_17;if(_1b&&_1b.focus){try{_1b.focus();}catch(e){}}_6._onFocusNode(_17);}if(_18&&_5.withGlobal(_19||_5.global,_7.isCollapsed)&&!_1a){if(_19){_19.focus();}try{_5.withGlobal(_19||_5.global,_7.moveToBookmark,null,[_18]);}catch(e2){}}};_6.watch("curNode",function(_1c,_1d,_1e){_7._curFocus=_1e;_7._prevFocus=_1d;if(_1e){_4.publish("focusNode",_1e);}});_6.watch("activeStack",function(_1f,_20,_21){_7._activeStack=_21;});_6.on("widget-blur",function(_22,by){_4.publish("widgetBlur",_22,by);});_6.on("widget-focus",function(_23,by){_4.publish("widgetFocus",_23,by);});return _7;}); define("dijit/_base/focus",["dojo/_base/array","dojo/dom","dojo/_base/lang","dojo/topic","dojo/_base/window","../focus","../main"],function(_1,_2,_3,_4,_5,_6,_7){var _8={_curFocus:null,_prevFocus:null,isCollapsed:function(){return _7.getBookmark().isCollapsed;},getBookmark:function(){var bm,rg,tg,_9=_5.doc.selection,cf=_6.curNode;if(_5.global.getSelection){_9=_5.global.getSelection();if(_9){if(_9.isCollapsed){tg=cf?cf.tagName:"";if(tg){tg=tg.toLowerCase();if(tg=="textarea"||(tg=="input"&&(!cf.type||cf.type.toLowerCase()=="text"))){_9={start:cf.selectionStart,end:cf.selectionEnd,node:cf,pRange:true};return {isCollapsed:(_9.end<=_9.start),mark:_9};}}bm={isCollapsed:true};if(_9.rangeCount){bm.mark=_9.getRangeAt(0).cloneRange();}}else{rg=_9.getRangeAt(0);bm={isCollapsed:false,mark:rg.cloneRange()};}}}else{if(_9){tg=cf?cf.tagName:"";tg=tg.toLowerCase();if(cf&&tg&&(tg=="button"||tg=="textarea"||tg=="input")){if(_9.type&&_9.type.toLowerCase()=="none"){return {isCollapsed:true,mark:null};}else{rg=_9.createRange();return {isCollapsed:rg.text&&rg.text.length?false:true,mark:{range:rg,pRange:true}};}}bm={};try{rg=_9.createRange();bm.isCollapsed=!(_9.type=="Text"?rg.htmlText.length:rg.length);}catch(e){bm.isCollapsed=true;return bm;}if(_9.type.toUpperCase()=="CONTROL"){if(rg.length){bm.mark=[];var i=0,_a=rg.length;while(i<_a){bm.mark.push(rg.item(i++));}}else{bm.isCollapsed=true;bm.mark=null;}}else{bm.mark=rg.getBookmark();}}else{console.warn("No idea how to store the current selection for this browser!");}}return bm;},moveToBookmark:function(_b){var _c=_5.doc,_d=_b.mark;if(_d){if(_5.global.getSelection){var _e=_5.global.getSelection();if(_e&&_e.removeAllRanges){if(_d.pRange){var n=_d.node;n.selectionStart=_d.start;n.selectionEnd=_d.end;}else{_e.removeAllRanges();_e.addRange(_d);}}else{console.warn("No idea how to restore selection for this browser!");}}else{if(_c.selection&&_d){var rg;if(_d.pRange){rg=_d.range;}else{if(_3.isArray(_d)){rg=_c.body.createControlRange();_1.forEach(_d,function(n){rg.addElement(n);});}else{rg=_c.body.createTextRange();rg.moveToBookmark(_d);}}rg.select();}}}},getFocus:function(_f,_10){var _11=!_6.curNode||(_f&&_2.isDescendant(_6.curNode,_f.domNode))?_7._prevFocus:_6.curNode;return {node:_11,bookmark:_11&&(_11==_6.curNode)&&_5.withGlobal(_10||_5.global,_7.getBookmark),openedForWindow:_10};},_activeStack:[],registerIframe:function(_12){return _6.registerIframe(_12);},unregisterIframe:function(_13){_13&&_13.remove();},registerWin:function(_14,_15){return _6.registerWin(_14,_15);},unregisterWin:function(_16){_16&&_16.remove();}};_6.focus=function(_17){if(!_17){return;}var _18="node" in _17?_17.node:_17,_19=_17.bookmark,_1a=_17.openedForWindow,_1b=_19?_19.isCollapsed:false;if(_18){var _1c=(_18.tagName.toLowerCase()=="iframe")?_18.contentWindow:_18;if(_1c&&_1c.focus){try{_1c.focus();}catch(e){}}_6._onFocusNode(_18);}if(_19&&_5.withGlobal(_1a||_5.global,_7.isCollapsed)&&!_1b){if(_1a){_1a.focus();}try{_5.withGlobal(_1a||_5.global,_7.moveToBookmark,null,[_19]);}catch(e2){}}};_6.watch("curNode",function(_1d,_1e,_1f){_7._curFocus=_1f;_7._prevFocus=_1e;if(_1f){_4.publish("focusNode",_1f);}});_6.watch("activeStack",function(_20,_21,_22){_7._activeStack=_22;});_6.on("widget-blur",function(_23,by){_4.publish("widgetBlur",_23,by);});_6.on("widget-focus",function(_24,by){_4.publish("widgetFocus",_24,by);});_3.mixin(_7,_8);return _7;});

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

Loading…
Cancel
Save