Преглед изворни кода

Merge remote-tracking branch 'origin/candidate-4.0.0' into candidate-4.0.2

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman пре 12 година
родитељ
комит
ef05d63059
44 измењених фајлова са 3465 додато и 0 уклоњено
  1. 18 0
      esp/files/dijit/form/templates/Button.html
  2. 7 0
      esp/files/dijit/form/templates/CheckBox.html
  3. 24 0
      esp/files/dijit/form/templates/ComboButton.html
  4. 18 0
      esp/files/dijit/form/templates/DropDownBox.html
  5. 21 0
      esp/files/dijit/form/templates/DropDownButton.html
  6. 38 0
      esp/files/dijit/form/templates/HorizontalSlider.html
  7. 18 0
      esp/files/dijit/form/templates/Select.html
  8. 27 0
      esp/files/dijit/form/templates/Spinner.html
  9. 6 0
      esp/files/dijit/form/templates/TextBox.html
  10. 10 0
      esp/files/dijit/form/templates/ValidationTextBox.html
  11. 46 0
      esp/files/dijit/form/templates/VerticalSlider.html
  12. 10 0
      esp/files/dijit/layout/templates/AccordionButton.html
  13. 22 0
      esp/files/dijit/layout/templates/ScrollingTabController.html
  14. 5 0
      esp/files/dijit/layout/templates/TabContainer.html
  15. 4 0
      esp/files/dijit/layout/templates/_ScrollingTabControllerButton.html
  16. 8 0
      esp/files/dijit/layout/templates/_TabButton.html
  17. 8 0
      esp/files/dijit/robot.js
  18. 25 0
      esp/files/dijit/robotx.js
  19. 35 0
      esp/files/dijit/templates/Calendar.html
  20. 9 0
      esp/files/dijit/templates/CheckedMenuItem.html
  21. 5 0
      esp/files/dijit/templates/ColorPalette.html
  22. 10 0
      esp/files/dijit/templates/Dialog.html
  23. 15 0
      esp/files/dijit/templates/Fieldset.html
  24. 9 0
      esp/files/dijit/templates/InlineEditBox.html
  25. 4 0
      esp/files/dijit/templates/Menu.html
  26. 2 0
      esp/files/dijit/templates/MenuBar.html
  27. 4 0
      esp/files/dijit/templates/MenuBarItem.html
  28. 13 0
      esp/files/dijit/templates/MenuItem.html
  29. 10 0
      esp/files/dijit/templates/MenuSeparator.html
  30. 9 0
      esp/files/dijit/templates/ProgressBar.html
  31. 17 0
      esp/files/dijit/templates/TitlePane.html
  32. 4 0
      esp/files/dijit/templates/Tooltip.html
  33. 6 0
      esp/files/dijit/templates/TooltipDialog.html
  34. 6 0
      esp/files/dijit/templates/Tree.html
  35. 12 0
      esp/files/dijit/templates/TreeNode.html
  36. 1242 0
      esp/files/dijit/themes/themeTester-orig.html
  37. 1379 0
      esp/files/dijit/themes/themeTester.html
  38. BIN
      esp/files/dijit/themes/themeTesterImages/blackButtonEnabled.gif
  39. BIN
      esp/files/dijit/themes/themeTesterImages/blackButtonHover.gif
  40. 5 0
      esp/files/dijit/themes/themeTesterQuirk.html
  41. 170 0
      esp/files/dojo/robot.js
  42. 171 0
      esp/files/dojo/robotx.js
  43. 13 0
      esp/files/dojo/tests.js
  44. BIN
      esp/files/img/queries_icon.png

+ 18 - 0
esp/files/dijit/form/templates/Button.html

@@ -0,0 +1,18 @@
+<span class="dijit dijitReset dijitInline" role="presentation"
+	><span class="dijitReset dijitInline dijitButtonNode"
+		data-dojo-attach-event="ondijitclick:__onClick" role="presentation"
+		><span class="dijitReset dijitStretch dijitButtonContents"
+			data-dojo-attach-point="titleNode,focusNode"
+			role="button" aria-labelledby="${id}_label"
+			><span class="dijitReset dijitInline dijitIcon" data-dojo-attach-point="iconNode"></span
+			><span class="dijitReset dijitToggleButtonIconChar">&#x25CF;</span
+			><span class="dijitReset dijitInline dijitButtonText"
+				id="${id}_label"
+				data-dojo-attach-point="containerNode"
+			></span
+		></span
+	></span
+	><input ${!nameAttrSetting} type="${type}" value="${value}" class="dijitOffScreen"
+		data-dojo-attach-event="onclick:_onClick"
+		tabIndex="-1" role="presentation" data-dojo-attach-point="valueNode"
+/></span>

+ 7 - 0
esp/files/dijit/form/templates/CheckBox.html

@@ -0,0 +1,7 @@
+<div class="dijit dijitReset dijitInline" role="presentation"
+	><input
+	 	${!nameAttrSetting} type="${type}" role="${type}" aria-checked="false" ${checkedAttrSetting}
+		class="dijitReset dijitCheckBoxInput"
+		data-dojo-attach-point="focusNode"
+	 	data-dojo-attach-event="ondijitclick:_onClick"
+/></div>

+ 24 - 0
esp/files/dijit/form/templates/ComboButton.html

@@ -0,0 +1,24 @@
+<table class="dijit dijitReset dijitInline dijitLeft"
+	cellspacing='0' cellpadding='0' role="presentation"
+	><tbody role="presentation"><tr role="presentation"
+		><td class="dijitReset dijitStretch dijitButtonNode" data-dojo-attach-point="buttonNode" data-dojo-attach-event="ondijitclick:__onClick,onkeydown:_onButtonKeyDown"
+		><div id="${id}_button" class="dijitReset dijitButtonContents"
+			data-dojo-attach-point="titleNode"
+			role="button" aria-labelledby="${id}_label"
+			><div class="dijitReset dijitInline dijitIcon" data-dojo-attach-point="iconNode" role="presentation"></div
+			><div class="dijitReset dijitInline dijitButtonText" id="${id}_label" data-dojo-attach-point="containerNode" role="presentation"></div
+		></div
+		></td
+		><td id="${id}_arrow" class='dijitReset dijitRight dijitButtonNode dijitArrowButton'
+			data-dojo-attach-point="_popupStateNode,focusNode,_buttonNode"
+			data-dojo-attach-event="onkeydown:_onArrowKeyDown"
+			title="${optionsTitle}"
+			role="button" aria-haspopup="true"
+			><div class="dijitReset dijitArrowButtonInner" role="presentation"></div
+			><div class="dijitReset dijitArrowButtonChar" role="presentation">&#9660;</div
+		></td
+		><td style="display:none !important;"
+			><input ${!nameAttrSetting} type="${type}" value="${value}" data-dojo-attach-point="valueNode" role="presentation"
+				data-dojo-attach-event="onclick:_onClick"
+		/></td></tr></tbody
+></table>

+ 18 - 0
esp/files/dijit/form/templates/DropDownBox.html

@@ -0,0 +1,18 @@
+<div class="dijit dijitReset dijitInline dijitLeft"
+	id="widget_${id}"
+	role="combobox"
+	aria-haspopup="true"
+	data-dojo-attach-point="_popupStateNode"
+	><div class='dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton dijitArrowButtonContainer'
+		data-dojo-attach-point="_buttonNode" role="presentation"
+		><input class="dijitReset dijitInputField dijitArrowButtonInner" value="&#9660; " type="text" tabIndex="-1" readonly="readonly" role="button presentation" aria-hidden="true"
+			${_buttonInputDisabled}
+	/></div
+	><div class='dijitReset dijitValidationContainer'
+		><input class="dijitReset dijitInputField dijitValidationIcon dijitValidationInner" value="&#935; " type="text" tabIndex="-1" readonly="readonly" role="presentation"
+	/></div
+	><div class="dijitReset dijitInputField dijitInputContainer"
+		><input class='dijitReset dijitInputInner' ${!nameAttrSetting} type="text" autocomplete="off"
+			data-dojo-attach-point="textbox,focusNode" role="textbox"
+	/></div
+></div>

+ 21 - 0
esp/files/dijit/form/templates/DropDownButton.html

@@ -0,0 +1,21 @@
+<span class="dijit dijitReset dijitInline"
+	><span class='dijitReset dijitInline dijitButtonNode'
+		data-dojo-attach-event="ondijitclick:__onClick" data-dojo-attach-point="_buttonNode"
+		><span class="dijitReset dijitStretch dijitButtonContents"
+			data-dojo-attach-point="focusNode,titleNode,_arrowWrapperNode,_popupStateNode"
+			role="button" aria-haspopup="true" aria-labelledby="${id}_label"
+			><span class="dijitReset dijitInline dijitIcon"
+				data-dojo-attach-point="iconNode"
+			></span
+			><span class="dijitReset dijitInline dijitButtonText"
+				data-dojo-attach-point="containerNode"
+				id="${id}_label"
+			></span
+			><span class="dijitReset dijitInline dijitArrowButtonInner"></span
+			><span class="dijitReset dijitInline dijitArrowButtonChar">&#9660;</span
+		></span
+	></span
+	><input ${!nameAttrSetting} type="${type}" value="${value}" class="dijitOffScreen" tabIndex="-1"
+		data-dojo-attach-event="onclick:_onClick"
+		data-dojo-attach-point="valueNode" role="presentation"
+/></span>

+ 38 - 0
esp/files/dijit/form/templates/HorizontalSlider.html

@@ -0,0 +1,38 @@
+<table class="dijit dijitReset dijitSlider dijitSliderH" cellspacing="0" cellpadding="0" border="0" rules="none" data-dojo-attach-event="onkeydown:_onKeyDown, onkeyup:_onKeyUp"
+	role="presentation"
+	><tr class="dijitReset"
+		><td class="dijitReset" colspan="2"></td
+		><td data-dojo-attach-point="topDecoration" class="dijitReset dijitSliderDecoration dijitSliderDecorationT dijitSliderDecorationH"></td
+		><td class="dijitReset" colspan="2"></td
+	></tr
+	><tr class="dijitReset"
+		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerH"
+			><div class="dijitSliderDecrementIconH" style="display:none" data-dojo-attach-point="decrementButton"><span class="dijitSliderButtonInner">-</span></div
+		></td
+		><td class="dijitReset"
+			><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperH dijitSliderLeftBumper" data-dojo-attach-event="press:_onClkDecBumper"></div
+		></td
+		><td class="dijitReset"
+			><input data-dojo-attach-point="valueNode" type="hidden" ${!nameAttrSetting}
+			/><div class="dijitReset dijitSliderBarContainerH" role="presentation" data-dojo-attach-point="sliderBarContainer"
+				><div role="presentation" data-dojo-attach-point="progressBar" class="dijitSliderBar dijitSliderBarH dijitSliderProgressBar dijitSliderProgressBarH" data-dojo-attach-event="press:_onBarClick"
+					><div class="dijitSliderMoveable dijitSliderMoveableH"
+						><div data-dojo-attach-point="sliderHandle,focusNode" class="dijitSliderImageHandle dijitSliderImageHandleH" data-dojo-attach-event="press:_onHandleClick" role="slider"></div
+					></div
+				></div
+				><div role="presentation" data-dojo-attach-point="remainingBar" class="dijitSliderBar dijitSliderBarH dijitSliderRemainingBar dijitSliderRemainingBarH" data-dojo-attach-event="press:_onBarClick"></div
+			></div
+		></td
+		><td class="dijitReset"
+			><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperH dijitSliderRightBumper" data-dojo-attach-event="press:_onClkIncBumper"></div
+		></td
+		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerH"
+			><div class="dijitSliderIncrementIconH" style="display:none" data-dojo-attach-point="incrementButton"><span class="dijitSliderButtonInner">+</span></div
+		></td
+	></tr
+	><tr class="dijitReset"
+		><td class="dijitReset" colspan="2"></td
+		><td data-dojo-attach-point="containerNode,bottomDecoration" class="dijitReset dijitSliderDecoration dijitSliderDecorationB dijitSliderDecorationH"></td
+		><td class="dijitReset" colspan="2"></td
+	></tr
+></table>

+ 18 - 0
esp/files/dijit/form/templates/Select.html

@@ -0,0 +1,18 @@
+<table class="dijit dijitReset dijitInline dijitLeft"
+	data-dojo-attach-point="_buttonNode,tableNode,focusNode,_popupStateNode" cellspacing='0' cellpadding='0'
+	role="listbox" aria-haspopup="true"
+	><tbody role="presentation"><tr role="presentation"
+		><td class="dijitReset dijitStretch dijitButtonContents" role="presentation"
+			><div class="dijitReset dijitInputField dijitButtonText"  data-dojo-attach-point="containerNode,textDirNode" role="presentation"></div
+			><div class="dijitReset dijitValidationContainer"
+				><input class="dijitReset dijitInputField dijitValidationIcon dijitValidationInner" value="&#935; " type="text" tabIndex="-1" readonly="readonly" role="presentation"
+			/></div
+			><input type="hidden" ${!nameAttrSetting} data-dojo-attach-point="valueNode" value="${value}" aria-hidden="true"
+		/></td
+		><td class="dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton dijitArrowButtonContainer"
+			data-dojo-attach-point="titleNode" role="presentation"
+			><input class="dijitReset dijitInputField dijitArrowButtonInner" value="&#9660; " type="text" tabIndex="-1" readonly="readonly" role="presentation"
+				${_buttonInputDisabled}
+		/></td
+	></tr></tbody
+></table>

+ 27 - 0
esp/files/dijit/form/templates/Spinner.html

@@ -0,0 +1,27 @@
+<div class="dijit dijitReset dijitInline dijitLeft"
+	id="widget_${id}" role="presentation"
+	><div class="dijitReset dijitButtonNode dijitSpinnerButtonContainer"
+		><input class="dijitReset dijitInputField dijitSpinnerButtonInner" type="text" tabIndex="-1" readonly="readonly" role="presentation"
+		/><div class="dijitReset dijitLeft dijitButtonNode dijitArrowButton dijitUpArrowButton"
+			data-dojo-attach-point="upArrowNode"
+			><div class="dijitArrowButtonInner"
+				><input class="dijitReset dijitInputField" value="&#9650; " type="text" tabIndex="-1" readonly="readonly" role="presentation"
+					${_buttonInputDisabled}
+			/></div
+		></div
+		><div class="dijitReset dijitLeft dijitButtonNode dijitArrowButton dijitDownArrowButton"
+			data-dojo-attach-point="downArrowNode"
+			><div class="dijitArrowButtonInner"
+				><input class="dijitReset dijitInputField" value="&#9660; " type="text" tabIndex="-1" readonly="readonly" role="presentation"
+					${_buttonInputDisabled}
+			/></div
+		></div
+	></div
+	><div class='dijitReset dijitValidationContainer'
+		><input class="dijitReset dijitInputField dijitValidationIcon dijitValidationInner" value="&#935; " type="text" tabIndex="-1" readonly="readonly" role="presentation"
+	/></div
+	><div class="dijitReset dijitInputField dijitInputContainer"
+		><input class='dijitReset dijitInputInner' data-dojo-attach-point="textbox,focusNode" type="${type}" data-dojo-attach-event="onkeydown:_onKeyDown"
+			role="spinbutton" autocomplete="off" ${!nameAttrSetting}
+	/></div
+></div>

+ 6 - 0
esp/files/dijit/form/templates/TextBox.html

@@ -0,0 +1,6 @@
+<div class="dijit dijitReset dijitInline dijitLeft" id="widget_${id}" role="presentation"
+	><div class="dijitReset dijitInputField dijitInputContainer"
+		><input class="dijitReset dijitInputInner" data-dojo-attach-point='textbox,focusNode' autocomplete="off"
+			${!nameAttrSetting} type='${type}'
+	/></div
+></div>

+ 10 - 0
esp/files/dijit/form/templates/ValidationTextBox.html

@@ -0,0 +1,10 @@
+<div class="dijit dijitReset dijitInline dijitLeft"
+	id="widget_${id}" role="presentation"
+	><div class='dijitReset dijitValidationContainer'
+		><input class="dijitReset dijitInputField dijitValidationIcon dijitValidationInner" value="&#935; " type="text" tabIndex="-1" readonly="readonly" role="presentation"
+	/></div
+	><div class="dijitReset dijitInputField dijitInputContainer"
+		><input class="dijitReset dijitInputInner" data-dojo-attach-point='textbox,focusNode' autocomplete="off"
+			${!nameAttrSetting} type='${type}'
+	/></div
+></div>

+ 46 - 0
esp/files/dijit/form/templates/VerticalSlider.html

@@ -0,0 +1,46 @@
+<table class="dijit dijitReset dijitSlider dijitSliderV" cellspacing="0" cellpadding="0" border="0" rules="none" data-dojo-attach-event="onkeydown:_onKeyDown,onkeyup:_onKeyUp"
+	role="presentation"
+	><tr class="dijitReset"
+		><td class="dijitReset"></td
+		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV"
+			><div class="dijitSliderIncrementIconV" style="display:none" data-dojo-attach-point="decrementButton"><span class="dijitSliderButtonInner">+</span></div
+		></td
+		><td class="dijitReset"></td
+	></tr
+	><tr class="dijitReset"
+		><td class="dijitReset"></td
+		><td class="dijitReset"
+			><center><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperV dijitSliderTopBumper" data-dojo-attach-event="press:_onClkIncBumper"></div></center
+		></td
+		><td class="dijitReset"></td
+	></tr
+	><tr class="dijitReset"
+		><td data-dojo-attach-point="leftDecoration" class="dijitReset dijitSliderDecoration dijitSliderDecorationL dijitSliderDecorationV"></td
+		><td class="dijitReset dijitSliderDecorationC" style="height:100%;"
+			><input data-dojo-attach-point="valueNode" type="hidden" ${!nameAttrSetting}
+			/><center class="dijitReset dijitSliderBarContainerV" role="presentation" data-dojo-attach-point="sliderBarContainer"
+				><div role="presentation" data-dojo-attach-point="remainingBar" class="dijitSliderBar dijitSliderBarV dijitSliderRemainingBar dijitSliderRemainingBarV" data-dojo-attach-event="press:_onBarClick"><!--#5629--></div
+				><div role="presentation" data-dojo-attach-point="progressBar" class="dijitSliderBar dijitSliderBarV dijitSliderProgressBar dijitSliderProgressBarV" data-dojo-attach-event="press:_onBarClick"
+					><div class="dijitSliderMoveable dijitSliderMoveableV" style="vertical-align:top;"
+						><div data-dojo-attach-point="sliderHandle,focusNode" class="dijitSliderImageHandle dijitSliderImageHandleV" data-dojo-attach-event="press:_onHandleClick" role="slider"></div
+					></div
+				></div
+			></center
+		></td
+		><td data-dojo-attach-point="containerNode,rightDecoration" class="dijitReset dijitSliderDecoration dijitSliderDecorationR dijitSliderDecorationV"></td
+	></tr
+	><tr class="dijitReset"
+		><td class="dijitReset"></td
+		><td class="dijitReset"
+			><center><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperV dijitSliderBottomBumper" data-dojo-attach-event="press:_onClkDecBumper"></div></center
+		></td
+		><td class="dijitReset"></td
+	></tr
+	><tr class="dijitReset"
+		><td class="dijitReset"></td
+		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV"
+			><div class="dijitSliderDecrementIconV" style="display:none" data-dojo-attach-point="incrementButton"><span class="dijitSliderButtonInner">-</span></div
+		></td
+		><td class="dijitReset"></td
+	></tr
+></table>

+ 10 - 0
esp/files/dijit/layout/templates/AccordionButton.html

@@ -0,0 +1,10 @@
+<div data-dojo-attach-event='ondijitclick:_onTitleClick' class='dijitAccordionTitle' role="presentation">
+	<div data-dojo-attach-point='titleNode,focusNode' data-dojo-attach-event='onkeydown:_onTitleKeyDown'
+			class='dijitAccordionTitleFocus' role="tab" aria-expanded="false"
+		><span class='dijitInline dijitAccordionArrow' role="presentation"></span
+		><span class='arrowTextUp' role="presentation">+</span
+		><span class='arrowTextDown' role="presentation">-</span
+		><span role="presentation" class="dijitInline dijitIcon" data-dojo-attach-point="iconNode"></span>
+		<span role="presentation" data-dojo-attach-point='titleTextNode, textDirNode' class='dijitAccordionText'></span>
+	</div>
+</div>

+ 22 - 0
esp/files/dijit/layout/templates/ScrollingTabController.html

@@ -0,0 +1,22 @@
+<div class="dijitTabListContainer-${tabPosition}" style="visibility:hidden">
+	<div data-dojo-type="dijit.layout._ScrollingTabControllerMenuButton"
+		 class="tabStripButton-${tabPosition}"
+		 id="${id}_menuBtn"
+		 data-dojo-props="containerId: '${containerId}', iconClass: 'dijitTabStripMenuIcon',
+					dropDownPosition: ['below-alt', 'above-alt']"
+		 data-dojo-attach-point="_menuBtn" showLabel="false" title="">&#9660;</div>
+	<div data-dojo-type="dijit.layout._ScrollingTabControllerButton"
+		 class="tabStripButton-${tabPosition}"
+		 id="${id}_leftBtn"
+		 data-dojo-props="iconClass:'dijitTabStripSlideLeftIcon', showLabel:false, title:''"
+		 data-dojo-attach-point="_leftBtn" data-dojo-attach-event="onClick: doSlideLeft">&#9664;</div>
+	<div data-dojo-type="dijit.layout._ScrollingTabControllerButton"
+		 class="tabStripButton-${tabPosition}"
+		 id="${id}_rightBtn"
+		 data-dojo-props="iconClass:'dijitTabStripSlideRightIcon', showLabel:false, title:''"
+		 data-dojo-attach-point="_rightBtn" data-dojo-attach-event="onClick: doSlideRight">&#9654;</div>
+	<div class='dijitTabListWrapper' data-dojo-attach-point='tablistWrapper'>
+		<div role='tablist' data-dojo-attach-event='onkeydown:onkeydown'
+			 data-dojo-attach-point='containerNode' class='nowrapTabStrip'></div>
+	</div>
+</div>

+ 5 - 0
esp/files/dijit/layout/templates/TabContainer.html

@@ -0,0 +1,5 @@
+<div class="dijitTabContainer">
+	<div class="dijitTabListWrapper" data-dojo-attach-point="tablistNode"></div>
+	<div data-dojo-attach-point="tablistSpacer" class="dijitTabSpacer ${baseClass}-spacer"></div>
+	<div class="dijitTabPaneWrapper ${baseClass}-container" data-dojo-attach-point="containerNode"></div>
+</div>

+ 4 - 0
esp/files/dijit/layout/templates/_ScrollingTabControllerButton.html

@@ -0,0 +1,4 @@
+<div data-dojo-attach-event="ondijitclick:_onClick" class="dijitTabInnerDiv dijitTabContent dijitButtonContents"  data-dojo-attach-point="focusNode" role="button">
+	<span role="presentation" class="dijitInline dijitTabStripIcon" data-dojo-attach-point="iconNode"></span>
+	<span data-dojo-attach-point="containerNode,titleNode" class="dijitButtonText"></span>
+</div>

+ 8 - 0
esp/files/dijit/layout/templates/_TabButton.html

@@ -0,0 +1,8 @@
+<div role="presentation" data-dojo-attach-point="titleNode,innerDiv,tabContent" class="dijitTabInner dijitTabContent">
+	<span role="presentation" class="dijitInline dijitIcon dijitTabButtonIcon" data-dojo-attach-point="iconNode"></span>
+	<span data-dojo-attach-point='containerNode,focusNode' class='tabLabel'></span>
+	<span class="dijitInline dijitTabCloseButton dijitTabCloseIcon" data-dojo-attach-point='closeNode'
+		  role="presentation">
+		<span data-dojo-attach-point='closeText' class='dijitTabCloseText'>[x]</span
+				></span>
+</div>

+ 8 - 0
esp/files/dijit/robot.js

@@ -0,0 +1,8 @@
+define([
+	"dojo/robot"
+], function(){
+	// module:
+	//		dijit/robot
+	// summary:
+	//		Used to have code needed by robot test harness, but no longer
+});

+ 25 - 0
esp/files/dijit/robotx.js

@@ -0,0 +1,25 @@
+define([
+	"dojo/_base/kernel", // kernel.experimental
+	"dojo/robotx"		// includes doh/robot, dojo/robot, and dojo/robotx, all of which affect and return doh/robot module
+], function(kernel, robot){
+
+	// module:
+	//		dijit/robotx
+	// summary:
+	//		Loads doh/robot, dojo/robot, dojo/robotx, and
+	//		sets dijit global in main window to point to the dijit loaded in the iframe.
+	//		TODO: Remove for 2.0.    Tests shouldn't reference a dijit global at all, and should load dojo/robotx
+	//		in preference to this file.
+
+	kernel.experimental("dijit.robotx");
+
+	var __updateDocument = robot._updateDocument;
+
+	robot._updateDocument = function(){
+		__updateDocument();
+		var win = kernel.global;
+		if(win.dijit){
+			window.dijit = win.dijit; // window reference needed for IE
+		}
+	};
+});

+ 35 - 0
esp/files/dijit/templates/Calendar.html

@@ -0,0 +1,35 @@
+<table cellspacing="0" cellpadding="0" class="dijitCalendarContainer" role="grid" aria-labelledby="${id}_mddb ${id}_year" data-dojo-attach-point="gridNode">
+	<thead>
+		<tr class="dijitReset dijitCalendarMonthContainer" valign="top">
+			<th class='dijitReset dijitCalendarArrow' data-dojo-attach-point="decrementMonth" scope="col">
+				<span class="dijitInline dijitCalendarIncrementControl dijitCalendarDecrease" role="presentation"></span>
+				<span data-dojo-attach-point="decreaseArrowNode" class="dijitA11ySideArrow">-</span>
+			</th>
+			<th class='dijitReset' colspan="5" scope="col">
+				<div data-dojo-attach-point="monthNode">
+				</div>
+			</th>
+			<th class='dijitReset dijitCalendarArrow' scope="col" data-dojo-attach-point="incrementMonth">
+				<span class="dijitInline dijitCalendarIncrementControl dijitCalendarIncrease" role="presentation"></span>
+				<span data-dojo-attach-point="increaseArrowNode" class="dijitA11ySideArrow">+</span>
+			</th>
+		</tr>
+		<tr role="row">
+			${!dayCellsHtml}
+		</tr>
+	</thead>
+	<tbody data-dojo-attach-point="dateRowsNode" data-dojo-attach-event="ondijitclick: _onDayClick" class="dijitReset dijitCalendarBodyContainer">
+			${!dateRowsHtml}
+	</tbody>
+	<tfoot class="dijitReset dijitCalendarYearContainer">
+		<tr>
+			<td class='dijitReset' valign="top" colspan="7" role="presentation">
+				<div class="dijitCalendarYearLabel">
+					<span data-dojo-attach-point="previousYearLabelNode" class="dijitInline dijitCalendarPreviousYear" role="button"></span>
+					<span data-dojo-attach-point="currentYearLabelNode" class="dijitInline dijitCalendarSelectedYear" role="button" id="${id}_year"></span>
+					<span data-dojo-attach-point="nextYearLabelNode" class="dijitInline dijitCalendarNextYear" role="button"></span>
+				</div>
+			</td>
+		</tr>
+	</tfoot>
+</table>

+ 9 - 0
esp/files/dijit/templates/CheckedMenuItem.html

@@ -0,0 +1,9 @@
+<tr class="dijitReset dijitMenuItem" data-dojo-attach-point="focusNode" role="${role}" tabIndex="-1" aria-checked="${checked}">
+	<td class="dijitReset dijitMenuItemIconCell" role="presentation">
+		<span class="dijitInline dijitIcon dijitMenuItemIcon dijitCheckedMenuItemIcon" data-dojo-attach-point="iconNode"></span>
+		<span class="dijitMenuItemIconChar dijitCheckedMenuItemIconChar">${checkedChar}</span>
+	</td>
+	<td class="dijitReset dijitMenuItemLabel" colspan="2" data-dojo-attach-point="containerNode,labelNode,textDirNode"></td>
+	<td class="dijitReset dijitMenuItemAccelKey" style="display: none" data-dojo-attach-point="accelKeyNode"></td>
+	<td class="dijitReset dijitMenuArrowCell" role="presentation">&#160;</td>
+</tr>

+ 5 - 0
esp/files/dijit/templates/ColorPalette.html

@@ -0,0 +1,5 @@
+<div class="dijitInline dijitColorPalette" role="grid">
+	<table dojoAttachPoint="paletteTableNode" class="dijitPaletteTable" cellSpacing="0" cellPadding="0" role="presentation">
+		<tbody data-dojo-attach-point="gridNode"></tbody>
+	</table>
+</div>

+ 10 - 0
esp/files/dijit/templates/Dialog.html

@@ -0,0 +1,10 @@
+<div class="dijitDialog" role="dialog" aria-labelledby="${id}_title">
+	<div data-dojo-attach-point="titleBar" class="dijitDialogTitleBar">
+		<span data-dojo-attach-point="titleNode" class="dijitDialogTitle" id="${id}_title"
+				role="heading" level="1"></span>
+		<span data-dojo-attach-point="closeButtonNode" class="dijitDialogCloseIcon" data-dojo-attach-event="ondijitclick: onCancel" title="${buttonCancel}" role="button" tabindex="0">
+			<span data-dojo-attach-point="closeText" class="closeText" title="${buttonCancel}">x</span>
+		</span>
+	</div>
+	<div data-dojo-attach-point="containerNode" class="dijitDialogPaneContent"></div>
+</div>

+ 15 - 0
esp/files/dijit/templates/Fieldset.html

@@ -0,0 +1,15 @@
+<fieldset>
+	<legend data-dojo-attach-event="ondijitclick:_onTitleClick, onkeydown:_onTitleKey"
+			dojoAttachPoint="titleBarNode, titleNode, focusNode">
+		<span data-dojo-attach-point="arrowNode" class="dijitInline dijitArrowNode" role="presentation"></span
+		><span data-dojo-attach-point="arrowNodeInner" class="dijitArrowNodeInner"></span
+		><span dojoAttachPoint="titleNode" class="dijitFieldsetLegendNode"></span>
+	</legend>
+	<div class="dijitFieldsetContentOuter" data-dojo-attach-point="hideNode" role="presentation">
+		<div class="dijitReset" data-dojo-attach-point="wipeNode" role="presentation">
+			<div class="dijitFieldsetContentInner" data-dojo-attach-point="containerNode" role="region" id="${id}_pane" aria-labelledby="${id}_titleBarNode">
+				<!-- nested divs because wipeIn()/wipeOut() doesn't work right on node w/padding etc.  Put padding on inner div. -->
+			</div>
+		</div>
+	</div>
+</fieldset>

+ 9 - 0
esp/files/dijit/templates/InlineEditBox.html

@@ -0,0 +1,9 @@
+<span data-dojo-attach-point="editNode" role="presentation" class="dijitReset dijitInline dijitOffScreen"
+	><span data-dojo-attach-point="editorPlaceholder"></span
+	><span data-dojo-attach-point="buttonContainer"
+		><button data-dojo-type="./form/Button" data-dojo-props="label: '${buttonSave}', 'class': 'saveButton'"
+			data-dojo-attach-point="saveButton" data-dojo-attach-event="onClick:save"></button
+		><button data-dojo-type="./form/Button"  data-dojo-props="label: '${buttonCancel}', 'class': 'cancelButton'"
+			data-dojo-attach-point="cancelButton" data-dojo-attach-event="onClick:cancel"></button
+	></span
+></span>

+ 4 - 0
esp/files/dijit/templates/Menu.html

@@ -0,0 +1,4 @@
+<table class="dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable" role="menu" tabIndex="${tabIndex}"
+	   cellspacing="0">
+	<tbody class="dijitReset" data-dojo-attach-point="containerNode"></tbody>
+</table>

+ 2 - 0
esp/files/dijit/templates/MenuBar.html

@@ -0,0 +1,2 @@
+<div class="dijitMenuBar dijitMenuPassive" data-dojo-attach-point="containerNode" role="menubar" tabIndex="${tabIndex}"
+	 ></div>

+ 4 - 0
esp/files/dijit/templates/MenuBarItem.html

@@ -0,0 +1,4 @@
+<div class="dijitReset dijitInline dijitMenuItem dijitMenuItemLabel" data-dojo-attach-point="focusNode"
+	 	role="menuitem" tabIndex="-1">
+	<span data-dojo-attach-point="containerNode,textDirNode"></span>
+</div>

+ 13 - 0
esp/files/dijit/templates/MenuItem.html

@@ -0,0 +1,13 @@
+<tr class="dijitReset dijitMenuItem" data-dojo-attach-point="focusNode" role="menuitem" tabIndex="-1">
+	<td class="dijitReset dijitMenuItemIconCell" role="presentation">
+		<span role="presentation" class="dijitInline dijitIcon dijitMenuItemIcon" data-dojo-attach-point="iconNode"></span>
+	</td>
+	<td class="dijitReset dijitMenuItemLabel" colspan="2" data-dojo-attach-point="containerNode,textDirNode"></td>
+	<td class="dijitReset dijitMenuItemAccelKey" style="display: none" data-dojo-attach-point="accelKeyNode"></td>
+	<td class="dijitReset dijitMenuArrowCell" role="presentation">
+		<span data-dojo-attach-point="arrowWrapper" style="visibility: hidden">
+			<span class="dijitInline dijitIcon dijitMenuExpand"></span>
+			<span class="dijitMenuExpandA11y">+</span>
+		</span>
+	</td>
+</tr>

+ 10 - 0
esp/files/dijit/templates/MenuSeparator.html

@@ -0,0 +1,10 @@
+<tr class="dijitMenuSeparator" role="separator">
+	<td class="dijitMenuSeparatorIconCell">
+		<div class="dijitMenuSeparatorTop"></div>
+		<div class="dijitMenuSeparatorBottom"></div>
+	</td>
+	<td colspan="3" class="dijitMenuSeparatorLabelCell">
+		<div class="dijitMenuSeparatorTop dijitMenuSeparatorLabel"></div>
+		<div class="dijitMenuSeparatorBottom"></div>
+	</td>
+</tr>

+ 9 - 0
esp/files/dijit/templates/ProgressBar.html

@@ -0,0 +1,9 @@
+<div class="dijitProgressBar dijitProgressBarEmpty" role="progressbar"
+	><div  data-dojo-attach-point="internalProgress" class="dijitProgressBarFull"
+		><div class="dijitProgressBarTile" role="presentation"></div
+		><span style="visibility:hidden">&#160;</span
+	></div
+	><div data-dojo-attach-point="labelNode" class="dijitProgressBarLabel" id="${id}_label"></div
+	><span data-dojo-attach-point="indeterminateHighContrastImage"
+		   class="dijitInline dijitProgressBarIndeterminateHighContrastImage"></span
+></div>

+ 17 - 0
esp/files/dijit/templates/TitlePane.html

@@ -0,0 +1,17 @@
+<div>
+	<div data-dojo-attach-event="ondijitclick:_onTitleClick, onkeydown:_onTitleKey"
+			class="dijitTitlePaneTitle" data-dojo-attach-point="titleBarNode" id="${id}_titleBarNode">
+		<div class="dijitTitlePaneTitleFocus" data-dojo-attach-point="focusNode">
+			<span data-dojo-attach-point="arrowNode" class="dijitInline dijitArrowNode" role="presentation"></span
+			><span data-dojo-attach-point="arrowNodeInner" class="dijitArrowNodeInner"></span
+			><span data-dojo-attach-point="titleNode" class="dijitTitlePaneTextNode"></span>
+		</div>
+	</div>
+	<div class="dijitTitlePaneContentOuter" data-dojo-attach-point="hideNode" role="presentation">
+		<div class="dijitReset" data-dojo-attach-point="wipeNode" role="presentation">
+			<div class="dijitTitlePaneContentInner" data-dojo-attach-point="containerNode" role="region" id="${id}_pane" aria-labelledby="${id}_titleBarNode">
+				<!-- nested divs because wipeIn()/wipeOut() doesn't work right on node w/padding etc.  Put padding on inner div. -->
+			</div>
+		</div>
+	</div>
+</div>

+ 4 - 0
esp/files/dijit/templates/Tooltip.html

@@ -0,0 +1,4 @@
+<div class="dijitTooltip dijitTooltipLeft" id="dojoTooltip"
+	><div class="dijitTooltipConnector" data-dojo-attach-point="connectorNode"></div
+	><div class="dijitTooltipContainer dijitTooltipContents" data-dojo-attach-point="containerNode" role='alert'></div
+></div>

+ 6 - 0
esp/files/dijit/templates/TooltipDialog.html

@@ -0,0 +1,6 @@
+<div role="alertdialog" tabIndex="-1">
+	<div class="dijitTooltipContainer" role="presentation">
+		<div class="dijitTooltipContents dijitTooltipFocusNode" data-dojo-attach-point="containerNode"></div>
+	</div>
+	<div class="dijitTooltipConnector" role="presentation" data-dojo-attach-point="connectorNode"></div>
+</div>

+ 6 - 0
esp/files/dijit/templates/Tree.html

@@ -0,0 +1,6 @@
+<div role="tree">
+	<div class="dijitInline dijitTreeIndent" style="position: absolute; top: -9999px" data-dojo-attach-point="indentDetector"></div>
+	<div class="dijitTreeExpando dijitTreeExpandoLoading" data-dojo-attach-point="rootLoadingIndicator"></div>
+	<div data-dojo-attach-point="containerNode" class="dijitTreeContainer" role="presentation">
+	</div>
+</div>

+ 12 - 0
esp/files/dijit/templates/TreeNode.html

@@ -0,0 +1,12 @@
+<div class="dijitTreeNode" role="presentation"
+	><div data-dojo-attach-point="rowNode" class="dijitTreeRow" role="presentation"
+		><span data-dojo-attach-point="expandoNode" class="dijitInline dijitTreeExpando" role="presentation"></span
+		><span data-dojo-attach-point="expandoNodeText" class="dijitExpandoText" role="presentation"></span
+		><span data-dojo-attach-point="contentNode"
+			class="dijitTreeContent" role="presentation">
+			<span role="presentation" class="dijitInline dijitIcon dijitTreeIcon" data-dojo-attach-point="iconNode"></span
+			><span data-dojo-attach-point="labelNode,focusNode" class="dijitTreeLabel" role="treeitem" tabindex="-1" aria-selected="false"></span>
+		</span
+	></div>
+	<div data-dojo-attach-point="containerNode" class="dijitTreeNodeContainer" role="presentation" style="display: none;"></div>
+</div>

Разлика између датотеке није приказан због своје велике величине
+ 1242 - 0
esp/files/dijit/themes/themeTester-orig.html


Разлика између датотеке није приказан због своје велике величине
+ 1379 - 0
esp/files/dijit/themes/themeTester.html


BIN
esp/files/dijit/themes/themeTesterImages/blackButtonEnabled.gif


BIN
esp/files/dijit/themes/themeTesterImages/blackButtonHover.gif


+ 5 - 0
esp/files/dijit/themes/themeTesterQuirk.html

@@ -0,0 +1,5 @@
+<html>
+<head>
+<script type="text/javascript" src="../tests/_loadTest.js" file="themeTester.html"></script>
+</head>
+</html>

+ 170 - 0
esp/files/dojo/robot.js

@@ -0,0 +1,170 @@
+define([
+	"./_base/array",
+	"./dom",
+	"./dom-geometry",
+	"./_base/kernel",
+	"./_base/lang",
+	"./_base/window",
+	"doh/_browserRunner",
+	"doh/robot",
+	"./window"
+], function(array, dom, geom, kernel, lang, win, doh, robot, winUtils){
+
+kernel.experimental("dojo.robot");
+
+// users who use doh+dojo get the added convenience of robot.mouseMoveAt(),
+// instead of computing the absolute coordinates of their elements themselves
+lang.mixin(robot, {
+
+	_resolveNode: function(/*String||DOMNode||Function*/ n){
+		if(typeof n == "function"){
+			// if the user passed a function returning a node, evaluate it
+			n = n();
+		}
+		return n ? dom.byId(n) : null;
+	},
+
+	_scrollIntoView: function(/*Node*/ n){
+		// scrolls the passed node into view, scrolling all ancestor frames/windows as well.
+		// Assumes parent iframes can be made fully visible given the current browser window size
+		var p = null;
+		array.forEach(robot._getWindowChain(n), function(w){
+			// get the position of the node wrt its parent window
+			// if it is a parent frame, its padding and border extents will get added in
+			var p2 = geom.position(n, false),
+				b = geom.getPadBorderExtents(n),
+				oldp = null;
+			// if p2 is the position of the original passed node, store the position away as p
+			// otherwise, node is actually an iframe. in this case, add the iframe's position wrt its parent window and also the iframe's padding and border extents
+			if(!p){
+				p = p2;
+			}else{
+				oldp = p;
+				p = {x: p.x+p2.x+b.l,
+					y: p.y+p2.y+b.t,
+					w: p.w,
+					h: p.h};
+
+			}
+			// scroll the parent window so that the node translated into the parent window's coordinate space is in view
+			winUtils.scrollIntoView(n,p);
+			// adjust position for the new scroll offsets
+			p2 = geom.position(n, false);
+			if(!oldp){
+				p = p2;
+			}else{
+				p = {x: oldp.x+p2.x+b.l,
+					y: oldp.y+p2.y+b.t,
+					w: p.w,
+					h: p.h};
+			}
+			// get the parent iframe so it can be scrolled too
+			n = w.frameElement;
+		});
+	},
+
+	_position: function(/*Node*/ n){
+		// Returns the geom.position of the passed node wrt the passed window's viewport,
+		// following any parent iframes containing the node and clipping the node to each iframe.
+		// precondition: _scrollIntoView already called
+		var p = null, max = Math.max, min = Math.min;
+		// p: the returned position of the node
+		array.forEach(robot._getWindowChain(n), function(w){
+			// get the position of the node wrt its parent window
+			// if it is a parent frame, its padding and border extents will get added in
+			var p2 = geom.position(n, false), b = geom.getPadBorderExtents(n);
+			// if p2 is the position of the original passed node, store the position away as p
+			// otherwise, node is actually an iframe. in this case, add the iframe's position wrt its parent window and also the iframe's padding and border extents
+			if(!p){
+				p = p2;
+			}else{
+				var view = winUtils.getBox(n.contentWindow.document);
+				p2.r = p2.x+view.w;
+				p2.b = p2.y+view.h;
+				p = {x: max(p.x+p2.x,p2.x)+b.l, // clip left edge of node wrt the iframe
+					y: max(p.y+p2.y,p2.y)+b.t,	// top edge
+					r: min(p.x+p2.x+p.w,p2.r)+b.l,	// right edge (to compute width)
+					b: min(p.y+p2.y+p.h,p2.b)+b.t}; // bottom edge (to compute height)
+				// save a few bytes by computing width and height from r and b
+				p.w = p.r-p.x;
+				p.h = p.b-p.y;
+			}
+			// the new node is now the old node's parent iframe
+			n=w.frameElement;
+		});
+		return p;
+	},
+
+	_getWindowChain : function(/*Node*/ n){
+		// Returns an array of windows starting from the passed node's parent window and ending at dojo's window
+		var cW = winUtils.get(n.ownerDocument);
+		var arr = [cW];
+		var f = cW.frameElement;
+		return (cW == win.global || !f) ? arr : arr.concat(robot._getWindowChain(f));
+	},
+
+	scrollIntoView : function(/*String||DOMNode||Function*/ node, /*Number, optional*/ delay){
+		// summary:
+		//		Scroll the passed node into view, if it is not.
+		// node:
+		//		The id of the node, or the node itself, to move the mouse to.
+		//		If you pass an id or a function that returns a node, the node will not be evaluated until the movement executes.
+		//		This is useful if you need to move the mouse to an node that is not yet present.
+		// delay:
+		//		Delay, in milliseconds, to wait before firing.
+		//		The delay is a delta with respect to the previous automation call.
+
+		robot.sequence(function(){
+			robot._scrollIntoView(robot._resolveNode(node));
+		}, delay);
+	},
+
+	mouseMoveAt : function(/*String||DOMNode||Function*/ node, /*Integer, optional*/ delay, /*Integer, optional*/ duration, /*Number, optional*/ offsetX, /*Number, optional*/ offsetY){
+		// summary:
+		//		Moves the mouse over the specified node at the specified relative x,y offset.
+		// description:
+		//		Moves the mouse over the specified node at the specified relative x,y offset.
+		//		If you do not specify an offset, mouseMove will default to move to the middle of the node.
+		//		Example: to move the mouse over a ComboBox's down arrow node, call doh.mouseMoveAt(dijit.byId('setvaluetest').downArrowNode);
+		// node:
+		//		The id of the node, or the node itself, to move the mouse to.
+		//		If you pass an id or a function that returns a node, the node will not be evaluated until the movement executes.
+		//		This is useful if you need to move the mouse to an node that is not yet present.
+		// delay:
+		//		Delay, in milliseconds, to wait before firing.
+		//		The delay is a delta with respect to the previous automation call.
+		//		For example, the following code ends after 600ms:
+		// |	robot.mouseClick({left:true}, 100) // first call; wait 100ms
+		// |	robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
+		// duration:
+		//		Approximate time Robot will spend moving the mouse
+		//		The default is 100ms.
+		// offsetX:
+		//		x offset relative to the node, in pixels, to move the mouse. The default is half the node's width.
+		// offsetY:
+		//		y offset relative to the node, in pixels, to move the mouse. The default is half the node's height.
+
+		robot._assertRobot();
+
+		// Schedule an action to scroll the node into view, then calculate it's center point
+		var point = {};
+		this.sequence(function(){
+			node = robot._resolveNode(node);
+			robot._scrollIntoView(node);
+			var pos = robot._position(node);
+			if(offsetY === undefined){
+				offsetX = pos.w/2;
+				offsetY = pos.h/2;
+			}
+			point.x = pos.x+offsetX;
+			point.y = pos.y+offsetY;
+		}, delay);
+
+		// Schedule a bunch of actions to move the mouse from the current position to point.
+		// These actions won't run until after the above callback.
+		this.mouseMoveTo(point, 0, duration, false);
+	}
+});
+
+return robot;
+});

+ 171 - 0
esp/files/dojo/robotx.js

@@ -0,0 +1,171 @@
+define([
+	"require",
+	"doh/main",
+	"./aspect",
+	"./dom-construct",
+	"./dom-style",
+	"./_base/kernel",
+	"./_base/lang",
+	"./on",
+	"./robot",
+	"./sniff",
+	"./_base/window"
+], function(require, doh, aspect, construct, style, kernel, lang, on, robot, has, win){
+
+kernel.experimental("dojo.robotx");
+
+// module:
+//		dojo.robotx
+// description:
+//		loads an external app into an iframe and points dojo.doc to the iframe document, allowing the robot to control it
+//		to use: set robotURL in djConfig to the URL you want to load
+//		dojo.require this file
+
+// The iframe containing the external app
+var iframe = null;
+
+// On IE6/7, a firebug console will appear.   Scrunch it a bit to leave room for the external test file.
+kernel.config.debugHeight = kernel.config.debugHeight || 200;
+
+
+// urlLoaded is a Deferred that will be resolved whenever the iframe passed to initRobot() finishes loading, or reloads
+var urlLoaded;
+
+function attachIframe(url){
+	// summary:
+	//		Create iframe to load external app at specified url.   Iframe gets onload handler to  call onIframeLoad()
+	//		when specified URL finishes loading, and also if the iframe loads a different URL in the future.
+	// returns:
+	//		A Deferred that fires when everything has finished initializing
+
+	require(["./domReady!"], function(){
+		var emptyStyle = {
+			overflow: "hidden",
+			margin: "0px",
+			borderWidth: "0px",
+			height: "100%",
+			width: "100%"
+		};
+		style.set(document.documentElement, emptyStyle);
+		style.set(document.body, emptyStyle);
+
+		// Create the iframe for the external document.   Put it above the firebug-lite div (if such a div exists).
+		// console.log("creating iframe for external document");
+		iframe = document.createElement("iframe");
+		iframe.setAttribute("ALLOWTRANSPARENCY","true");
+		iframe.scrolling = has("ie") ? "yes" : "auto";
+		var scrollRoot = document.compatMode == "BackCompat" ? document.body : document.documentElement;
+		var consoleHeight = (document.getElementById("firebug") || {}).offsetHeight || 0;
+		style.set(iframe, {
+			border: "0px none",
+			padding: "0px",
+			margin: "0px",
+			width: "100%",
+			height: consoleHeight ? (scrollRoot.clientHeight - consoleHeight)+"px" : "100%"
+		});
+		iframe.src = url;
+
+		// Code to handle load event on iframe.  Seems like this should happen before setting iframe src on line above?
+		// Also, can't we use on() in all cases, even for old IE?
+		if(iframe.attachEvent !== undefined){
+			iframe.attachEvent("onload", onIframeLoad);
+		}else{
+			on(iframe, "load", onIframeLoad);
+		}
+
+		construct.place(iframe, win.body(), "first");
+	});
+}
+
+function onIframeLoad(){
+	// summary:
+	//		Load handler when iframe specified to initRobot() finishes loading, or when it reloads.
+	//		It resolves the urlLoaded Deferred to make the rests of the tests runs.
+
+	robot._updateDocument();
+
+	// If dojo is present in the test case, then at least make a best effort to wait for it to load.
+	// The test must handle other race conditions like initial data queries or asynchronous parses by itself.
+	if(iframe.contentWindow.require){
+		iframe.contentWindow.require(["dojo/ready"], function(ready){
+			ready(Infinity, function(){
+				setTimeout(function(){
+					urlLoaded.resolve(true);
+				}, 500);	// 500ms fudge factor; otherwise focus doesn't work on IE8, see ValidationTextBox.js, TimeTextBox.js, etc.
+			});
+		});
+	}else{
+		urlLoaded.resolve(true);
+	}
+}
+
+lang.mixin(robot, {
+	_updateDocument: function(){
+		// summary:
+		//		Called every time a new page is loaded into the iframe, to setup variables
+		//		Point dojo.global, dojo.publish, etc. to refer to iframe.
+		//		Remove for 2.0?
+
+		kernel.setContext(iframe.contentWindow, iframe.contentWindow.document);
+
+		// Also set pointers inside robot, for easy access via AMD (where there is no dojo variable)
+		robot.window = iframe.contentWindow;
+		robot.doc = iframe.contentWindow.document;
+
+		// TODO: shouldn't this wait until dojo has finished loading in the iframe?  See require code in onIframeLoad().
+		var win = kernel.global;
+		if(win.dojo){
+			// allow the tests to subscribe to topics published by the iframe
+			kernel.publish = win.dojo.publish;
+			kernel.subscribe = win.dojo.subscribe;
+			kernel.connectPublisher = win.dojo.connectPublisher;
+		}
+	},
+
+	initRobot: function(/*String*/ url){
+		// summary:
+		//		Opens the application at the specified URL for testing, redirecting dojo to point to the application
+		//		environment instead of the test environment.
+		// url:
+		//		URL to open. Any of the test's dojo.doc calls (e.g. dojo.byId()), and any dijit.registry calls
+		//		(e.g. dijit.byId()) will point to elements and widgets inside this application.
+
+		doh.registerGroup("initialize robot", {
+			name: "load " + url,
+			timeout: 100000,	// could take more than 10s so setting to 100s
+			runTest: function(){
+				// Setup module level urlLoaded Deferred that will be resolved by onIframeLoad(), after the iframe
+				// has finished loading
+				urlLoaded = new doh.Deferred();
+				attachIframe(url);
+
+				return urlLoaded;
+			}
+		});
+	},
+
+	waitForPageToLoad: function(/*Function*/ submitActions){
+		// summary:
+		//		Notifies DOH that the doh.robot is about to make a page change in the application it is driving,
+		//		returning a doh.Deferred object the user should return in their runTest function as part of a DOH test.
+		// example:
+		// |	runTest: function(){
+		// |		return waitForPageLoad(function(){ doh.robot.keyPress(keys.ENTER, 500); });
+		// |	}
+		// submitActions:
+		//		The doh.robot will execute the actions the test passes into the submitActions argument (like clicking the submit button),
+		//		expecting these actions to create a page change (like a form submit).
+		//		After these actions execute and the resulting page loads, the next test will start.
+
+		// Setup a new Deferred that onIframeLoad() will resolve when the iframe finishes loading
+		urlLoaded = new doh.Deferred();
+
+		submitActions();
+
+		return urlLoaded;
+	}
+
+});
+
+return robot;
+});

+ 13 - 0
esp/files/dojo/tests.js

@@ -0,0 +1,13 @@
+//This file is the command-line entry point for running the tests in
+//Rhino and Spidermonkey.
+
+/*=====
+dojo.tests = {
+	// summary:
+	//		D.O.H. Test files for Dojo unit testing.
+};
+=====*/
+
+load("dojo.js");
+load("tests/runner.js");
+tests.run();

BIN
esp/files/img/queries_icon.png