Parcourir la source

Merge pull request #5441 from GordonSmith/DojoBuild3

Use Dojo Build to create optimized ECL Watch

Reviewed-By: Xiaoming Wang <xiaoming.wang@lexisnexis.com>
Reviewed-By: Kevin Wang <kevin.wang@lexisnexis.com>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman il y a 11 ans
Parent
commit
f8576e75fc
100 fichiers modifiés avec 108 ajouts et 13136 suppressions
  1. 27 0
      .gitmodules
  2. 16 0
      esp/CMakeLists.txt
  3. 65 0
      esp/build.sh
  4. 0 5
      esp/files/d3/d3.v3.min.js
  5. 0 1
      esp/files/d3/topojson.v1.min.js
  6. 0 927
      esp/files/dgrid/CHANGES.md
  7. 0 156
      esp/files/dgrid/CellSelection.js
  8. 0 275
      esp/files/dgrid/ColumnSet.js
  9. 0 527
      esp/files/dgrid/Grid.js
  10. 0 127
      esp/files/dgrid/GridFromHtml.js
  11. 0 116
      esp/files/dgrid/GridWithColumnSetsFromHtml.js
  12. 0 514
      esp/files/dgrid/Keyboard.js
  13. 0 190
      esp/files/dgrid/LICENSE
  14. 0 928
      esp/files/dgrid/List.js
  15. 0 3
      esp/files/dgrid/OnDemandGrid.js
  16. 0 626
      esp/files/dgrid/OnDemandList.js
  17. 0 136
      esp/files/dgrid/README.md
  18. 0 615
      esp/files/dgrid/Selection.js
  19. 0 646
      esp/files/dgrid/TouchScroll.js
  20. 0 351
      esp/files/dgrid/_StoreMixin.js
  21. 0 55
      esp/files/dgrid/css/TouchScroll.css
  22. 0 40
      esp/files/dgrid/css/columnset.css
  23. 0 208
      esp/files/dgrid/css/dgrid.css
  24. 0 50
      esp/files/dgrid/css/dgrid_rtl.css
  25. 0 48
      esp/files/dgrid/css/extensions/ColumnHider.css
  26. 0 14
      esp/files/dgrid/css/extensions/ColumnReorder.css
  27. 0 58
      esp/files/dgrid/css/extensions/ColumnResizer.css
  28. 0 8
      esp/files/dgrid/css/extensions/CompoundColumns.css
  29. 0 38
      esp/files/dgrid/css/extensions/Pagination.css
  30. 0 16
      esp/files/dgrid/css/has-transforms3d.css
  31. BIN
      esp/files/dgrid/css/images/ui-icons_222222_256x240.png
  32. BIN
      esp/files/dgrid/css/images/ui-icons_222222_256x240_white.png
  33. 0 8
      esp/files/dgrid/css/skins/README.md
  34. 0 108
      esp/files/dgrid/css/skins/cactus.css
  35. 0 67
      esp/files/dgrid/css/skins/claro.css
  36. BIN
      esp/files/dgrid/css/skins/images/row_back.png
  37. 0 38
      esp/files/dgrid/css/skins/nihilo.css
  38. 0 86
      esp/files/dgrid/css/skins/sage.css
  39. 0 68
      esp/files/dgrid/css/skins/slate.css
  40. 0 46
      esp/files/dgrid/css/skins/soria.css
  41. 0 84
      esp/files/dgrid/css/skins/squid.css
  42. 0 48
      esp/files/dgrid/css/skins/tundra.css
  43. 0 143
      esp/files/dgrid/demos/dTuned/data.js
  44. 0 272
      esp/files/dgrid/demos/dTuned/index.html
  45. 0 46
      esp/files/dgrid/demos/dTuned/resources/dTuned.css
  46. BIN
      esp/files/dgrid/demos/dTuned/resources/images/grid-header-bg.png
  47. BIN
      esp/files/dgrid/demos/dTuned/resources/images/grid-header-separator.png
  48. BIN
      esp/files/dgrid/demos/dTuned/resources/images/grid-header-sorted-separator.png
  49. BIN
      esp/files/dgrid/demos/dTuned/resources/images/grid-header-sorted.png
  50. BIN
      esp/files/dgrid/demos/dTuned/resources/images/header-background.png
  51. BIN
      esp/files/dgrid/demos/dTuned/resources/images/header.png
  52. 0 219
      esp/files/dgrid/demos/multiview/index.html
  53. BIN
      esp/files/dgrid/demos/multiview/resources/df-128.png
  54. BIN
      esp/files/dgrid/demos/multiview/resources/df-32.png
  55. BIN
      esp/files/dgrid/demos/multiview/resources/df-64.png
  56. BIN
      esp/files/dgrid/demos/multiview/resources/dojo-128.png
  57. BIN
      esp/files/dgrid/demos/multiview/resources/dojo-32.png
  58. BIN
      esp/files/dgrid/demos/multiview/resources/dojo-64.png
  59. 0 213
      esp/files/dgrid/demos/todo/index.html
  60. 0 538
      esp/files/dgrid/editor.js
  61. 0 313
      esp/files/dgrid/extensions/ColumnHider.js
  62. 0 193
      esp/files/dgrid/extensions/ColumnReorder.js
  63. 0 448
      esp/files/dgrid/extensions/ColumnResizer.js
  64. 0 90
      esp/files/dgrid/extensions/CompoundColumns.js
  65. 0 83
      esp/files/dgrid/extensions/DijitRegistry.js
  66. 0 286
      esp/files/dgrid/extensions/DnD.js
  67. 0 512
      esp/files/dgrid/extensions/Pagination.js
  68. 0 93
      esp/files/dgrid/extensions/_DnD-touch-autoscroll.js
  69. 0 6
      esp/files/dgrid/extensions/nls/columnHider.js
  70. 0 9
      esp/files/dgrid/extensions/nls/de/pagination.js
  71. 0 3
      esp/files/dgrid/extensions/nls/es/columnHider.js
  72. 0 3
      esp/files/dgrid/extensions/nls/es/pagination.js
  73. 0 9
      esp/files/dgrid/extensions/nls/fr/pagination.js
  74. 0 3
      esp/files/dgrid/extensions/nls/ja/pagination.js
  75. 0 20
      esp/files/dgrid/extensions/nls/pagination.js
  76. 0 9
      esp/files/dgrid/extensions/nls/pt/pagination.js
  77. 0 9
      esp/files/dgrid/extensions/nls/sk/pagination.js
  78. 0 9
      esp/files/dgrid/extensions/nls/th/pagination.js
  79. 0 9
      esp/files/dgrid/extensions/nls/zh-cn/pagination.js
  80. 0 9
      esp/files/dgrid/extensions/nls/zh-hk/pagination.js
  81. 0 23
      esp/files/dgrid/package.js
  82. 0 31
      esp/files/dgrid/package.json
  83. 0 197
      esp/files/dgrid/selector.js
  84. 0 186
      esp/files/dgrid/test/GridFromHtml.html
  85. 0 87
      esp/files/dgrid/test/GridFromHtml_Editors.html
  86. 0 143
      esp/files/dgrid/test/Grid_headerless.html
  87. 0 103
      esp/files/dgrid/test/Grid_mouseevents.html
  88. 0 205
      esp/files/dgrid/test/Grid_rendering.html
  89. 0 68
      esp/files/dgrid/test/JsonRest.html
  90. 0 72
      esp/files/dgrid/test/JsonRest_duplicates.html
  91. 0 100
      esp/files/dgrid/test/Keyboard.html
  92. 0 378
      esp/files/dgrid/test/OnDemand.html
  93. 0 71
      esp/files/dgrid/test/OnDemand_promises.html
  94. 0 76
      esp/files/dgrid/test/OnDemand_tile.html
  95. 0 133
      esp/files/dgrid/test/Selection.html
  96. 0 59
      esp/files/dgrid/test/autoheight.html
  97. 0 127
      esp/files/dgrid/test/common_cases.html
  98. 0 264
      esp/files/dgrid/test/complex_column.html
  99. 0 35
      esp/files/dgrid/test/data/DeferredWrapper.js
  100. 0 0
      esp/files/dgrid/test/data/base.js

+ 27 - 0
.gitmodules

@@ -0,0 +1,27 @@
+[submodule "esp/src/topojson"]
+	path = esp/src/topojson
+	url = git@github.com:hpcc-systems/topojson.git
+[submodule "esp/src/xstyle"]
+	path = esp/src/xstyle
+	url = git@github.com:hpcc-systems/xstyle.git
+[submodule "esp/src/put-selector"]
+	path = esp/src/put-selector
+	url = git@github.com:hpcc-systems/put-selector.git
+[submodule "esp/src/dgrid"]
+	path = esp/src/dgrid
+	url = git@github.com:hpcc-systems/dgrid.git
+[submodule "esp/src/dojo"]
+	path = esp/src/dojo
+	url = git@github.com:hpcc-systems/dojo.git
+[submodule "esp/src/d3"]
+	path = esp/src/d3
+	url = git@github.com:hpcc-systems/d3.git
+[submodule "esp/src/dijit"]
+	path = esp/src/dijit
+	url = git@github.com:hpcc-systems/dijit.git
+[submodule "esp/src/dojox"]
+	path = esp/src/dojox
+	url = git@github.com:hpcc-systems/dojox.git
+[submodule "esp/src/util"]
+	path = esp/src/util
+	url = git@github.com:hpcc-systems/util.git

+ 16 - 0
esp/CMakeLists.txt

@@ -25,3 +25,19 @@ HPCC_ADD_SUBDIRECTORY (smc "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (test "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (tools "CLIENTTOOLS")
 HPCC_ADD_SUBDIRECTORY (xslt "PLATFORM")
+
+if ( PLATFORM )
+    set(ECLWATCH_BUILD_DEST "${CMAKE_CURRENT_BINARY_DIR}/tmp/files")
+    set(ECLWATCH_BUILD_OUT "${CMAKE_CURRENT_BINARY_DIR}/eclwatch_build_out.txt")
+    set(ECLWATCH_BUILD_ERR "${CMAKE_CURRENT_BINARY_DIR}/eclwatch_build_err.txt")
+    install ( CODE "
+        message(\"Run Dojo build tool...\")
+        message(\"Dojo build:  Build Target - ${ECLWATCH_BUILD_DEST}\")
+        message(\"Dojo build:  Output log - ${ECLWATCH_BUILD_OUT}\")
+        message(\"Dojo build:  Error log - ${ECLWATCH_BUILD_ERR}\")
+        execute_process(COMMAND \"${CMAKE_CURRENT_SOURCE_DIR}/build.sh\" \"${ECLWATCH_BUILD_DEST}\" OUTPUT_FILE \"${ECLWATCH_BUILD_OUT}\" ERROR_FILE \"${ECLWATCH_BUILD_ERR}\")
+        execute_process(COMMAND \"tail\" \"--lines=4\" \"${ECLWATCH_BUILD_DEST}/build-report.txt\")
+        message(\"\")
+    " COMPONENT Runtime)
+    Install ( DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/tmp/files" DESTINATION componentfiles COMPONENT Runtime USE_SOURCE_PERMISSIONS PATTERN "build-report.txt" EXCLUDE PATTERN "*.map" EXCLUDE  PATTERN "*.uncompressed.js" EXCLUDE)
+endif ( PLATFORM )

+ 65 - 0
esp/build.sh

@@ -0,0 +1,65 @@
+#!/usr/bin/env bash
+
+set -e
+
+# Base directory for this entire project
+BASEDIR=$(cd $(dirname $0) && pwd)
+
+# Source directory for unbuilt code
+SRCDIR="$BASEDIR/src"
+
+# Directory containing dojo build utilities
+TOOLSDIR="$SRCDIR/util/buildscripts"
+
+# Destination directory for built code
+DISTDIR=$1
+
+# Module ID of the main application package loader configuration
+LOADERMID="eclwatch/run"
+
+# Main application package loader configuration
+LOADERCONF="$SRCDIR/$LOADERMID.js"
+
+# Main application package build configuration
+PROFILE="$BASEDIR/profiles/eclwatch.profile.js"
+
+# Configuration over. Main application start up!
+
+if [ ! -d "$TOOLSDIR" ]; then
+    echo "Can't find Dojo build tools -- did you initialise submodules? (git submodule update --init --recursive)"
+    exit 1
+fi
+
+echo "Building application with $PROFILE to $DISTDIR."
+
+echo -n "Cleaning old files..."
+rm -rf "$DISTDIR"
+echo " Done"
+
+mkdir -p "$DISTDIR"
+cp -r "$SRCDIR/CodeMirror2" "$DISTDIR/CodeMirror2"
+
+cd "$TOOLSDIR"
+
+if which node >/dev/null; then
+    node ../../dojo/dojo.js load=build --require "$LOADERCONF" --profile "$PROFILE" --releaseDir "$DISTDIR" ${*:2}
+elif which java >/dev/null; then
+    java -Xms256m -Xmx256m  -cp ../shrinksafe/js.jar:../closureCompiler/compiler.jar:../shrinksafe/shrinksafe.jar org.mozilla.javascript.tools.shell.Main  ../../dojo/dojo.js baseUrl=../../dojo load=build --require "$LOADERCONF" --profile "$PROFILE" --releaseDir "$DISTDIR" ${*:2}
+else
+    echo "Need node.js or Java to build!"
+    exit 1
+fi
+
+cd "$BASEDIR"
+
+LOADERMID=${LOADERMID//\//\\\/}
+
+# Copy & minify stub.htm to dist
+cat "$SRCDIR/stub.htm" | tr '\n' ' ' | \
+perl -pe "
+  s/<\!--.*?-->//g;                          # Strip comments
+#  s/isDebug: *1/deps:['$LOADERMID']/;        # Remove isDebug, add deps
+#  s/<script src=\"$LOADERMID.*?\/script>//;  # Remove script eclwatch/run
+  s/\s+/ /g;                                 # Collapse white-space" > "$DISTDIR/stub.htm"
+
+echo "Build complete"

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 5
esp/files/d3/d3.v3.min.js


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 1
esp/files/d3/topojson.v1.min.js


+ 0 - 927
esp/files/dgrid/CHANGES.md

@@ -1,927 +0,0 @@
-This document outlines changes since 0.3.0.  For older changelogs, see the
-[dgrid wiki](https://github.com/SitePen/dgrid/wiki).
-
-# 0.3.12
-
-## Significant changes
-
-### General/Core
-
-* Fixed a regression in `Grid` since 0.3.7 where formatters were run in the
-  global context by default instead of in the context of the column definition.
-  (#748, thanks mbretter)
-* The `className` column definition property now supports being assigned a
-  function value, in which case the function will be called for each row in the
-  grid (including the header).  For rows in the body, the associated data object
-  (e.g. store item) will be passed, but for the header row, nothing will be
-  passed, so this will need to be handled in the function's logic.
-
-### Mixins
-
-* `Selection` and `CellSelection` now fire `dgrid-select` and `dgrid-deselect`
-  events on the same turn that `select` is called. The events still include
-  `rows` or `cells` containing all rows or cells selected at once; only the
-  timing of the events firing has changed.
-* Fixed an issue in `Selection` code flow which caused devices supporting
-  MSPointer to behave incorrectly with recent versions of Dojo.
-
-### Extensions
-
-* Fixed a regression in `Pagination` where `rowsPerPage` (and thus also
-  `queryOptions.count`) would be set to a string rather than a number when the
-  page size drop-down is used. (#752)
-
-## Other changes and fixes
-
-### Mixins
-
-* The `Keyboard` mixin now properly adds/removes header navigation when
-  `set("showHeader", ...)` is called. (#734)
-
-### Column Plugins
-
-* Added logic to `editor` to preserve editor focus when a row is updated
-  (particularly useful with always-on editors with autoSave enabled). (#579)
-* Removed a `mousedown` event handler from `editor` which was interfering with
-  certain widget features such as `TextBox#selectOnClick`; this event handler
-  should no longer be necessary. (#704)
-
-### Extensions
-
-* The `ColumnHider` extension's menu trigger node no longer reopens the menu if
-  the menu is already open; it will close it just like clicking anywhere else
-  outside the menu. (#755)
-
-# 0.3.11
-
-## Significant changes
-
-### General/Core
-
-* Fixed a regression related to `OnDemandList` in conjunction with the `tree`
-  plugin, where queries would not fire due to confusion between different levels.
-  (#717)
-* Fixed a regression related to `List` and `OnDemandList` in conjunction with
-  `tree` by adding a `cleanEmptyObservers` flag, which `tree` will set to false.
-  (#713)
-* Added a `highlightDuration` property to `List` to allow customizing the length
-  of time that rows remain highlighted when modified. (#736, thanks Zarillion)
-
-### Mixins
-
-* Fixed a follow-up issue in `Selection` related to the fix for #226, where
-  deselect events were not firing for removed rows. (#684)
-
-### Column Plugins
-
-* The `tree` column plugin will now include an `originalQuery` property in the
-  `options` object passed to `getChildren`, allowing store implementations to
-  re-apply query filters to queries for child items. (#145, #732)
-
-### Extensions
-
-* The `Pagination` extension now has proper setters for `rowsPerPage` and
-  `pageSizeOptions`.  If `rowsPerPage` is set to a value that is not present in
-  `pageSizeOptions`, an option will be added for the new value.  The drop-down's
-  options will always appear in ascending order. (#631)
-
-## Other changes and fixes
-
-### General/Core
-
-* Fixed an issue in `OnDemandList#_calcRowHeight` to properly calculate height
-  of the first row. (#552)
-* Fixed a compatibility issue in `OnDemandList` and `dojo/store/DataStore` due
-  to a conflicting property in `queryOptions`. (#440)
-
-### Mixins
-
-* Fixed an issue in `Selection` where its select-all keybinding would prevent
-  select-all functionality within text editors. (#711)
-* Fixed an issue in `Selection` where the selection could fall out of sync for
-  an item with a falsy id. (#715)
-
-### Extensions
-
-* The `Pagination` extension will now render its footer controls properly in RTL
-  locales (provided `dgrid_rtl.css` is loaded). (#707)
-
-# 0.3.10
-
-## Significant changes
-
-### General/Core
-
-* Updated the README and fixed the redirect in `test/intern/runTests.html` to
-  reference the correct path where intern-geezer installs to as of Intern 1.2.
-* Fixed some issues, including a regression, in `List` involving handling of
-  observed store updates, particularly in conjunction with overlapping queries
-  performed by `OnDemandList`. (#701)
-* Fixed a regression in `_StoreMixin` (affecting `OnDemandList` and `Pagination`)
-  where setting `store` to `null` would cause an error. (#688, thanks kilink)
-* Fixed a regression in `_StoreMixin` which caused an error when updating the
-  only row present in a list or grid. (#693)
-* Updated the `put-selector` dependency to 0.3.5, which includes a fix for an
-  issue involving iOS Safari's JavaScript optimization, which was causing
-  errors in dgrid.
-
-## Other changes and fixes
-
-### Mixins
-
-* The `Keyboard` mixin will now manage focus if a row is updated or removed;
-  in the former case, the new row will receive focus (assuming it is within
-  the currently-rendered area), otherwise the next row will receive focus. (#496)
-* The `editor` column plugin will now return focus to the parent cell when an
-  editor is dismissed, if the `Keyboard` mixin is also in use. (#263)
-
-### Extensions
-
-* Improved accessibility of the `ColumnHider` extension, adding a tab stop for
-  the menu trigger, focusing the first checkbox within the menu when it opens,
-  allowing it to be dismissed by pressing escape (at which time focus returns
-  to the trigger), and adding ARIA role and label to the popup menu itself.
-
-# 0.3.9
-
-## Significant changes
-
-### General/Core
-
-* dgrid now uses [Intern](http://theintern.io) for unit and functional tests,
-  instead of DOH.  See the README for setup instructions.
-* Fixed a regression with `OnDemandList` which would cause improper rendering
-  after scrolling. (#548)
-* Fixed an issue with `OnDemandList` causing `queryRowsOverlap` only taking
-  effect between the first two queries. (#644)
-* Added the capability to opt out of custom TouchScroll logic on devices that
-  support touch, by setting `useTouchScroll: false` on the instance. (#656)
-* Fixed logic in `Grid`, `GridFromHtml`, and `selector` to allow specifying a
-  blank label for a column by passing an empty string to `column.label`. (#664)
-
-### Mixins
-
-* The `Selection` mixin now uses MSPointer events where available, which avoids
-  issues in cases where something cancels a MSPointer event, preventing relevant
-  mouse events from firing (for example, `dojo/dnd` + `dojo/touch` in 1.9). (#658)
-* The `CellSelection` mixin now supports selecting or deselecting all columns
-  in a row if a row object is passed.
-* Fixed a regression in the `Selection` mixin where unselectable rows could still
-  be selected via ctrl+click.
-
-### Column Plugins
-
-* Fixed a regression in `selector` which caused an error when clicking the
-  select-all checkbox. (#674)
-
-### Extensions
-
-* Fixed a regression in the `Pagination` extension where duplicate rows could
-  be displayed if several paging/sorting requests are fired in quick succession
-  to an asynchronous store.  Note that the fix involves canceling old requests,
-  which may cause Deferred errors to be logged to the console; this is normal.
-  The `dgrid-error` event will *not* be emitted for canceled requests. (#635)
-
-## Other changes and fixes
-
-### General/Core
-
-* Fixed a potential issue in `Grid` in non-ES5 environments that augment the
-  Array prototype. (#624)
-* Fixed an issue with `OnDemandList` involving where a new row is inserted in
-  the DOM when the relevant result set is currently empty. (#647)
-* Fixed issues involving `List` and `OnDemandList` not properly cleaning up
-  observers that are no longer needed. (#642, #677)
-* Reworked logic in `List#adjustRowIndices` to not skip updating row indices
-  even when `maintainOddEven` is `false`.
-* Fixed an edge case in `OnDemandList` where it would refuse to load additional
-  data if the grid were resized larger while its viewport is scrolled to the top.
-  (#361)
-
-### Mixins
-
-* Fixed an issue in the `ColumnSet` mixin which affected horizontal scrolling at
-  certain zoom levels on Chrome.
-* The `Selection` and `CellSelection` mixins no longer lose selection of rows
-  when items are modified.  Rows are still deselected if items are removed.
-  (#226)
-
-### Column Plugins
-
-* Fixed issues in the `editor` column plugin regarding consistency of
-  dirty data and `dgrid-datachange` event firing for always-on radio buttons.
-* Fixed an issue in the `editor` plugin that caused errors in Chrome/Safari when
-  an editor loses focus and hides due to clicking within the browser's UI
-  controls. (#603)
-* Fixed an issue in the `editor` column plugin's cleanup logic which could occur
-  when the loading node for a request is removed before the request completes.
-  (#195)
-* The `editor` column plugin will now directly update row data in cases where
-  a store is not being used. (#171)
-
-### Extensions
-
-* Fixed an issue with the `ColumnReorder` extension involving grids whose IDs
-  end with a hyphen followed by numbers. (#556)
-* The `ColumnResizer` extension now properly calls the grid's `resize` method,
-  even on programmatically-triggered resize operations.
-* Fixed a potential issue in the `CompoundColumns` extension in non-ES5
-  environments that augment the Array prototype. (#624)
-* Added localizations for the `Pagination` extension:
-  * German (#657, thanks tryte)
-  * Traditional and Simplified Chinese (#671, thanks expando)
-  * Thai (#672, thanks dylans)
-
-# 0.3.8
-
-## Significant changes
-
-### General/Core
-
-* The `dgrid-sort` event now emits off of the original target of the event which
-  triggered it, rather than always off of the header cell. (#539)
-* Fixed a regression (present since 0.3.5) in `OnDemandList` which prevented
-  `noDataMessage` from being displayed for async stores. (#519)
-* `_StoreMixin` (used by `OnDemandList`, `OnDemandGrid`, and `Pagination`) now
-  supports calling the `set` method of Stateful objects during `save`.  (#563)
-
-### Column Plugins
-
-* Resolved an infinite-recursion regression in `selector`, observable when used
-  in conjunction with the `ColumnReorder` extension. (#525)
-
-### Extensions
-
-* Fixed a regression in the `ColumnResizer` extension where columns were no
-  longer appropriately adjusted when the first resize occurred. (#526)
-
-## Other changes and fixes
-
-### General/Core
-
-* Fixed issues in `OnDemandList` and the `Pagination` extension where
-  `noDataMessage` could potentially appear multiple times for successive
-  empty query results. (#542)
-
-### Mixins
-
-* Resolved an issue in the `ColumnSet` mixin which caused some browsers to block
-  clicks near the bottom of the grid when no ColumnSet scrollbars are shown.
-  (#571)
-
-### Column Plugins
-
-* Resolved an issue in `selector` where selectors would not work in cases where
-  the initial column structure did not contain a selector column, but the
-  structure was later changed to include one. (#533)
-* Resolved an issue in `selector` where rows that should be unselectable were
-  still selectable by clicking within the selector column. (#545)
-
-### Extensions
-
-* Revised the previous workaround for IE8 in the `ColumnHider` extension to
-  an alternative which involves less code and avoids an issue when all columns
-  are hidden. (#537)
-* The `DijitRegistry` extension now implements the `isLeftToRight` method, to
-  accommodate needs of Dijit layout widgets in Dojo 1.9. (#536)
-* The `DijitRegistry` extension now implements the `getParent` method, to
-  accommodate e.g. `dijit/_KeyNavContainer`. (#538, thanks k2s)
-* The `Pagination` extension now properly only shows page 1 once if there is
-  only one page of results. (#520)
-* The `Pagination` extension now properly initializes the page size drop-down
-  based on the initial `rowsPerPage` value, if one matches.
-  (#577, thanks Gordon Smith)
-
-# 0.3.7
-
-## Significant changes
-
-### General/Core
-
-* `Grid` now supports the `formatterScope` instance property, along the same
-  lines as `dojox/grid`. (#470; thanks gratex)
-* `Grid` has been refactored to include `formatter` considerations within the
-  default `renderCell` logic; this allows `formatter` functions to coexist with
-  the `editor` and `tree` column plugins. (#495, #497; thanks gratex)
-* Fixed an issue with `_StoreMixin` which caused `set` functions in column
-  definitions to be ignored for all but the last subrow or columnset. (#489)
-
-### Mixins
-
-* Fixed a regression in the `Selection` mixin due to text selection changes,
-  where Firefox would not allow selecting text or moving the cursor inside
-  form inputs. (#492)
-* The `Selection` mixin no longer calls `allowSelect` for `deselect` calls
-  (only `select` calls).  This avoids potential errors when resetting column
-  structures, and reduces unnecessary calls.
-* The `Selection` mixin has been refactored to break out logic for each selection
-  mode to a separate method.  These methods follow the naming convention
-  `_modeSelectionHandler` (where "mode" would be the name of the mode).
-  This allows custom selection modes to be added easily.
-* The `Selection` mixin now supports a `toggle` mode, useful for touch input
-  where holding a modifier key to deselect is generally not an option.
-* Fixed an issue with the `Selection` and `CellSelection` mixins where calling
-  `deselect` with a range would actually deselect the first target, then select
-  everything else in the range. (#491)
-
-### Column Plugins
-
-* The `selector` plugin will now match its disabled state against the
-  `allowSelect` method on the grid, as well as the column definition's
-  `disabled` function.
-* The `tree` plugin's `renderExpando` function now receives a 4th argument:
-  the object represented by the current row. (#427; thanks pags)
-
-### Extensions
-
-* The `ColumnResizer` extension no longer emits superfluous events for all columns
-  on the first resize. (#441)
-* The `DnD` extension now inherits the `Selection` mixin to guarantee resilient
-  handling of drag operations where part of the selection has scrolled out of
-  view and been unrendered.
-* The `Pagination` extension now applies the `dgrid-page-link` class to all
-  navigation controls (not just the page numbers), to make them distinguishable
-  by something other than what tag they use. (related to #379)
-
-## Other changes and fixes
-
-### General/Core
-
-* The `List` module's `startup` method now correctly checks `_started` before
-  calling `this.inherited`.  (Thanks dancrumb)
-* Fixed an issue in `List` which could cause errors on certain successive tree
-  row removals/insertions. (#418, #467)
-
-### Mixins
-
-* The `ColumnSet` mixin now adjusts the positioning of its scrollbars
-  appropriately if the footer node is present. (#463)
-* The `CellSelection` mixin now properly deselects if an unselected cell within
-  the same row as a selected cell is right-clicked.
-* Fixed issues with the `Keyboard` mixin pertaining to resetting columns, or
-  not setting them initially. (#494)
-* The `Keyboard` mixin now ensures that if the header area is scrolled due to a
-  focus shift, the body scrolls with it. (#474)
-
-### Column Plugins
-
-* Fixed an issue in the `editor` plugin that caused checkboxes to fail to
-  initialize values properly in IE < 8. (#479)
-* The `tree` plugin no longer completely overwrites classes on the expando node
-  when expanding/collapsing, so custom classes will be preserved. (#409)
-
-### Extensions
-
-* The `ColumnHider` extension now absolutely-positions the node for opening the
-  menu, which ensures it is visible even on platforms with no vertical scrollbars.
-  (#406)
-* The `ColumnHider` extension now relies on CSS to specify an icon, rather than
-  using text to show a plus sign.  The icon can be changed by overriding
-  the background on the `dgrid-hider-toggle` class.  (#306)
-* Fixed issues in the `ColumnHider` extension involving redundant calls to
-  `toggleColumnHiddenState`. (#464)
-* The `DnD` extension now cleans references from the dnd source's hash when
-  `removeRow` is called on the grid. (#335)
-* Resolved an issue in `Pagination` where IE9+ would dispatch events to the
-  wrong handlers after clicking one of the navigation controls. (#379)
-
-# 0.3.6
-
-## Breaking changes
-
-### OnDemandList's dgrid-refresh-complete event no longer includes rows
-
-The `rows` property of this event was removed to match the implementation
-added to the Pagination extension, which does not include it.  If a particular
-row is needed, it can be resolved from the QueryResults included on the event
-via `grid.row(...).element`.
-
-## Significant changes
-
-### General/Core
-
-* Added an index page to the test folder to browse the tests via a grid. (#407)
-* Added a preliminary set of DOH tests to assist in spotting regressions. (#412)
-
-### Mixins
-
-* The `Keyboard` mixin has been made significantly more extensible (#429):
-  * Added `keyMap` and `headerKeyMap` properties, which are object hashes
-    whose keys are event key codes and whose values are functions to be
-    executed in the context of the instance; if not specified, defaults
-    (exposed via `Keyboard.defaultKeyMap` and `keyboard.defaultHeaderKeyMap`)
-    will be used.
-  * Added `addKeyHandler(key, callback, isHeader)` method for registering
-    additional keyboard handlers; this is usually easier than trying to
-    override `keyMap` or `headerKeyMap`.
-* The `Keyboard` mixin no longer emits `dgrid-cellfocusout` and
-  `dgrid-cellfocusin` when spacebar is pressed. (#429)
-
-### Column Plugins
-
-* The `editor` column plugin now emits `dgrid-editor-show` and `dgrid-editor-hide`
-  events when an editor with `editOn` set is shown or hidden, respectively. (#424)
-* The `editor` column plugin now adds a `dgrid-cell-editing` class to any cell
-  containing an active editor. (#442; thanks Brandano for the idea)
-
-### Extensions
-
-* The `Pagination` extension now emits `dgrid-refresh-complete` like
-  `OnDemandList`.  (#188, #411)
-
-## Other changes and fixes
-
-### General/Core
-
-* Fixed `Grid#styleColumn`, which had broken in 0.3.5. (#408)
-* Fixed an issue with `Grid#cell` specific to when a cell object representing a
-  header cell was passed in. (#429)
-* The `Keyboard` mixin now properly handles Home/End keypresses.
-* Fixed logic in `_StoreMixin` to work around a
-  [Dojo 1.8 bug with `when`](http://bugs.dojotoolkit.org/ticket/16667), which
-  could inappropriately mutate the return value of `_trackError`. (#411)
-* Fixed logic in `OnDemandList` so that asynchronous errors during `refresh`
-  are properly signaled via the promise it returns. (#411)
-* Added CSS to ensure that IE6 renders empty `OnDemandList` preload nodes with
-  0 height. (#429)
-
-### Column Plugins
-
-* The `editor` plugin now supports widgets returning object values by comparing
-  using `valueOf`. (#256, #304, #423)
-* The `tree` plugin has been refactored to make use of the `util/has-css3`
-  module, rather than feature-detecting upon first expansion. (#416)
-* The `tree` plugin now implements `expand` such that it will bail out if the
-  target row is already in the desired state.
-
-# 0.3.5
-
-## Breaking changes
-
-### Signature of the newRow method
-
-The `newRow` method in List, called in reaction to observed store changes,
-has had its signature altered to match that of `insertRow`.  Please note
-that it is likely that `newRow` may be refactored out of existence in the future.
-
-### Grid and the columns property
-
-The `Grid` module now normalizes the `columns` instance property to an object
-even when it is passed in as an array. This means that any code written
-which accesses `grid.columns` directly will break if it expects it to maintain
-the array structure that was originally passed in.
-
-To compensate for this, `get("columns")` retains the previous behavior - it
-returns `columns` as initially passed, except in the case where `subRows` is
-passed instead, in which case it returns an object hash version of the structure
-keyed by column IDs.
-
-### put-selector version
-
-When updating to dgrid 0.3.5, make sure you also update your version of
-[put-selector](https://github.com/kriszyp/put-selector) to 0.3.1 or higher
-(0.3.2 is the latest at the time of this writing).  If you use
-[cpm](https://github.com/kriszyp/cpm) to update dgrid, this should happen
-automatically.
-
-## Significant changes
-
-### General/Core
-
-* `List` instances will now clean up any styles added dynamically via the
-    `addCssRule` method; this also applies by extension to `Grid#styleColumn`
-    and `ColumnSet#styleColumnSet`.  This may cause a change in behavior in some
-    edge cases; the previous behavior can be obtained by passing
-    `cleanAddedRules: false` in the constructor arguments object. (#371)
-* The `up` and `down` methods of `List` will now call `grid.row` internally to
-    resolve whatever argument is passed; the `left` and `right` methods of
-    `Grid` will call `grid.cell`.  (Formerly these methods only accepted a
-    row or cell object directly.)
-* The `Grid` module now ensures that an object hash of the grid's columns is
-    always available (see Breaking Changes above); this fixes issues when
-    column IDs are explicitly set, but then couldn't be properly looked up
-    against the `columns` array.
-* The `Grid` module now emits a `dgrid-sort` event when a sortable header cell
-    is clicked; this event includes a `sort` property, and may be canceled to
-    stop the sort, or to substitute alternative behavior.  In the latter case,
-    if updating the sort arrow in the UI is still desired, call the
-    `updateSortArrow` method and pass the `sort` value from the event.
-* The `OnDemandList` module now supports a `pagingMethod` property, which allows
-    specifying whether to throttle or debounce scroll events.  The default
-    behavior has been changed from `"throttleDelayed"` to `"debounce"`, which
-    generally is capable of far reducing the number of store queries issued,
-    moreso if `pagingDelay` is increased (though its default remains the same).
-* The `OnDemandList` module now supports a `keepScrollPosition` property, which
-    will attempt to preserve scroll position between refresh calls.  This can be
-    set on the instance itself to affect all refreshes, or can be passed to the
-    `refresh` method directly for a specific call.
-* The `OnDemandList` module now returns a promise from the `refresh` method,
-    which resolves when the grid finishes rendering results after the refresh.
-    It also emits a `dgrid-refresh-complete` event, which includes both a
-    reference to the QueryResults object (`results`) and the rendered rows
-    (`rows`).  In addition, the `dgrid-error` event now fires more consistently
-    (both for `OnDemandList` and `Pagination`).
-
-### Mixins
-
-* The `Selection` mixin now supports an `allowTextSelection` property, allowing
-    text selection within a List or Grid to be permitted or denied completely
-    independently from the `selectionMode` property; default behavior is still
-    to prevent unless `selectionMode` is `none`.  Selection prevention itself
-    has also been fixed to work in all browsers. (#148)
-
-### Column Plugins
-
-* Fixed a `tree` regression since 0.3.2 involving only-child rows being misplaced
-    upon observed changes. (#353)
-
-### Extensions
-
-* The `ColumnResizer` extension now supports an `adjustLastColumn` flag; when
-    set to `true` (the default, and previous behavior), this will adjust the
-    last column's width to `auto` at times where a column resize operation would
-    otherwise cause column widths to stretch due to how browsers render tables.
-    This can be set to `false` to purposely disable this behavior.
-* The `Pagination` extension now returns a promise from the `refresh` and
-    `gotoPage` methods, which resolves when the grid finishes rendering results.
-    Note that it does not (yet) emit an event like `OnDemandList`.
-* The `Pagination` extension now re-queries for the current page of data when
-    the grid is notified of a store modification which affects the number of
-    items currently rendered. (#283)
-* The `Pagination` extension now supports a `showLoadingMessage` property; by
-    default (`true`), a loading node will be displayed whenever a new page is
-    requested; if set to `false`, the grid will instead retain the previous
-    content until the new data is fully received and ready to render. (#219)
-* The `Pagination` extension now includes localized strings for the following languages:
-    * French (#381, thanks mduriancik)
-    * Brazilian Portuguese (#376, thanks stavarengo)
-    * Slovak (#381, thanks mduriancik)
-* The `DijitRegistry` extension now supports dgrid components as direct children
-    of common Dijit layout container widgets, and will now properly alter the
-    size of a list or grid if the `resize` method is passed an argument. (#401)
-
-## Other changes and fixes
-
-### General/Core
-
-* Resolved an issue where upon changing column structure, the placement of the
-    sort arrow would be lost even though the grid is still sorting by the same
-    field.
-* Simplified logic in `Grid` to always create `tr` elements. (#387)
-* Resolved an issue where `OnDemandList` could end up firing requests where
-    start exceeds total and count is negative. (#323)
-* Resolved issues regarding proper handling of errors / rejected promises in
-    `OnDemandList` as well as the `Pagination` extension.
-    (#351; obsoletes #241, #242)
-* Resolved potential memory leaks in `Grid`, `ColumnSet`, and `ColumnResizer`.
-    (#393, #394, #395, #396, #397)
-* Resolved issues in `Grid`, `ColumnSet`, `ColumnHider`, and `ColumnResizer`
-    regarding dynamic style injection for grids with DOM node IDs containing
-    unsafe characters; added `escapeCssIdentifier` function to `util/misc`. (#402)
-* Resolved an issue in `TouchScroll` which unnecessarily prevented native
-    touch-scrolling even when the component can't be scrolled. (#344)
-
-### Mixins
-
-* Resolved an issue with the `ColumnSet` mixin where clicking within the
-    horizontal scrollbar area (aside from the arrows/handle) wouldn't work in IE.
-    (#307)
-* Improved logic of `isSelect` for `Selection` and `CellSelection` regarding
-    unloaded rows/cells in combination with the select-all feature in some cases.
-    (#258)
-
-### Extensions
-
-* Resolved an issue where `ColumnHider` would leave styles applied for hiding
-    columns, which could have adverse effects if a new grid is later created
-    with the same ID. (#371)
-* Resolved an issue with `ColumnHider` which could cause the hidden state of
-    columns to be forgotten when other components such as `ColumnReorder`
-    interact with the column structure. (#289)
-* Resolved an issue with `ColumnHider` related to IE8 standards mode's handling
-    of `display: none` cells. (#362)
-* Resolved an issue where widths set via the `ColumnResizer` extension would be
-    reset upon rearranging columns with the `ColumnReorder` extension.
-* Resolved an issue in `ColumnResizer` styles which caused body and header cells
-    to skew in Chrome 19 and Safari 6. (#142, #370)
-* Changed name of private `_columnStyles` object used by the `ColumnResizer`
-    extension to `_columnSizes` to reduce ambiguity.
-* The `Pagination` extension will no longer immediately throw errors if it is
-    initialized without a store.  However, a warning will be logged, and any
-    method calls will likely throw errors until a store is assigned. (#355)
-
-# 0.3.4
-
-## Significant changes
-
-### Extensions
-
-* The `ColumnResizer` extension now emits a `dgrid-columnresize` event when a resize
-    occurs; if initiated by the user, the event will include a `parentType` property
-    indicating the type of event that triggered it.  If this event is canceled,
-    the column will not be resized. (#320)
-* The `ColumnResizer` extension now honors a `width` property included on column
-    definition objects for the purpose of initializing the width of a column; this
-    can be useful if it is desired to persist and restore custom column widths
-    from a cookie or other local storage. (#321)
-* The `ColumnResizer` extension now honors a `resizable` property included on
-    column definition objects for the purpose of disallowing resize of specific
-    columns. (#325)
-
-## Other changes and fixes
-
-### General/Core
-
-* Resolved an issue in `List` relating to scrolling and preload nodes. (#318, #323)
-
-### Mixins
-
-* The `ColumnSet` mixin now supports horizontal mousewheel events. (#239)
-
-### Column Plugins
-
-* The column plugins (`editor`, `selector`, and `tree`) can now be invoked without
-    a column definition object at all, if no properties need to be set.  This
-    is mostly useful for `selector`. (#324)
-* Fixed an issue with the `selector` plugin when a column definition lacks a
-    `label` property. (#324)
-* Always-on `editor` columns now honor the `canEdit` function on column definitions
-    at the time each cell is rendered.
-* Always-on `editor` columns now properly revert values if the `dgrid-datachange`
-    event is canceled. (#252)
-
-### Extensions
-
-* The `ColumnResizer` extension's resize indicator now follows the cursor
-    even when dragging beyond the grid's boundaries, and reacts if the mouse
-    button is released even outside the boundaries of the browser window. (#310)
-
-# 0.3.3
-
-## Breaking changes
-
-* The `Keyboard` module's `dgrid-cellfocusin` and `dgrid-cellfocusout` events
-    now report either a `row` or `cell` object, depending on whether
-    `cellNavigation` is `false` or `true`, respectively.  (Formerly these events
-    always contained a `cell` property pointing to the DOM node that fired the event.)
-* Several mixin and extension modules have had their `declare` hierarchies
-    simplified under the expectation that they will always be mixed in as
-    documented, and never be instantiated directly.  To be clear, this will not
-    break any code that is written as prescribed by the documentation.
-
-## Significant changes
-
-* All custom events fired by dgrid components now report the following properties:
-    * `grid`: The dgrid instance which fired the event.
-    * `parentType`: If the event was fired in direct response to another event,
-        this property reflects the type of the originating event.  If the event
-        was fired due to a direct API call, `parentType` will not be defined.
-* The `ColumnReorder` extension now fires a `dgrid-columnreorder` event when
-    a column is reordered via drag'n'drop.  Note that this event always reports
-    a `parentType` of `"dnd"` (there is no way to trigger this event directly
-    from an API call).
-* The `Pagination` extension now exposes and references its i18n strings via the
-    `i18nPagination` instance property, allowing these strings to be overridden.
-    (#225)
-
-## Other changes and fixes
-
-### General/Core
-
-* Fixed an issue with the `up` and `down` methods in `List` and the `left` and
-    `right` methods in `Grid`, which could cause them to attempt to traverse
-    outside the list/grid in question.
-* Fixed an issue in the observer code in `List` which could cause an updated
-    row to render out-of-sequence when `tree` is used. (#154)
-* Fixed an issue that could cause old IE to throw errors due to an undefined
-    parameter to `insertBefore`. (#308)
-* The `_StoreMixin` module now shows/hides a node displaying `noDataMessage` in
-    reaction to the last row being removed or first row being added. (#229)
-* The `OnDemandList` module now adheres more strictly to the `maxRowsPerPage`
-    property.  To accommodate this, the default has been increased from `100` to
-    `250`. (#280)
-* The `OnDemandList` module's default value for `farOffRemoval` has been
-    lowered from `10000` to `2000`.
-* The `loadingMessage` property (referenced by `OnDemandList` and the `Pagination`
-    extension) now supports HTML strings, like `noDataMessage` (#312)
-* The CSS for one of the `util/has-css3` module's tests has had its class renamed
-    to prevent conflicting with users of Modernizr. (#313)
-
-### Mixins
-
-* The `Selection` mixin in single-selection mode now properly allows reselecting
-    a row that was deselected immediately prior. (#295)
-
-### Extensions
-
-* The `ColumnHider` extension will now resize its popup element and enable
-    scrolling within it, in cases where its height would otherwise exceed the
-    that of the parent grid. (#311)
-* The `Pagination` extension now supports `noDataMessage` like `OnDemandList`. (#180)
-
-# 0.3.2
-
-## Breaking changes
-
-### GridFromHtml and OnDemandGrid
-
-The `GridFromHtml` module no longer automatically mixes in the `OnDemandGrid`
-module, mixing in only `Grid` instead, in order to support the option of using
-alternative store-backed mechanisms such as the `Pagination` extension.
-This may cause existing code which relied on `GridFromHtml` and loaded from a
-store to break.  Such cases will now need to mix in `OnDemandList` manually
-(they don't need to mix in `OnDemandGrid`, since `Grid` is still inherited by
-`GridFromHtml`).
-
-There are a couple of ways to deal with this.  In Dojo 1.8, when parsing dgrid
-instances declaratively, the new `data-dojo-mixins` attribute can be used to
-mix `OnDemandList` into `GridFromHtml`:
-
-```html
-<table data-dojo-type="dgrid/GridFromHtml" data-dojo-mixins="dgrid/OnDemandList" data-dojo-props="...">
-    ...
-</table>
-```
-
-In the case of Dojo 1.7, `dojo/parser` doesn't understand module IDs, and so a
-global reference to the dgrid components used is needed.  Changing such code to
-mix in `OnDemandList` involves nothing more than an additional use of `declare`:
-
-```html
-<table data-dojo-type="dgrid.OnDemandGridFromHtml" data-dojo-props="...">
-    ...
-</table>
-...
-<script>
-    var dgrid = {}; // declared in global scope
-    require(["dojo/_base/declare", "dojo/parser", "dgrid/GridFromHtml", "dgrid/OnDemandList", ..., "dojo/domReady!"],
-    function(declare, parser, GridFromHtml, OnDemandList, ...) {
-        // Create dgrid constructor with necessary components, available in the global scope.
-        dgrid.OnDemandGridFromHtml = declare([GridFromHtml, OnDemandList]);
-        
-        // Parse the document, now that the above constructor is available.
-        parser.parse();
-    });
-</script>
-```
-
-## Significant changes
-
-### General/Core
-
-* All dgrid components now have `scrollTo` and `getScrollPosition` methods,
-  either inheriting from `TouchScroll` (see below) or implemented in `List`
-  based on `scrollTop` and `scrollLeft`.  Updates have been made to dgrid
-  components where necessary to leverage these methods.
-* All dgrid components now respond to `set("showFooter")` consistently with
-  `set("showHeader")`. (#284)
-* It is now possible to initialize or later set CSS classes on a dgrid component's
-  top DOM node via `"class"` or `className`. (#183)
-* `_StoreMixin` (used by `OnDemandList` and the `Pagination` extension) now
-  includes a reference to the grid instance in emitted `dgrid-error` events
-  (via a `grid` property on the `error` object).
-* The `TouchScroll` module has undergone significant changes and improvements:
-    * uses CSS3 `translate3d` to take advantage of hardware acceleration
-        * a `util/has-css3` module has been added with has-feature tests to
-          detect CSS3 features to be used by `TouchScroll`
-    * implements increased tension and bounce-back beyond edges
-    * displays scrollbars as appropriate while scrolling
-    * implements `scrollTo` and `getScrollPosition` methods to allow manipulation
-      and retrieval of scroll information based on CSS transformations
-    * allows configuring how many touches are necessary to activate scrolling,
-      via the `touchesToScroll` property
-
-### Mixins
-
-* The `ColumnSet` mixin now defines a `styleColumnSet` method, which is
-  analogous to Grid's `styleColumn` method, but instead adds a style rule for
-  the class on nodes containing the entire columnset contents for a row.
-* The `Keyboard` mixin now defines `focus` and `focusHeader` methods, for
-  programmatically focusing a row or cell (depending on the value of the
-  `cellNavigation` setting). (#130)
-
-### Column Plugins
-
-* The `tree` column plugin now supports a `collapseOnRefresh` property in the
-  column definition; if set to `true`, it will cause all parent rows to render
-  collapsed whenever the grid is refreshed, rather than remembering their
-  previous state.
-* The `tree` column plugin now supports a `allowDuplicates` property in the
-  column definition; this can be set to `true` to allow for cases where the same
-  item may appear under multiple parents in the tree.  Note however that it
-  limits the capabilities of the `row` method to the top level only. (#147)
-
-### Extensions
-
-* A `CompoundColumns` extension has been added, which allows defining column
-  structures which include additional spanning header cells describing the
-  contents beneath.
-* The `ColumnHider` extension has undergone some refactoring to make it more
-  extensible and to provide a public API for toggling the hidden state of a
-  column, via the `toggleColumnHiddenState(columnId)` method.
-* The `ColumnReorder` extension has been refactored to allow reordering of
-  columns within the same subrow or columnset in more complex column structures,
-  in addition to the previous ability to reorder columns in simple single-row
-  structures.
-* The `DnD` extension now properly supports touch devices when used with Dojo 1.8.
-* The `DnD` extension now supports specifying a `getObjectDndType` function, for
-  customizing the DnD type reported for each item rendered.
-
-## Other changes and fixes
-
-### General/Core
-
-* Several accessibility issues have been addressed, including fixes to the
-  roles reported by certain elements, and labels added to the Pagination
-  extension's controls. (Partly attributed to #273)
-* `Grid`: calls to `cell` with a falsy `columnId` value now work properly. (#198)
-* Fixed an issue with dgrid instances not reacting correctly to window resize.
-* Fixed an issue affecting odd/even row classes on in-place updates. (#269)
-* Fixed a rendering issue involving confusion of preload node dimensions. (#161)
-* Fixed an issue causing `tree` level indentation to render improperly when used
-  with the `Pagination` extension.
-* Fixed a deprecated API call in `_StoreMixin`. (#272)
-* Improved logic in `OnDemandList` to properly account for lists with displays
-  which tile items using `display: inline-block`.
-
-### Mixins
-
-* The `ColumnSet` mixin now behaves properly when calling
-  `set("columnSets", ...)`. (#202)
-* The non-standard `colsetid` attribute assigned to nodes by the `ColumnSet`
-  mixin has been replaced with the `data-dgrid-column-set-id` attribute.
-* The `Selection` mixin will now properly reset `_lastSelected` when
-  `clearSelection` is called. (#175)
-* The `Selection` mixin will now wait until `mouseup` when handling mouse events
-  on targets that are already selected. (#251)
-
-### Column Plugins
-
-* The `expand` method defined by the `tree` column plugin will no longer
-  be called at all in reaction to events on rows which report no children.
-
-### Extensions
-
-* The `ColumnHider` extension now supports setting `hidden` and `unhidable`
-  together, resulting in the column being hidden and not being present in the
-  popup menu (but it can still be shown programmatically). (#199)
-* The `ColumnHider` extension now behaves appropriately for columns with no
-  `label` defined. (#244)
-* A number of protected members in the `ColumnHider` extension have been renamed:
-    * `_toggleColumnState` has been replaced by `_setColumnHiddenState` and the
-      public API `toggleColumnHiddenState` mentioned above
-    * `_toggleHiderMenu` has been renamed to `_toggleColumnHiderMenu`
-    * `_columnStyleRules` has been renamed to `_columnHiderRules`
-* An issue with the `ColumnResizer` extension which could cause distortion of
-  width values on the first resize has been fixed. (#291)
-* The `DnD` extension can now drag non-root tree items *in Dojo 1.8 only* by
-  passing `allowNested: true` to the source via `dndParams`. (#68)
-* The `DnD` extension now behaves better with regard to synchronizing with
-  dgrid's `Selection` mixin, and also with regard to dragging when some selected
-  nodes are no longer in the DOM. (#185, #246)
-* The `DnD` extension now adds CSS to adequately override spurious styles which
-  can leak in from dijit.css in Dojo 1.8. (#255)
-
-# 0.3.1
-
-## Significant changes
-
-* Column plugins can now define the following functions on column definitions,
-  providing more opportune timing for initialization and tear-down:
-    * `init`, which will be executed at the time the grid's column configuration
-      is (re-)applied
-    * `destroy`, which will be executed when the grid is destroyed, as well as
-      before a new column configuration is applied
-* The `tree` plugin now supports the following column definition properties:
-    * `shouldExpand(row, level, previouslyExpanded)`, a function providing for
-      conditional automatic expansion of parent rows (#141)
-    * `indentWidth`, an integer specifying the size (in pixels) of each level's
-      indent (note that the default is now `9`, though it was previously `19`)
-    * `renderExpando()`, a function which can replace the default logic for
-      rendering the expando node (the arrow next to the content of each cell)
-* The `editor` plugin now augments the grid instance with an `edit(cell)` method
-  which can be used to programmatically activate the editor in a given cell.
-* A `util/mouse` module has been added, which exposes simulated events for
-  the mouse entering and leaving grid rows and cells. (#165)
-* A `package.js` has been added in order to streamline the build process.
-  `package.json` has been updated to reflect the presence of `package.js` and
-  reference the latest versions of xstyle and put-selector, each of which now
-  have a `package.js` of their own.
-
-## Other Fixes
-
-* Mouse events for expanding/collapsing rows in tree grids should be a bit more
-  reliable. (#112)
-* Rows expanded in a tree grid which has been started up but is currently hidden
-  will now be rendered properly when re-shown. (#140)
-* The `tree` and `editor` plugins can now both be used on the same column, by
-  wrapping `editor` with `tree`. (#144)
-* `sortable` now defaults to `false` for columns where `field` is `"_item"`
-  or entirely unspecified (in which case there's nothing to sort by anyway).
-  (#149)
-* The `Pagination` extension now behaves appropriately with empty result sets.
-  (#173)
-* The `ColumnHider` extension now iterates over `subRows` rather than `columns`,
-  making it a bit more reliable in general. (#164)
-* A couple of issues with the `DijitRegistry` extension were identified and
-  fixed. (#146, thanks jdohert)

+ 0 - 156
esp/files/dgrid/CellSelection.js

@@ -1,156 +0,0 @@
-define([
-	"dojo/_base/declare",
-	"dojo/aspect",
-	"dojo/on",
-	"dojo/has",
-	"./Selection",
-	"put-selector/put"
-], function(declare, aspect, listen, has, Selection, put){
-
-return declare(Selection, {
-	// summary:
-	//		Add cell level selection capabilities to a grid. The grid will have a selection property and
-	//		fire "dgrid-select" and "dgrid-deselect" events.
-	
-	// ensure we don't select when an individual cell is not identifiable
-	selectionDelegate: ".dgrid-cell",
-	
-	_selectionTargetType: "cells",
-	
-	_select: function(cell, toCell, value){
-		var i, id;
-		if(typeof value === "undefined"){
-			// default to true
-			value = true;
-		}
-		if(typeof cell != "object" || !("element" in cell)){
-			cell = this.cell(cell);
-		}else if(!cell.row){
-			// Row object was passed instead of cell
-			if(value && typeof value === "object"){
-				// value is a hash of true/false values
-				for(id in value){
-					this._select(this.cell(cell.id, id), null, value[id]);
-				}
-			}else{
-				// Select/deselect all columns in row
-				for(id in this.columns){
-					this._select(this.cell(cell.id, id), null, value);
-				}
-			}
-			return;
-		}
-		if(this.allowSelect(cell)){
-			var selection = this.selection,
-				rowId = cell.row.id,
-				previousRow = selection[rowId];
-			if(!cell.column){
-				for(i in this.columns){
-					this._select(this.cell(rowId, i), null, value);
-				}
-				return;
-			}
-			var previous = previousRow && previousRow[cell.column.id];
-			if(value === null){
-				// indicates a toggle
-				value = !previous;
-			}
-			var element = cell.element;
-			previousRow = previousRow || {};
-			previousRow[cell.column.id] = value;
-			this.selection[rowId] = previousRow;
-			
-			// Check for all-false objects to see if it can be deleted.
-			// This prevents build-up of unnecessary iterations later.
-			var hasSelected = false;
-			for(i in previousRow){
-				if(previousRow[i] === true){
-					hasSelected = true;
-					break;
-				}
-			}
-			if(!hasSelected){ delete this.selection[rowId]; }
-			
-			if(element){
-				// add or remove classes as appropriate
-				if(value){
-					put(element, ".dgrid-selected.ui-state-active");
-				}else{
-					put(element, "!dgrid-selected!ui-state-active");
-				}
-			}
-			if(value != previous && element){
-				this._selectionEventQueues[(value ? "" : "de") + "select"].push(cell);
-			}
-			if(toCell){
-				// a range
-				if(!toCell.element){
-					toCell = this.cell(toCell);
-				}
-				var toElement = toCell.element;
-				var fromElement = cell.element;
-				// find if it is earlier or later in the DOM
-				var traverser = (toElement && (toElement.compareDocumentPosition ? 
-					toElement.compareDocumentPosition(fromElement) == 2 :
-					toElement.sourceIndex > fromElement.sourceIndex)) ? "nextSibling" : "previousSibling";
-				// now we determine which columns are in the range 
-				var idFrom = cell.column.id, idTo = toCell.column.id, started, columnIds = [];
-				for(id in this.columns){
-					if(started){
-						columnIds.push(id);				
-					}
-					if(id == idFrom && (idFrom = columnIds) || // once found, we mark it off so we don't hit it again
-						id == idTo && (idTo = columnIds)){
-						columnIds.push(id);
-						if(started || // last id, we are done 
-							(idFrom == columnIds && id == idTo)){ // the ids are the same, we are done
-							break;
-						}
-						started = true;
-					}
-				}
-				// now we iterate over rows
-				var row = cell.row, nextNode = row.element;
-				toElement = toCell.row.element;
-				do{
-					// looping through each row..
-					// and now loop through each column to be selected
-					for(i = 0; i < columnIds.length; i++){
-						cell = this.cell(nextNode, columnIds[i]);
-						this._select(cell, null, value);
-					}
-					if(nextNode == toElement){
-						break;
-					}
-				}while((nextNode = cell.row.element[traverser]));
-			}
-		}
-	},
-	isSelected: function(object, columnId){
-		// summary:
-		//		Returns true if the indicated cell is selected.
-		
-		if(typeof object === "undefined" || object === null){
-			return false;
-		}
-		if(!object.element){
-			object = this.cell(object, columnId);
-		}
-		
-		// First check whether the given cell is indicated in the selection hash;
-		// failing that, check if allSelected is true (testing against the
-		// allowSelect method if possible)
-		var rowId = object.row.id;
-		if(rowId in this.selection){
-			return !!this.selection[rowId][object.column.id];
-		}else{
-			return this.allSelected && (!object.row.data || this.allowSelect(object));
-		}
-	},
-	clearSelection: function(exceptId){
-		// disable exceptId in cell selection, since it would require double parameters
-		exceptId = false;
-		this.inherited(arguments);
-	}
-});
-});

+ 0 - 275
esp/files/dgrid/ColumnSet.js

@@ -1,275 +0,0 @@
-define(["dojo/_base/kernel", "dojo/_base/declare", "dojo/_base/lang", "dojo/_base/Deferred", "dojo/on", "dojo/aspect", "dojo/query", "dojo/has", "./util/misc", "put-selector/put", "xstyle/has-class", "./Grid", "dojo/_base/sniff", "xstyle/css!./css/columnset.css"],
-function(kernel, declare, lang, Deferred, listen, aspect, query, has, miscUtil, put, hasClass, Grid){
-	has.add("event-mousewheel", function(global, document, element){
-		return typeof element.onmousewheel !== "undefined";
-	});
-	has.add("event-wheel", function(global, document, element){
-		var supported = false;
-		// From https://developer.mozilla.org/en-US/docs/Mozilla_event_reference/wheel
-		try{
-			WheelEvent("wheel");
-			supported = true;
-		}catch(e){ // empty catch block; prevent debuggers from snagging
-		}finally{
-			return supported;
-		}
-	});
-
-	var colsetidAttr = "data-dgrid-column-set-id";
-	
-	hasClass("safari", "ie-7");
-	
-	function adjustScrollLeft(grid, row){
-		var scrollLefts = grid._columnSetScrollLefts;
-		function doAdjustScrollLeft(){
-			query(".dgrid-column-set", row).forEach(function(element){
-				element.scrollLeft = scrollLefts[element.getAttribute(colsetidAttr)];
-			});
-		}
-		if(has("ie") < 8 || has("quirks")){
-			setTimeout(doAdjustScrollLeft, 1);
-		}else{
-			doAdjustScrollLeft();
-		}
-	}
-	
-	function scrollColumnSet(grid, columnSetNode, amount){
-		var id = columnSetNode.getAttribute(colsetidAttr),
-			scroller = grid._columnSetScrollers[id],
-			scrollLeft = scroller.scrollLeft + amount;
-
-		scroller.scrollLeft = scrollLeft < 0 ? 0 : scrollLeft;
-	}
-	
-	var horizMouseWheel;
-	if(!has("touch")){
-		horizMouseWheel = has("event-mousewheel") || has("event-wheel") ? function(grid){
-			return function(target, listener){
-				return listen(target, has("event-wheel") ? "wheel" : "mousewheel", function(event){
-					var node = event.target, deltaX;
-					// WebKit will invoke mousewheel handlers with an event target of a text
-					// node; check target and if it's not an element node, start one node higher
-					// in the tree
-					if(node.nodeType !== 1){
-						node = node.parentNode;
-					}
-					while(!query.matches(node, ".dgrid-column-set[" + colsetidAttr + "]", target)){
-						if(node === target || !(node = node.parentNode)){
-							return;
-						}
-					}
-					
-					// Normalize reported delta value:
-					// wheelDeltaX (webkit, mousewheel) needs to be negated and divided by 3
-					// deltaX (FF17+, wheel) can be used exactly as-is
-					deltaX = event.deltaX || -event.wheelDeltaX / 3;
-					if(deltaX){
-						// only respond to horizontal movement
-						listener.call(null, grid, node, deltaX);
-					}
-				});
-			};
-		} : function(grid){
-			return function(target, listener){
-				return listen(target, ".dgrid-column-set[" + colsetidAttr + "]:MozMousePixelScroll", function(event){
-					if(event.axis === 1){
-						// only respond to horizontal movement
-						listener.call(null, grid, this, event.detail);
-					}
-				});
-			};
-		};
-	}
-	
-	return declare(null, {
-		// summary:
-		//		Provides column sets to isolate horizontal scroll of sets of 
-		//		columns from each other. This mainly serves the purpose of allowing for
-		//		column locking.
-		
-		postCreate: function(){
-			this.inherited(arguments);
-			
-			if(!has("touch")){
-				this.on(horizMouseWheel(this), function(grid, colsetNode, amount){
-					var id = colsetNode.getAttribute(colsetidAttr),
-						scroller = grid._columnSetScrollers[id],
-						scrollLeft = scroller.scrollLeft + amount;
-					
-					scroller.scrollLeft = scrollLeft < 0 ? 0 : scrollLeft;
-				});
-			}
-		},
-		columnSets: [],
-		createRowCells: function(tag, each, subRows, object){
-			var row = put("table.dgrid-row-table");
-			var tr = put(row, "tbody tr");
-			for(var i = 0, l = this.columnSets.length; i < l; i++){
-				// iterate through the columnSets
-				var cell = put(tr, tag + ".dgrid-column-set-cell.dgrid-column-set-" + i +
-					" div.dgrid-column-set[" + colsetidAttr + "=" + i + "]");
-				cell.appendChild(this.inherited(arguments, [tag, each, this.columnSets[i], object]));
-			}
-			return row;
-		},
-		renderArray: function(){
-			var grid = this,
-				rows = this.inherited(arguments);
-
-			Deferred.when(rows, function(rows){
-				for(var i = 0; i < rows.length; i++){
-					adjustScrollLeft(grid, rows[i]);
-				}
-			});
-			return rows;
-		},
-
-		renderHeader: function(){
-			// summary:
-			//		Setup the headers for the grid
-			this.inherited(arguments);
-			
-			var columnSets = this.columnSets,
-				domNode = this.domNode,
-				scrollers = this._columnSetScrollers,
-				scrollerContents = this._columnSetScrollerContents = {},
-				scrollLefts = this._columnSetScrollLefts = {},
-				grid = this,
-				i, l;
-			
-			function reposition(){
-				grid._positionScrollers();
-			}
-			
-			if (scrollers) {
-				// this isn't the first time; destroy existing scroller nodes first
-				for(i in scrollers){
-					put(scrollers[i], "!");
-				}
-			} else {
-				// first-time-only operations: hook up event/aspected handlers
-				aspect.after(this, "resize", reposition, true);
-				aspect.after(this, "styleColumn", reposition, true);
-				listen(domNode, ".dgrid-column-set:dgrid-cellfocusin", lang.hitch(this, '_onColumnSetScroll'));
-			}
-			
-			// reset to new object to be populated in loop below
-			scrollers = this._columnSetScrollers = {};
-			
-			for(i = 0, l = columnSets.length; i < l; i++){
-				this._putScroller(columnSets[i], i);
-			}
-			
-			this._positionScrollers();
-		},
-		
-		styleColumnSet: function(colsetId, css){
-			// summary:
-			//		Dynamically creates a stylesheet rule to alter a columnset's style.
-			
-			var rule = this.addCssRule("#" + miscUtil.escapeCssIdentifier(this.domNode.id) + " .dgrid-column-set-" + colsetId, css);
-			this._positionScrollers();
-			return rule;
-		},
-		
-		_destroyColumns: function(){
-			var columnSetsLength = this.columnSets.length,
-				i, j, k, subRowsLength, len, columnSet, subRow, column;
-			for(i = 0; i < columnSetsLength; i++){
-				columnSet = this.columnSets[i];
-				for(j = 0, subRowsLength = columnSet.length; j < subRowsLength; j++){
-					subRow = columnSet[j];
-					for(k = 0, len = subRow.length; k < len; k++){
-						column = subRow[k];
-						if(typeof column.destroy === "function"){ column.destroy(); }
-					}
-				}
-			}
-			this.inherited(arguments);
-		},
-		configStructure: function(){
-			this.columns = {};
-			for(var i = 0, l = this.columnSets.length; i < l; i++){
-				// iterate through the columnSets
-				var columnSet = this.columnSets[i];
-				for(var j = 0; j < columnSet.length; j++){
-					columnSet[j] = this._configColumns(i + "-" + j + "-", columnSet[j]);
-				}
-			}
-		},
-
-		_positionScrollers: function (){
-			var domNode = this.domNode,
-				scrollers = this._columnSetScrollers,
-				scrollerContents = this._columnSetScrollerContents,
-				columnSets = this.columnSets,
-				left = 0,
-				scrollerWidth = 0,
-				numScrollers = 0, // tracks number of visible scrollers (sets w/ overflow)
-				i, l, columnSetElement, contentWidth;
-			
-			for(i = 0, l = columnSets.length; i < l; i++){
-				// iterate through the columnSets
-				left += scrollerWidth;
-				columnSetElement = query('.dgrid-column-set[' + colsetidAttr + '="' + i +'"]', domNode)[0];
-				scrollerWidth = columnSetElement.offsetWidth;
-				contentWidth = columnSetElement.firstChild.offsetWidth;
-				scrollerContents[i].style.width = contentWidth + "px";
-				scrollers[i].style.width = scrollerWidth + "px";
-				scrollers[i].style.bottom = this.showFooter ? this.footerNode.offsetHeight + "px" : "0px";
-				// IE seems to need scroll to be set explicitly
-				scrollers[i].style.overflowX = contentWidth > scrollerWidth ? "scroll" : "auto";
-				scrollers[i].style.left = left + "px";
-				// Keep track of how many scrollbars we're showing
-				if(contentWidth > scrollerWidth){ numScrollers++; }
-			}
-			
-			// Align bottom of body node depending on whether there are scrollbars
-			this.bodyNode.style.bottom = numScrollers ?
-				(has("dom-scrollbar-height") + (has("ie") ? 1 : 0) + "px") :
-				"0";
-		},
-
-		_putScroller: function (columnSet, i){
-			// function called for each columnSet
-			var scroller = this._columnSetScrollers[i] =
-				put(this.domNode, "div.dgrid-column-set-scroller.dgrid-column-set-scroller-" + i +
-					"[" + colsetidAttr + "=" + i +"]");
-			this._columnSetScrollerContents[i] = put(scroller, "div.dgrid-column-set-scroller-content");
-			listen(scroller, "scroll", lang.hitch(this, '_onColumnSetScroll'));
-		},
-
-		_onColumnSetScroll: function (evt){
-			var scrollLeft = evt.target.scrollLeft,
-				colSetId = evt.target.getAttribute(colsetidAttr),
-				newScrollLeft;
-
-			if(this._columnSetScrollLefts[colSetId] != scrollLeft){
-				query('.dgrid-column-set[' + colsetidAttr + '="' + colSetId + '"],.dgrid-column-set-scroller[' + colsetidAttr + '="' + colSetId + '"]', this.domNode).
-					forEach(function(element, i){
-						element.scrollLeft = scrollLeft;
-						if(!i){
-							// Compute newScrollLeft based on actual resulting
-							// value of scrollLeft, which may be different than
-							// what we assigned under certain circumstances
-							// (e.g. Chrome under 33% / 67% / 90% zoom).
-							// Only need to compute this once, as it will be the
-							// same for every row.
-							newScrollLeft = element.scrollLeft;
-						}
-					});
-				this._columnSetScrollLefts[colSetId] = newScrollLeft;
-			}
-		},
-		
-		_setColumnSets: function(columnSets){
-			this._destroyColumns();
-			this.columnSets = columnSets;
-			this._updateColumns();
-		},
-		setColumnSets: function(columnSets){
-			kernel.deprecated("setColumnSets(...)", 'use set("columnSets", ...) instead', "dgrid 0.4");
-			this.set("columnSets", columnSets);
-		}
-	});
-});

+ 0 - 527
esp/files/dgrid/Grid.js

@@ -1,527 +0,0 @@
-define(["dojo/_base/kernel", "dojo/_base/declare", "dojo/on", "dojo/has", "put-selector/put", "./List", "./util/misc", "dojo/_base/sniff"],
-function(kernel, declare, listen, has, put, List, miscUtil){
-	var contentBoxSizing = has("ie") < 8 && !has("quirks");
-	var invalidClassChars = /[^\._a-zA-Z0-9-]/g;
-	function appendIfNode(parent, subNode){
-		if(subNode && subNode.nodeType){
-			parent.appendChild(subNode);
-		}
-	}
-	
-	var Grid = declare(List, {
-		columns: null,
-		// cellNavigation: Boolean
-		//		This indicates that focus is at the cell level. This may be set to false to cause
-		//		focus to be at the row level, which is useful if you want only want row-level
-		//		navigation.
-		cellNavigation: true,
-		tabableHeader: true,
-		showHeader: true,
-		column: function(target){
-			// summary:
-			//		Get the column object by node, or event, or a columnId
-			if(typeof target != "object"){
-				return this.columns[target];
-			}else{
-				return this.cell(target).column;
-			}
-		},
-		listType: "grid",
-		cell: function(target, columnId){
-			// summary:
-			//		Get the cell object by node, or event, id, plus a columnId
-			
-			if(target.column && target.element){ return target; }
-			
-			if(target.target && target.target.nodeType){
-				// event
-				target = target.target;
-			}
-			var element;
-			if(target.nodeType){
-				var object;
-				do{
-					if(this._rowIdToObject[target.id]){
-						break;
-					}
-					var colId = target.columnId;
-					if(colId){
-						columnId = colId;
-						element = target;
-						break;
-					}
-					target = target.parentNode;
-				}while(target && target != this.domNode);
-			}
-			if(!element && typeof columnId != "undefined"){
-				var row = this.row(target),
-					rowElement = row && row.element;
-				if(rowElement){
-					var elements = rowElement.getElementsByTagName("td");
-					for(var i = 0; i < elements.length; i++){
-						if(elements[i].columnId == columnId){
-							element = elements[i];
-							break;
-						}
-					}
-				}
-			}
-			if(target != null){
-				return {
-					row: row || this.row(target),
-					column: columnId && this.column(columnId),
-					element: element
-				};
-			}
-		},
-		
-		createRowCells: function(tag, each, subRows, object){
-			// summary:
-			//		Generates the grid for each row (used by renderHeader and and renderRow)
-			var row = put("table.dgrid-row-table[role=presentation]"),
-				cellNavigation = this.cellNavigation,
-				// IE < 9 needs an explicit tbody; other browsers do not
-				tbody = (has("ie") < 9 || has("quirks")) ? put(row, "tbody") : row,
-				tr,
-				si, sl, i, l, // iterators
-				subRow, column, id, extraClasses, className,
-				cell, innerCell, colSpan, rowSpan; // used inside loops
-			
-			// Allow specification of custom/specific subRows, falling back to
-			// those defined on the instance.
-			subRows = subRows || this.subRows;
-			
-			for(si = 0, sl = subRows.length; si < sl; si++){
-				subRow = subRows[si];
-				// for single-subrow cases in modern browsers, TR can be skipped
-				// http://jsperf.com/table-without-trs
-				tr = put(tbody, "tr");
-				if(subRow.className){
-					put(tr, "." + subRow.className);
-				}
-
-				for(i = 0, l = subRow.length; i < l; i++){
-					// iterate through the columns
-					column = subRow[i];
-					id = column.id;
-
-					extraClasses = column.field ? ".field-" + column.field : "";
-					className = typeof column.className === "function" ?
-						column.className(object) : column.className;
-					if(className){
-						extraClasses += "." + className;
-					}
-
-					cell = put(tag + (
-							".dgrid-cell.dgrid-cell-padding" +
-							(id ? ".dgrid-column-" + id : "") +
-							extraClasses.replace(/ +/g, ".")
-						).replace(invalidClassChars,"-") +
-						"[role=" + (tag === "th" ? "columnheader" : "gridcell") + "]");
-					cell.columnId = id;
-					if(contentBoxSizing){
-						// The browser (IE7-) does not support box-sizing: border-box, so we emulate it with a padding div
-						innerCell = put(cell, "!dgrid-cell-padding div.dgrid-cell-padding");// remove the dgrid-cell-padding, and create a child with that class
-						cell.contents = innerCell;
-					}else{
-						innerCell = cell;
-					}
-					colSpan = column.colSpan;
-					if(colSpan){
-						cell.colSpan = colSpan;
-					}
-					rowSpan = column.rowSpan;
-					if(rowSpan){
-						cell.rowSpan = rowSpan;
-					}
-					each(innerCell, column);
-					// add the td to the tr at the end for better performance
-					tr.appendChild(cell);
-				}
-			}
-			return row;
-		},
-		
-		left: function(cell, steps){
-			if(!cell.element){ cell = this.cell(cell); }
-			return this.cell(this._move(cell, -(steps || 1), "dgrid-cell"));
-		},
-		right: function(cell, steps){
-			if(!cell.element){ cell = this.cell(cell); }
-			return this.cell(this._move(cell, steps || 1, "dgrid-cell"));
-		},
-		
-		renderRow: function(object, options){
-			var self = this;
-			var row = this.createRowCells("td", function(td, column){
-				var data = object;
-				// Support get function or field property (similar to DataGrid)
-				if(column.get){
-					data = column.get(object);
-				}else if("field" in column && column.field != "_item"){
-					data = data[column.field];
-				}
-				
-				if(column.renderCell){
-					// A column can provide a renderCell method to do its own DOM manipulation,
-					// event handling, etc.
-					appendIfNode(td, column.renderCell(object, data, td, options));
-				}else{
-					defaultRenderCell.call(column, object, data, td, options);
-				}
-			}, options && options.subRows, object);
-			// row gets a wrapper div for a couple reasons:
-			//	1. So that one can set a fixed height on rows (heights can't be set on <table>'s AFAICT)
-			// 2. So that outline style can be set on a row when it is focused, and Safari's outline style is broken on <table>
-			return put("div[role=row]>", row);
-		},
-		renderHeader: function(){
-			// summary:
-			//		Setup the headers for the grid
-			var
-				grid = this,
-				columns = this.columns,
-				headerNode = this.headerNode,
-				i = headerNode.childNodes.length;
-			
-			headerNode.setAttribute("role", "row");
-			
-			// clear out existing header in case we're resetting
-			while(i--){
-				put(headerNode.childNodes[i], "!");
-			}
-			
-			var row = this.createRowCells("th", function(th, column){
-				var contentNode = column.headerNode = th;
-				if(contentBoxSizing){
-					// we're interested in the th, but we're passed the inner div
-					th = th.parentNode;
-				}
-				var field = column.field;
-				if(field){
-					th.field = field;
-				}
-				// allow for custom header content manipulation
-				if(column.renderHeaderCell){
-					appendIfNode(contentNode, column.renderHeaderCell(contentNode));
-				}else if("label" in column || column.field){
-					contentNode.appendChild(document.createTextNode(
-						"label" in column ? column.label : column.field));
-				}
-				if(column.sortable !== false && field && field != "_item"){
-					th.sortable = true;
-					th.className += " dgrid-sortable";
-				}
-			}, this.subRows && this.subRows.headerRows);
-			this._rowIdToObject[row.id = this.id + "-header"] = this.columns;
-			headerNode.appendChild(row);
-			
-			// If the columns are sortable, re-sort on clicks.
-			// Use a separate listener property to be managed by renderHeader in case
-			// of subsequent calls.
-			if(this._sortListener){
-				this._sortListener.remove();
-			}
-			this._sortListener = listen(row, "click,keydown", function(event){
-				// respond to click, space keypress, or enter keypress
-				if(event.type == "click" || event.keyCode == 32 /* space bar */ || (!has("opera") && event.keyCode == 13) /* enter */){
-					var target = event.target,
-						field, sort, newSort, eventObj;
-					do{
-						if(target.sortable){
-							// If the click is on the same column as the active sort,
-							// reverse sort direction
-							newSort = [{
-								attribute: (field = target.field || target.columnId),
-								descending: (sort = grid._sort[0]) && sort.attribute == field &&
-									!sort.descending
-							}];
-							
-							// Emit an event with the new sort
-							eventObj = {
-								bubbles: true,
-								cancelable: true,
-								grid: grid,
-								parentType: event.type,
-								sort: newSort
-							};
-							
-							if (listen.emit(event.target, "dgrid-sort", eventObj)){
-								// Stash node subject to DOM manipulations,
-								// to be referenced then removed by sort()
-								grid._sortNode = target;
-								grid.set("sort", newSort);
-							}
-							
-							break;
-						}
-					}while((target = target.parentNode) && target != headerNode);
-				}
-			});
-		},
-		
-		resize: function(){
-			// extension of List.resize to allow accounting for
-			// column sizes larger than actual grid area
-			var
-				headerTableNode = this.headerNode.firstChild,
-				contentNode = this.contentNode,
-				width;
-			
-			this.inherited(arguments);
-			
-			if(!has("ie") || (has("ie") > 7 && !has("quirks"))){
-				// Force contentNode width to match up with header width.
-				// (Old IEs don't have a problem due to how they layout.)
-				
-				contentNode.style.width = ""; // reset first
-				
-				if(contentNode && headerTableNode){
-					if((width = headerTableNode.offsetWidth) != contentNode.offsetWidth){
-						// update size of content node if necessary (to match size of rows)
-						// (if headerTableNode can't be found, there isn't much we can do)
-						contentNode.style.width = width + "px";
-					}
-				}
-			}
-		},
-		
-		destroy: function(){
-			// Run _destroyColumns first to perform any column plugin tear-down logic.
-			this._destroyColumns();
-			if(this._sortListener){
-				this._sortListener.remove();
-			}
-			
-			this.inherited(arguments);
-		},
-		
-		_setSort: function(property, descending){
-			// summary:
-			//		Extension of List.js sort to update sort arrow in UI
-			
-			// Normalize _sort first via inherited logic, then update the sort arrow
-			this.inherited(arguments);
-			this.updateSortArrow(this._sort);
-		},
-		
-		updateSortArrow: function(sort, updateSort){
-			// summary:
-			//		Method responsible for updating the placement of the arrow in the
-			//		appropriate header cell.  Typically this should not be called (call
-			//		set("sort", ...) when actually updating sort programmatically), but
-			//		this method may be used by code which is customizing sort (e.g.
-			//		by reacting to the dgrid-sort event, canceling it, then
-			//		performing logic and calling this manually).
-			// sort: Array
-			//		Standard sort parameter - array of object(s) containing attribute
-			//		and optionally descending property
-			// updateSort: Boolean?
-			//		If true, will update this._sort based on the passed sort array
-			//		(i.e. to keep it in sync when custom logic is otherwise preventing
-			//		it from being updated); defaults to false
-			
-			// Clean up UI from any previous sort
-			if(this._lastSortedArrow){
-				// Remove the sort classes from the parent node
-				put(this._lastSortedArrow, "<!dgrid-sort-up!dgrid-sort-down");
-				// Destroy the lastSortedArrow node
-				put(this._lastSortedArrow, "!");
-				delete this._lastSortedArrow;
-			}
-			
-			if(updateSort){ this._sort = sort; }
-			if(!sort[0]){ return; } // nothing to do if no sort is specified
-			
-			var prop = sort[0].attribute,
-				desc = sort[0].descending,
-				target = this._sortNode, // stashed if invoked from header click
-				columns, column, i;
-			
-			delete this._sortNode;
-			
-			if(!target){
-				columns = this.columns;
-				for(i in columns){
-					column = columns[i];
-					if(column.field == prop){
-						target = column.headerNode;
-						break;
-					}
-				}
-			}
-			// skip this logic if field being sorted isn't actually displayed
-			if(target){
-				target = target.contents || target;
-				// place sort arrow under clicked node, and add up/down sort class
-				this._lastSortedArrow = put(target.firstChild, "-div.dgrid-sort-arrow.ui-icon[role=presentation]");
-				this._lastSortedArrow.innerHTML = "&nbsp;";
-				put(target, desc ? ".dgrid-sort-down" : ".dgrid-sort-up");
-				// call resize in case relocation of sort arrow caused any height changes
-				this.resize();
-			}
-		},
-		
-		styleColumn: function(colId, css){
-			// summary:
-			//		Dynamically creates a stylesheet rule to alter a column's style.
-			
-			return this.addCssRule("#" + miscUtil.escapeCssIdentifier(this.domNode.id) +
-				" .dgrid-column-" + colId, css);
-		},
-		
-		/*=====
-		_configColumn: function(column, columnId, rowColumns, prefix){
-			// summary:
-			//		Method called when normalizing base configuration of a single
-			//		column.  Can be used as an extension point for behavior requiring
-			//		access to columns when a new configuration is applied.
-		},=====*/
-		
-		_configColumns: function(prefix, rowColumns){
-			// configure the current column
-			var subRow = [],
-				isArray = rowColumns instanceof Array;
-			
-			function configColumn(column, columnId){
-				if(typeof column == "string"){
-					rowColumns[columnId] = column = {label:column};
-				}
-				if(!isArray && !column.field){
-					column.field = columnId;
-				}
-				columnId = column.id = column.id || (isNaN(columnId) ? columnId : (prefix + columnId));
-				if(isArray){ this.columns[columnId] = column; }
-				
-				// allow further base configuration in subclasses
-				if(this._configColumn){
-					this._configColumn(column, columnId, rowColumns, prefix);
-				}
-				
-				// add grid reference to each column object for potential use by plugins
-				column.grid = this;
-				if(typeof column.init === "function"){ column.init(); }
-				
-				subRow.push(column); // make sure it can be iterated on
-			}
-			
-			miscUtil.each(rowColumns, configColumn, this);
-			return isArray ? rowColumns : subRow;
-		},
-		
-		_destroyColumns: function(){
-			// summary:
-			//		Iterates existing subRows looking for any column definitions with
-			//		destroy methods (defined by plugins) and calls them.  This is called
-			//		immediately before configuring a new column structure.
-			
-			var subRows = this.subRows,
-				// if we have column sets, then we don't need to do anything with the missing subRows, ColumnSet will handle it
-				subRowsLength = subRows && subRows.length,
-				i, j, column, len;
-			
-			// First remove rows (since they'll be refreshed after we're done),
-			// so that anything aspected onto removeRow by plugins can run.
-			// (cleanup will end up running again, but with nothing to iterate.)
-			this.cleanup();
-			
-			for(i = 0; i < subRowsLength; i++){
-				for(j = 0, len = subRows[i].length; j < len; j++){
-					column = subRows[i][j];
-					if(typeof column.destroy === "function"){ column.destroy(); }
-				}
-			}
-		},
-		
-		configStructure: function(){
-			// configure the columns and subRows
-			var subRows = this.subRows,
-				columns = this._columns = this.columns;
-			
-			// Reset this.columns unless it was already passed in as an object
-			this.columns = !columns || columns instanceof Array ? {} : columns;
-			
-			if(subRows){
-				// Process subrows, which will in turn populate the this.columns object
-				for(var i = 0; i < subRows.length; i++){
-					subRows[i] = this._configColumns(i + "-", subRows[i]);
-				}
-			}else{
-				this.subRows = [this._configColumns("", columns)];
-			}
-		},
-		
-		_getColumns: function(){
-			// _columns preserves what was passed to set("columns"), but if subRows
-			// was set instead, columns contains the "object-ified" version, which
-			// was always accessible in the past, so maintain that accessibility going
-			// forward.
-			return this._columns || this.columns;
-		},
-		_setColumns: function(columns){
-			this._destroyColumns();
-			// reset instance variables
-			this.subRows = null;
-			this.columns = columns;
-			// re-run logic
-			this._updateColumns();
-		},
-		
-		_setSubRows: function(subrows){
-			this._destroyColumns();
-			this.subRows = subrows;
-			this._updateColumns();
-		},
-		
-		setColumns: function(columns){
-			kernel.deprecated("setColumns(...)", 'use set("columns", ...) instead', "dgrid 0.4");
-			this.set("columns", columns);
-		},
-		setSubRows: function(subrows){
-			kernel.deprecated("setSubRows(...)", 'use set("subRows", ...) instead', "dgrid 0.4");
-			this.set("subRows", subrows);
-		},
-		
-		_updateColumns: function(){
-			// summary:
-			//		Called when columns, subRows, or columnSets are reset
-			
-			this.configStructure();
-			this.renderHeader();
-			
-			this.refresh();
-			// re-render last collection if present
-			this._lastCollection && this.renderArray(this._lastCollection);
-			
-			// After re-rendering the header, re-apply the sort arrow if needed.
-			if(this._started){
-				if(this._sort && this._sort.length){
-					this.updateSortArrow(this._sort);
-				} else {
-					// Only call resize directly if we didn't call updateSortArrow,
-					// since that calls resize itself when it updates.
-					this.resize();
-				}
-			}
-		}
-	});
-	
-	function defaultRenderCell(object, data, td, options){
-		if(this.formatter){
-			// Support formatter, with or without formatterScope
-			var formatter = this.formatter,
-				formatterScope = this.grid.formatterScope;
-			td.innerHTML = typeof formatter === "string" && formatterScope ?
-				formatterScope[formatter](data, object) : this.formatter(data, object);
-		}else if(data != null){
-			td.appendChild(document.createTextNode(data)); 
-		}
-	}
-	
-	// expose appendIfNode and default implementation of renderCell,
-	// e.g. for use by column plugins
-	Grid.appendIfNode = appendIfNode;
-	Grid.defaultRenderCell = defaultRenderCell;
-	
-	return Grid;
-});

+ 0 - 127
esp/files/dgrid/GridFromHtml.js

@@ -1,127 +0,0 @@
-define(["./Grid", "dojo/_base/declare", "put-selector/put"],
-function(Grid, declare, put){
-	// summary:
-	//		This module supports parsing grid structure information from an HTML table.
-	//		This module does NOT support ColumnSets; see GridWithColumnSetsFromHtml
-	
-	// name of data attribute to check for column properties
-	var bagName = "data-dgrid-column";
-	
-	function getSubRowsFromDom(domNode){
-		// summary:
-		//		generate columns from DOM. Should this be in here, or a separate module?
-		var
-			columns = [], // to be pushed upon / returned
-			trs = domNode.getElementsByTagName("tr"),
-			trslen = trs.length,
-			getCol = GridFromHtml.utils.getColumnFromCell,
-			rowColumns, tr, ths, thslen;
-		
-		for(var i = 0; i < trslen; i++){
-			rowColumns = [];
-			columns.push(rowColumns);
-			tr = trs[i];
-			ths = tr.getElementsByTagName("th"), thslen = ths.length;
-			for(var j = 0; j < thslen; j++){
-				rowColumns.push(getCol(ths[j]));
-			}
-		}
-		if(tr){
-			// NOTE: this assumes that applicable TRs were ONLY found under one
-			// grouping element (e.g. thead)
-			domNode.removeChild(tr.parentNode);
-		}
-		
-		return columns;
-	}
-	
-	var GridFromHtml = declare(Grid, {
-		configStructure: function(){
-			// summary:
-			//		Configure subRows based on HTML originally in srcNodeRef
-			if(!this._checkedTrs){
-				this._checkedTrs = true;
-				this.subRows = getSubRowsFromDom(this.srcNodeRef, this.subRows);
-			}
-			return this.inherited(arguments);
-		},
-		
-		create: function(params, srcNodeRef){
-			// We need to replace srcNodeRef, presumably a table, with a div.
-			// (Otherwise we'll generate highly invalid markup, which IE doesn't like)
-			var
-				div = document.createElement("div"),
-				id = srcNodeRef.id,
-				style = srcNodeRef.getAttribute("style");
-			
-			// Copy some commonly-used attributes...
-			if(id){ this.id = id; } // will be propagated in List's create
-			div.className = srcNodeRef.className;
-			style && div.setAttribute("style", style);
-			
-			// replace srcNodeRef in DOM with the div
-			srcNodeRef.parentNode.replaceChild(div, srcNodeRef);
-			
-			(params = params || {}).srcNodeRef = srcNodeRef;
-			// call inherited with the new node
-			// (but configStructure will look at srcNodeRef)
-			this.inherited(arguments, [params, div]);
-			
-			// destroy srcNodeRef for good now that we're done with it
-			put(srcNodeRef, "!");
-		}
-	});
-	
-	// hang some utility functions, potentially useful for extensions
-	GridFromHtml.utils = {
-		// Functions for getting various types of values from HTML attributes
-		getBoolFromAttr: function(node, attr){
-			// used for e.g. sortable
-			var val = node.getAttribute(attr);
-			return val && val !== "false";
-		},
-		getNumFromAttr: function(node, attr){
-			// used for e.g. rowSpan, colSpan
-			var val = node.getAttribute(attr);
-			val = val && Number(val);
-			return isNaN(val) ? undefined : val;
-		},
-		getPropsFromNode: function(node){
-			// used to pull properties out of bag e.g. "data-dgrid-column".
-			var obj, str = node.getAttribute(bagName);
-			if(!str){ return {}; } // no props bag specified!
-			
-			// Yes, eval is evil, but this is ultimately the same thing that
-			// dojo.parser does for objects.
-			try{
-				obj = eval("(" + str + ")");
-			}catch(e){
-				throw new Error("Error in " + bagName + " {" + str + "}: " + e.toString());
-			}
-			return obj;
-		},
-		
-		// Function for aggregating th attributes into column properties
-		getColumnFromCell: function(th){
-			var
-				getNum = GridFromHtml.utils.getNumFromAttr,
-				obj, tmp;
-			
-			// Look for properties in data attribute.
-			// It's imperative that we hold on to this object as returned, as the
-			// object may be augmented further by other sources,
-			// e.g. Grid adding the grid property to reference the instance.
-			obj = GridFromHtml.utils.getPropsFromNode(th);
-			
-			// inspect standard attributes, but data attribute takes precedence
-			obj.label = "label" in obj ? obj.label : th.innerHTML;
-			obj.field = obj.field || th.className || th.innerHTML;
-			if(!obj.className && th.className){ obj.className = th.className; }
-			if(!obj.rowSpan && (tmp = getNum(th, "rowspan"))){ obj.rowSpan = tmp; }
-			if(!obj.colSpan && (tmp = getNum(th, "colspan"))){ obj.colSpan = tmp; }
-			
-			return obj;
-		}
-	};
-	return GridFromHtml;
-});

+ 0 - 116
esp/files/dgrid/GridWithColumnSetsFromHtml.js

@@ -1,116 +0,0 @@
-define(["./GridFromHtml", "./ColumnSet", "dojo/_base/declare"],
-function(GridFromHtml, ColumnSet, declare){
-	// summary:
-	//		This module augments GridFromHtml with additional support for interpreting
-	//		ColumnSets from colgroups in table markup.
-	
-	function getColumnSetsFromDom(domNode){
-		// summary:
-		//		Generates ColumnSets from DOM.
-		
-		var
-			columnsets = [], // to be pushed upon / returned
-			cgspans = [], // stores info on columnset sizes (colgroup span)
-			rowspans = [], // will store info on any "unexhausted" rowspans
-			colgroups = domNode.getElementsByTagName("colgroup"),
-			cglen = colgroups.length,
-			trs = domNode.getElementsByTagName("tr"),
-			trslen = trs.length,
-			getNum = GridFromHtml.utils.getNumFromAttr,
-			getCol = GridFromHtml.utils.getColumnFromCell,
-			// used in loops:
-			currcol, // keeps track of what column we're at
-			currcg, // and which colgroup
-			groupColumns, tr, ths, i, j, tmp;
-		
-		function incCurrcol(amount){
-			// Check whether we've passed into the next colgroup within current row.
-			// (Used within th loop)
-			currcol += amount;
-			tmp = cgspans[currcg];
-			if(currcol >= tmp){
-				// First, push info for the set we just finished:
-				// (i is still the active row index from the for loop)
-				columnsets[currcg][i] = groupColumns;
-				
-				// Now, time to move on to the next columnset for this row.
-				currcol -= tmp;
-				currcg++;
-				groupColumns = [];
-			}
-		}
-		
-		// no need for ColumnSet unless there's >1 colgroup
-		if(cglen < 2){ return false; }
-		
-		// read span from each colgroup (defaults to 1)
-		for(i = 0; i < cglen; i++){
-			// store number of cells this column spans
-			tmp = getNum(colgroups[i], "span") || 1;
-			cgspans[i] = tmp;
-			// add nested array to return value to be populated for this set
-			columnsets[i] = [];
-			// initialize inner rowspan-tracking array for each
-			rowspans[i] = [];
-			for(j = 0; j < tmp; j++){
-				rowspans[i][j] = 0;
-			}
-		}
-		
-		for(i = 0; i < trslen; i++){
-			currcol = currcg = 0;
-			groupColumns = [];
-			tr = trs[i];
-			ths = tr.getElementsByTagName("th"), thslen = ths.length;
-			for(j = 0; j < thslen; j++){
-				// account for space occupied by previous rowSpans
-				while(rowspans[currcg][currcol]){
-					// decrement rowspan "leftover" for next iteration
-					rowspans[currcg][currcol]--;
-					// skip past this cell for now, and try again w/ updated currcg/col
-					incCurrcol(1);
-				}
-				
-				// store cell info
-				tmp = getCol(ths[j]);
-				groupColumns.push(tmp);
-				
-				// if this cell has rowspan, keep that in mind for future iterations
-				rowspans[currcg][currcol] = tmp.rowSpan ? tmp.rowSpan - 1 : 0;
-				
-				// increment currcol/currcg appropriately, accounting for cell colSpan
-				incCurrcol(tmp.colSpan || 1);
-			}
-			// At the end of processing each row, there is a chance that the last
-			// column set didn't get pushed yet (specifically if there are trailing
-			// rowspans - since rowspan "debt" gets iterated at the beginning of each
-			// iteration, not the end).  In that case, push the last one now.
-			if(groupColumns.length){
-				columnsets[currcg][i] = groupColumns;
-			}
-		}
-		if(tr){
-			domNode.removeChild(tr.parentNode);
-		}
-		return columnsets;
-	}
-	return declare([GridFromHtml, ColumnSet], {
-		configStructure: function(){
-			// summary:
-			//		Configure subRows based on HTML originally in srcNodeRef
-			
-			var tmp;
-			if(!this._checkedTrs){
-				tmp = getColumnSetsFromDom(this.srcNodeRef);
-				if(tmp){
-					this.columnSets = tmp;
-					this._checkedTrs = true;
-				}else{
-					// no reason to worry about ColumnSets, let GridFromHtml do the job
-					return this.inherited(arguments);
-				}
-			}
-			return this.inherited(arguments);
-		}
-	});
-});

+ 0 - 514
esp/files/dgrid/Keyboard.js

@@ -1,514 +0,0 @@
-define([
-	"dojo/_base/declare",
-	"dojo/aspect",
-	"dojo/on",
-	"dojo/_base/lang",
-	"dojo/has",
-	"put-selector/put",
-	"dojo/_base/Deferred",
-	"dojo/_base/sniff"
-], function(declare, aspect, on, lang, has, put, Deferred){
-
-var delegatingInputTypes = {
-		checkbox: 1,
-		radio: 1,
-		button: 1
-	},
-	hasGridCellClass = /\bdgrid-cell\b/,
-	hasGridRowClass = /\bdgrid-row\b/;
-
-has.add("dom-contains", function(global, doc, element){
-	return !!element.contains; // not supported by FF < 9
-});
-
-function contains(parent, node){
-	// summary:
-	//		Checks to see if an element is contained by another element.
-	
-	if(has("dom-contains")){
-		return parent.contains(node);
-	}else{
-		return parent.compareDocumentPosition(node) & 8 /* DOCUMENT_POSITION_CONTAINS */;
-	}
-}
-
-var Keyboard = declare(null, {
-	// summary:
-	//		Adds keyboard navigation capability to a list or grid.
-	
-	// pageSkip: Number
-	//		Number of rows to jump by when page up or page down is pressed.
-	pageSkip: 10,
-	
-	tabIndex: 0,
-	
-	// keyMap: Object
-	//		Hash which maps key codes to functions to be executed (in the context
-	//		of the instance) for key events within the grid's body.
-	keyMap: null,
-	
-	// headerKeyMap: Object
-	//		Hash which maps key codes to functions to be executed (in the context
-	//		of the instance) for key events within the grid's header row.
-	headerKeyMap: null,
-	
-	postMixInProperties: function(){
-		this.inherited(arguments);
-		
-		if(!this.keyMap){
-			this.keyMap = lang.mixin({}, Keyboard.defaultKeyMap);
-		}
-		if(!this.headerKeyMap){
-			this.headerKeyMap = lang.mixin({}, Keyboard.defaultHeaderKeyMap);
-		}
-	},
-	
-	postCreate: function(){
-		this.inherited(arguments);
-		var grid = this;
-		
-		function handledEvent(event){
-			// text boxes and other inputs that can use direction keys should be ignored and not affect cell/row navigation
-			var target = event.target;
-			return target.type && (!delegatingInputTypes[target.type] || event.keyCode == 32);
-		}
-		
-		function enableNavigation(areaNode){
-			var cellNavigation = grid.cellNavigation,
-				isFocusableClass = cellNavigation ? hasGridCellClass : hasGridRowClass,
-				isHeader = areaNode === grid.headerNode,
-				initialNode = areaNode;
-			
-			function initHeader(){
-				if(grid._focusedHeaderNode){
-					// Remove the tab index for the node that previously had it.
-					grid._focusedHeaderNode.tabIndex = -1;
-				}
-				if(grid.showHeader){
-					// Set the tab index only if the header is visible.
-					grid._focusedHeaderNode = initialNode =
-						cellNavigation ? grid.headerNode.getElementsByTagName("th")[0] : grid.headerNode;
-					if(initialNode){ initialNode.tabIndex = grid.tabIndex; }
-				}
-			}
-			
-			if(isHeader){
-				// Initialize header now (since it's already been rendered),
-				// and aspect after future renderHeader calls to reset focus.
-				initHeader();
-				aspect.after(grid, "renderHeader", initHeader, true);
-			}else{
-				aspect.after(grid, "renderArray", function(ret){
-					// summary:
-					//		Ensures the first element of a grid is always keyboard selectable after data has been
-					//		retrieved if there is not already a valid focused element.
-					
-					return Deferred.when(ret, function(ret){
-						var focusedNode = grid._focusedNode || initialNode;
-						
-						// do not update the focused element if we already have a valid one
-						if(isFocusableClass.test(focusedNode.className) && contains(areaNode, focusedNode)){
-							return ret;
-						}
-						
-						// ensure that the focused element is actually a grid cell, not a
-						// dgrid-preload or dgrid-content element, which should not be focusable,
-						// even when data is loaded asynchronously
-						for(var i = 0, elements = areaNode.getElementsByTagName("*"), element; (element = elements[i]); ++i){
-							if(isFocusableClass.test(element.className)){
-								focusedNode = grid._focusedNode = element;
-								break;
-							}
-						}
-						
-						focusedNode.tabIndex = grid.tabIndex;
-						return ret;
-					});
-				});
-			}
-			
-			grid._listeners.push(on(areaNode, "mousedown", function(event){
-				if(!handledEvent(event)){
-					grid._focusOnNode(event.target, isHeader, event);
-				}
-			}));
-			
-			grid._listeners.push(on(areaNode, "keydown", function(event){
-				// For now, don't squash browser-specific functionalities by letting
-				// ALT and META function as they would natively
-				if(event.metaKey || event.altKey) {
-					return;
-				}
-				
-				var handler = grid[isHeader ? "headerKeyMap" : "keyMap"][event.keyCode];
-				
-				// Text boxes and other inputs that can use direction keys should be ignored and not affect cell/row navigation
-				if(handler && !handledEvent(event)){
-					handler.call(grid, event);
-				}
-			}));
-		}
-		
-		if(this.tabableHeader){
-			enableNavigation(this.headerNode);
-			on(this.headerNode, "dgrid-cellfocusin", function(){
-				grid.scrollTo({ x: this.scrollLeft });
-			});
-		}
-		enableNavigation(this.contentNode);
-	},
-	
-	removeRow: function(rowElement){
-		if(!this._focusedNode){
-			// Nothing special to do if we have no record of anything focused
-			return this.inherited(arguments);
-		}
-		
-		var self = this,
-			isActive = document.activeElement === this._focusedNode,
-			focusedTarget = this[this.cellNavigation ? "cell" : "row"](this._focusedNode),
-			focusedRow = focusedTarget.row || focusedTarget,
-			sibling;
-		rowElement = rowElement.element || rowElement;
-		
-		// If removed row previously had focus, temporarily store information
-		// to be handled in an immediately-following insertRow call, or next turn
-		if(rowElement === focusedRow.element){
-			sibling = this.down(focusedRow, true);
-			
-			// Check whether down call returned the same row, or failed to return
-			// any (e.g. during a partial unrendering)
-			if (!sibling || sibling.element === rowElement) {
-				sibling = this.up(focusedRow, true);
-			}
-			
-			this._removedFocus = {
-				active: isActive,
-				rowId: focusedRow.id,
-				columnId: focusedTarget.column && focusedTarget.column.id,
-				siblingId: !sibling || sibling.element === rowElement ? undefined : sibling.id
-			};
-			
-			// Call _restoreFocus on next turn, to restore focus to sibling
-			// if no replacement row was immediately inserted.
-			// Pass original row's id in case it was re-inserted in a renderArray
-			// call (and thus was found, but couldn't be focused immediately)
-			setTimeout(function() {
-				if(self._removedFocus){
-					self._restoreFocus(focusedRow.id);
-				}
-			}, 0);
-			
-			// Clear _focusedNode until _restoreFocus is called, to avoid
-			// needlessly re-running this logic
-			this._focusedNode = null;
-		}
-		
-		this.inherited(arguments);
-	},
-	
-	insertRow: function(object){
-		var rowElement = this.inherited(arguments);
-		if(this._removedFocus && !this._removedFocus.wait){
-			this._restoreFocus(rowElement);
-		}
-		return rowElement;
-	},
-	
-	_restoreFocus: function(row) {
-		// summary:
-		//		Restores focus to the newly inserted row if it matches the
-		//		previously removed row, or to the nearest sibling otherwise.
-		
-		var focusInfo = this._removedFocus,
-			newTarget;
-		
-		row = row && this.row(row);
-		newTarget = row && row.element && row.id === focusInfo.rowId ? row :
-			typeof focusInfo.siblingId !== "undefined" && this.row(focusInfo.siblingId);
-		
-		if(newTarget && newTarget.element){
-			if(!newTarget.element.parentNode.parentNode){
-				// This was called from renderArray, so the row hasn't
-				// actually been placed in the DOM yet; handle it on the next
-				// turn (called from removeRow).
-				focusInfo.wait = true;
-				return;
-			}
-			newTarget = typeof focusInfo.columnId !== "undefined" ?
-				this.cell(newTarget, focusInfo.columnId) : newTarget;
-			if(focusInfo.active){
-				// Row/cell was previously focused, so focus the new one immediately
-				this.focus(newTarget);
-			}else{
-				// Row/cell was not focused, but we still need to update tabIndex
-				// and the element's class to be consistent with the old one
-				put(newTarget.element, ".dgrid-focus");
-				newTarget.element.tabIndex = this.tabIndex;
-			}
-		}
-		
-		delete this._removedFocus;
-	},
-	
-	addKeyHandler: function(key, callback, isHeader){
-		// summary:
-		//		Adds a handler to the keyMap on the instance.
-		//		Supports binding additional handlers to already-mapped keys.
-		// key: Number
-		//		Key code representing the key to be handled.
-		// callback: Function
-		//		Callback to be executed (in instance context) when the key is pressed.
-		// isHeader: Boolean
-		//		Whether the handler is to be added for the grid body (false, default)
-		//		or the header (true).
-		
-		// Aspects may be about 10% slower than using an array-based appraoch,
-		// but there is significantly less code involved (here and above).
-		return aspect.after( // Handle
-			this[isHeader ? "headerKeyMap" : "keyMap"], key, callback, true);
-	},
-	
-	_focusOnNode: function(element, isHeader, event){
-		var focusedNodeProperty = "_focused" + (isHeader ? "Header" : "") + "Node",
-			focusedNode = this[focusedNodeProperty],
-			cellOrRowType = this.cellNavigation ? "cell" : "row",
-			cell = this[cellOrRowType](element),
-			inputs,
-			input,
-			numInputs,
-			inputFocused,
-			i;
-		
-		element = cell && cell.element;
-		if(!element){ return; }
-		
-		if(this.cellNavigation){
-			inputs = element.getElementsByTagName("input");
-			for(i = 0, numInputs = inputs.length; i < numInputs; i++){
-				input = inputs[i];
-				if((input.tabIndex != -1 || "lastValue" in input) && !input.disabled){
-					// Employ workaround for focus rectangle in IE < 8
-					if(has("ie") < 8){ input.style.position = "relative"; }
-					input.focus();
-					if(has("ie") < 8){ input.style.position = ""; }
-					inputFocused = true;
-					break;
-				}
-			}
-		}
-		
-		event = lang.mixin({ grid: this }, event);
-		if(event.type){
-			event.parentType = event.type;
-		}
-		if(!event.bubbles){
-			// IE doesn't always have a bubbles property already true.
-			// Opera throws if you try to set it to true if it is already true.
-			event.bubbles = true;
-		}
-		if(focusedNode){
-			// Clean up previously-focused element
-			// Remove the class name and the tabIndex attribute
-			put(focusedNode, "!dgrid-focus[!tabIndex]");
-			if(has("ie") < 8){
-				// Clean up after workaround below (for non-input cases)
-				focusedNode.style.position = "";
-			}
-			
-			// Expose object representing focused cell or row losing focus, via
-			// event.cell or event.row; which is set depends on cellNavigation.
-			event[cellOrRowType] = this[cellOrRowType](focusedNode);
-			on.emit(element, "dgrid-cellfocusout", event);
-		}
-		focusedNode = this[focusedNodeProperty] = element;
-		
-		// Expose object representing focused cell or row gaining focus, via
-		// event.cell or event.row; which is set depends on cellNavigation.
-		// Note that yes, the same event object is being reused; on.emit
-		// performs a shallow copy of properties into a new event object.
-		event[cellOrRowType] = cell;
-		
-		if(!inputFocused){
-			if(has("ie") < 8){
-				// setting the position to relative magically makes the outline
-				// work properly for focusing later on with old IE.
-				// (can't be done a priori with CSS or screws up the entire table)
-				element.style.position = "relative";
-			}
-			element.tabIndex = this.tabIndex;
-			element.focus();
-		}
-		put(element, ".dgrid-focus");
-		on.emit(focusedNode, "dgrid-cellfocusin", event);
-	},
-	
-	focusHeader: function(element){
-		this._focusOnNode(element || this._focusedHeaderNode, true);
-	},
-	
-	focus: function(element){
-		this._focusOnNode(element || this._focusedNode, false);
-	}
-});
-
-// Common functions used in default keyMap (called in instance context)
-
-var moveFocusVertical = Keyboard.moveFocusVertical = function(event, steps){
-	var cellNavigation = this.cellNavigation,
-		target = this[cellNavigation ? "cell" : "row"](event),
-		columnId = cellNavigation && target.column.id,
-		next = this.down(this._focusedNode, steps, true);
-	
-	// Navigate within same column if cell navigation is enabled
-	if(cellNavigation){ next = this.cell(next, columnId); }
-	this._focusOnNode(next, false, event);
-	
-	event.preventDefault();
-};
-
-var moveFocusUp = Keyboard.moveFocusUp = function(event){
-	moveFocusVertical.call(this, event, -1);
-};
-
-var moveFocusDown = Keyboard.moveFocusDown = function(event){
-	moveFocusVertical.call(this, event, 1);
-};
-
-var moveFocusPageUp = Keyboard.moveFocusPageUp = function(event){
-	moveFocusVertical.call(this, event, -this.pageSkip);
-};
-
-var moveFocusPageDown = Keyboard.moveFocusPageDown = function(event){
-	moveFocusVertical.call(this, event, this.pageSkip);
-};
-
-var moveFocusHorizontal = Keyboard.moveFocusHorizontal = function(event, steps){
-	if(!this.cellNavigation){ return; }
-	var isHeader = !this.row(event), // header reports row as undefined
-		currentNode = this["_focused" + (isHeader ? "Header" : "") + "Node"];
-	
-	this._focusOnNode(this.right(currentNode, steps), isHeader, event);
-	event.preventDefault();
-};
-
-var moveFocusLeft = Keyboard.moveFocusLeft = function(event){
-	moveFocusHorizontal.call(this, event, -1);
-};
-
-var moveFocusRight = Keyboard.moveFocusRight = function(event){
-	moveFocusHorizontal.call(this, event, 1);
-};
-
-var moveHeaderFocusEnd = Keyboard.moveHeaderFocusEnd = function(event, scrollToBeginning){
-	// Header case is always simple, since all rows/cells are present
-	var nodes;
-	if(this.cellNavigation){
-		nodes = this.headerNode.getElementsByTagName("th");
-		this._focusOnNode(nodes[scrollToBeginning ? 0 : nodes.length - 1], true, event);
-	}
-	// In row-navigation mode, there's nothing to do - only one row in header
-	
-	// Prevent browser from scrolling entire page
-	event.preventDefault();
-};
-
-var moveHeaderFocusHome = Keyboard.moveHeaderFocusHome = function(event){
-	moveHeaderFocusEnd.call(this, event, true);
-};
-
-var moveFocusEnd = Keyboard.moveFocusEnd = function(event, scrollToTop){
-	// summary:
-	//		Handles requests to scroll to the beginning or end of the grid.
-	
-	// Assume scrolling to top unless event is specifically for End key
-	var self = this,
-		cellNavigation = this.cellNavigation,
-		contentNode = this.contentNode,
-		contentPos = scrollToTop ? 0 : contentNode.scrollHeight,
-		scrollPos = contentNode.scrollTop + contentPos,
-		endChild = contentNode[scrollToTop ? "firstChild" : "lastChild"],
-		hasPreload = endChild.className.indexOf("dgrid-preload") > -1,
-		endTarget = hasPreload ? endChild[(scrollToTop ? "next" : "previous") + "Sibling"] : endChild,
-		endPos = endTarget.offsetTop + (scrollToTop ? 0 : endTarget.offsetHeight),
-		handle;
-	
-	if(hasPreload){
-		// Find the nearest dgrid-row to the relevant end of the grid
-		while(endTarget && endTarget.className.indexOf("dgrid-row") < 0){
-			endTarget = endTarget[(scrollToTop ? "next" : "previous") + "Sibling"];
-		}
-		// If none is found, there are no rows, and nothing to navigate
-		if(!endTarget){ return; }
-	}
-	
-	// Grid content may be lazy-loaded, so check if content needs to be
-	// loaded first
-	if(!hasPreload || endChild.offsetHeight < 1){
-		// End row is loaded; focus the first/last row/cell now
-		if(cellNavigation){
-			// Preserve column that was currently focused
-			endTarget = this.cell(endTarget, this.cell(event).column.id);
-		}
-		this._focusOnNode(endTarget, false, event);
-	}else{
-		// In IE < 9, the event member references will become invalid by the time
-		// _focusOnNode is called, so make a (shallow) copy up-front
-		if(!has("dom-addeventlistener")){
-			event = lang.mixin({}, event);
-		}
-		
-		// If the topmost/bottommost row rendered doesn't reach the top/bottom of
-		// the contentNode, we are using OnDemandList and need to wait for more
-		// data to render, then focus the first/last row in the new content.
-		handle = aspect.after(this, "renderArray", function(rows){
-			handle.remove();
-			return Deferred.when(rows, function(rows){
-				var target = rows[scrollToTop ? 0 : rows.length - 1];
-				if(cellNavigation){
-					// Preserve column that was currently focused
-					target = self.cell(target, self.cell(event).column.id);
-				}
-				self._focusOnNode(target, false, event);
-			});
-		});
-	}
-	
-	if(scrollPos === endPos){
-		// Grid body is already scrolled to end; prevent browser from scrolling
-		// entire page instead
-		event.preventDefault();
-	}
-};
-
-var moveFocusHome = Keyboard.moveFocusHome = function(event){
-	moveFocusEnd.call(this, event, true);
-};
-
-function preventDefault(event){
-	event.preventDefault();
-}
-
-Keyboard.defaultKeyMap = {
-	32: preventDefault, // space
-	33: moveFocusPageUp, // page up
-	34: moveFocusPageDown, // page down
-	35: moveFocusEnd, // end
-	36: moveFocusHome, // home
-	37: moveFocusLeft, // left
-	38: moveFocusUp, // up
-	39: moveFocusRight, // right
-	40: moveFocusDown // down
-};
-
-// Header needs fewer default bindings (no vertical), so bind it separately
-Keyboard.defaultHeaderKeyMap = {
-	32: preventDefault, // space
-	35: moveHeaderFocusEnd, // end
-	36: moveHeaderFocusHome, // home
-	37: moveFocusLeft, // left
-	39: moveFocusRight // right
-};
-
-return Keyboard;
-});

+ 0 - 190
esp/files/dgrid/LICENSE

@@ -1,190 +0,0 @@
-dgrid is available under *either* the terms of the modified BSD license *or* the
-Academic Free License version 2.1. As a recipient of dgrid, you may choose which
-license to receive this code under.
-
-The text of the AFL and BSD licenses is reproduced below. 
-
--------------------------------------------------------------------------------
-The "New" BSD License:
-**********************
-
-Copyright (c) 2010-2013, The Dojo Foundation
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-  * Redistributions of source code must retain the above copyright notice, this
-    list of conditions and the following disclaimer.
-  * Redistributions in binary form must reproduce the above copyright notice,
-    this list of conditions and the following disclaimer in the documentation
-    and/or other materials provided with the distribution.
-  * Neither the name of the Dojo Foundation nor the names of its contributors
-    may be used to endorse or promote products derived from this software
-    without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------------------
-The Academic Free License, v. 2.1:
-**********************************
-
-This Academic Free License (the "License") applies to any original work of
-authorship (the "Original Work") whose owner (the "Licensor") has placed the
-following notice immediately following the copyright notice for the Original
-Work:
-
-Licensed under the Academic Free License version 2.1
-
-1) Grant of Copyright License. Licensor hereby grants You a world-wide,
-royalty-free, non-exclusive, perpetual, sublicenseable license to do the
-following:
-
-a) to reproduce the Original Work in copies;
-
-b) to prepare derivative works ("Derivative Works") based upon the Original
-Work;
-
-c) to distribute copies of the Original Work and Derivative Works to the
-public;
-
-d) to perform the Original Work publicly; and
-
-e) to display the Original Work publicly.
-
-2) Grant of Patent License. Licensor hereby grants You a world-wide,
-royalty-free, non-exclusive, perpetual, sublicenseable license, under patent
-claims owned or controlled by the Licensor that are embodied in the Original
-Work as furnished by the Licensor, to make, use, sell and offer for sale the
-Original Work and Derivative Works.
-
-3) Grant of Source Code License. The term "Source Code" means the preferred
-form of the Original Work for making modifications to it and all available
-documentation describing how to modify the Original Work. Licensor hereby
-agrees to provide a machine-readable copy of the Source Code of the Original
-Work along with each copy of the Original Work that Licensor distributes.
-Licensor reserves the right to satisfy this obligation by placing a
-machine-readable copy of the Source Code in an information repository
-reasonably calculated to permit inexpensive and convenient access by You for as
-long as Licensor continues to distribute the Original Work, and by publishing
-the address of that information repository in a notice immediately following
-the copyright notice that applies to the Original Work.
-
-4) Exclusions From License Grant. Neither the names of Licensor, nor the names
-of any contributors to the Original Work, nor any of their trademarks or
-service marks, may be used to endorse or promote products derived from this
-Original Work without express prior written permission of the Licensor. Nothing
-in this License shall be deemed to grant any rights to trademarks, copyrights,
-patents, trade secrets or any other intellectual property of Licensor except as
-expressly stated herein. No patent license is granted to make, use, sell or
-offer to sell embodiments of any patent claims other than the licensed claims
-defined in Section 2. No right is granted to the trademarks of Licensor even if
-such marks are included in the Original Work. Nothing in this License shall be
-interpreted to prohibit Licensor from licensing under different terms from this
-License any Original Work that Licensor otherwise would have a right to
-license.
-
-5) This section intentionally omitted.
-
-6) Attribution Rights. You must retain, in the Source Code of any Derivative
-Works that You create, all copyright, patent or trademark notices from the
-Source Code of the Original Work, as well as any notices of licensing and any
-descriptive text identified therein as an "Attribution Notice." You must cause
-the Source Code for any Derivative Works that You create to carry a prominent
-Attribution Notice reasonably calculated to inform recipients that You have
-modified the Original Work.
-
-7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that
-the copyright in and to the Original Work and the patent rights granted herein
-by Licensor are owned by the Licensor or are sublicensed to You under the terms
-of this License with the permission of the contributor(s) of those copyrights
-and patent rights. Except as expressly stated in the immediately proceeding
-sentence, the Original Work is provided under this License on an "AS IS" BASIS
-and WITHOUT WARRANTY, either express or implied, including, without limitation,
-the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU.
-This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No
-license to Original Work is granted hereunder except under this disclaimer.
-
-8) Limitation of Liability. Under no circumstances and under no legal theory,
-whether in tort (including negligence), contract, or otherwise, shall the
-Licensor be liable to any person for any direct, indirect, special, incidental,
-or consequential damages of any character arising as a result of this License
-or the use of the Original Work including, without limitation, damages for loss
-of goodwill, work stoppage, computer failure or malfunction, or any and all
-other commercial damages or losses. This limitation of liability shall not
-apply to liability for death or personal injury resulting from Licensor's
-negligence to the extent applicable law prohibits such limitation. Some
-jurisdictions do not allow the exclusion or limitation of incidental or
-consequential damages, so this exclusion and limitation may not apply to You.
-
-9) Acceptance and Termination. If You distribute copies of the Original Work or
-a Derivative Work, You must make a reasonable effort under the circumstances to
-obtain the express assent of recipients to the terms of this License. Nothing
-else but this License (or another written agreement between Licensor and You)
-grants You permission to create Derivative Works based upon the Original Work
-or to exercise any of the rights granted in Section 1 herein, and any attempt
-to do so except under the terms of this License (or another written agreement
-between Licensor and You) is expressly prohibited by U.S. copyright law, the
-equivalent laws of other countries, and by international treaty. Therefore, by
-exercising any of the rights granted to You in Section 1 herein, You indicate
-Your acceptance of this License and all of its terms and conditions.
-
-10) Termination for Patent Action. This License shall terminate automatically
-and You may no longer exercise any of the rights granted to You by this License
-as of the date You commence an action, including a cross-claim or counterclaim,
-against Licensor or any licensee alleging that the Original Work infringes a
-patent. This termination provision shall not apply for an action alleging
-patent infringement by combinations of the Original Work with other software or
-hardware.
-
-11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this
-License may be brought only in the courts of a jurisdiction wherein the
-Licensor resides or in which Licensor conducts its primary business, and under
-the laws of that jurisdiction excluding its conflict-of-law provisions. The
-application of the United Nations Convention on Contracts for the International
-Sale of Goods is expressly excluded. Any use of the Original Work outside the
-scope of this License or after its termination shall be subject to the
-requirements and penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et
-seq., the equivalent laws of other countries, and international treaty. This
-section shall survive the termination of this License.
-
-12) Attorneys Fees. In any action to enforce the terms of this License or
-seeking damages relating thereto, the prevailing party shall be entitled to
-recover its costs and expenses, including, without limitation, reasonable
-attorneys' fees and costs incurred in connection with such action, including
-any appeal of such action. This section shall survive the termination of this
-License.
-
-13) Miscellaneous. This License represents the complete agreement concerning
-the subject matter hereof. If any provision of this License is held to be
-unenforceable, such provision shall be reformed only to the extent necessary to
-make it enforceable.
-
-14) Definition of "You" in This License. "You" throughout this License, whether
-in upper or lower case, means an individual or a legal entity exercising rights
-under, and complying with all of the terms of, this License. For legal
-entities, "You" includes any entity that controls, is controlled by, or is
-under common control with you. For purposes of this definition, "control" means
-(i) the power, direct or indirect, to cause the direction or management of such
-entity, whether by contract or otherwise, or (ii) ownership of fifty percent
-(50%) or more of the outstanding shares, or (iii) beneficial ownership of such
-entity.
-
-15) Right to Use. You may use the Original Work in all ways not otherwise
-restricted or conditioned by this License or by law, and Licensor promises not
-to interfere with or be responsible for such uses by You.
-
-This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved.
-Permission is hereby granted to copy and distribute this license without
-modification. This license may not be modified without the express written
-permission of its copyright owner.

+ 0 - 928
esp/files/dgrid/List.js

@@ -1,928 +0,0 @@
-define(["dojo/_base/kernel", "dojo/_base/declare", "dojo/on", "dojo/has", "./util/misc", "dojo/has!touch?./TouchScroll", "xstyle/has-class", "put-selector/put", "dojo/_base/sniff", "xstyle/css!./css/dgrid.css"], 
-function(kernel, declare, listen, has, miscUtil, TouchScroll, hasClass, put){
-	// Add user agent/feature CSS classes 
-	hasClass("mozilla", "opera", "webkit", "ie", "ie-6", "ie-6-7", "quirks", "no-quirks", "touch");
-	
-	var oddClass = "dgrid-row-odd",
-		evenClass = "dgrid-row-even",
-		scrollbarWidth, scrollbarHeight;
-	
-	function byId(id){
-		return document.getElementById(id);
-	}
-	
-	function getScrollbarSize(node, dimension){
-		// Used by has tests for scrollbar width/height
-		var body = document.body,
-			size;
-		
-		put(body, node, ".dgrid-scrollbar-measure");
-		size = node["offset" + dimension] - node["client" + dimension];
-		
-		put(node, "!dgrid-scrollbar-measure");
-		body.removeChild(node);
-		
-		return size;
-	}
-	has.add("dom-scrollbar-width", function(global, doc, element){
-		return getScrollbarSize(element, "Width");
-	});
-	has.add("dom-scrollbar-height", function(global, doc, element){
-		return getScrollbarSize(element, "Height");
-	});
-	
-	// var and function for autogenerating ID when one isn't provided
-	var autogen = 0;
-	function generateId(){
-		return "dgrid_" + autogen++;
-	}
-	
-	// common functions for class and className setters/getters
-	// (these are run in instance context)
-	var spaceRx = / +/g;
-	function setClass(cls){
-		// Format input appropriately for use with put...
-		var putClass = cls ? "." + cls.replace(spaceRx, ".") : "";
-		
-		// Remove any old classes, and add new ones.
-		if(this._class){
-			putClass = "!" + this._class.replace(spaceRx, "!") + putClass;
-		}
-		put(this.domNode, putClass);
-		
-		// Store for later retrieval/removal.
-		this._class = cls;
-	}
-	function getClass(){
-		return this._class;
-	}
-	
-	// window resize event handler, run in context of List instance
-	var winResizeHandler = has("ie") < 7 && !has("quirks") ? function(){
-		// IE6 triggers window.resize on any element resize;
-		// avoid useless calls (and infinite loop if height: auto).
-		// The measurement logic here is based on dojo/window logic.
-		var root, w, h, dims;
-		
-		if(!this._started){ return; } // no sense calling resize yet
-		
-		root = document.documentElement;
-		w = root.clientWidth;
-		h = root.clientHeight;
-		dims = this._prevWinDims || [];
-		if(dims[0] !== w || dims[1] !== h){
-			this.resize();
-			this._prevWinDims = [w, h];
-		}
-	} :
-	function(){
-		if(this._started){ this.resize(); }
-	};
-	
-	// Desktop versions of functions, deferred to when there is no touch support,
-	// or when the useTouchScroll instance property is set to false
-	
-	function desktopGetScrollPosition(){
-		return {
-			x: this.bodyNode.scrollLeft,
-			y: this.bodyNode.scrollTop
-		};
-	}
-	
-	function desktopScrollTo(options){
-		if(typeof options.x !== "undefined"){
-			this.bodyNode.scrollLeft = options.x;
-		}
-		if(typeof options.y !== "undefined"){
-			this.bodyNode.scrollTop = options.y;
-		}
-	}
-	
-	return declare(has("touch") ? TouchScroll : null, {
-		tabableHeader: false,
-		// showHeader: Boolean
-		//		Whether to render header (sub)rows.
-		showHeader: false,
-		
-		// showFooter: Boolean
-		//		Whether to render footer area.  Extensions which display content
-		//		in the footer area should set this to true.
-		showFooter: false,
-		
-		// maintainOddEven: Boolean
-		//		Whether to maintain the odd/even classes when new rows are inserted.
-		//		This can be disabled to improve insertion performance if odd/even styling is not employed.
-		maintainOddEven: true,
-		
-		// cleanAddedRules: Boolean
-		//		Whether to track rules added via the addCssRule method to be removed
-		//		when the list is destroyed.  Note this is effective at the time of
-		//		the call to addCssRule, not at the time of destruction.
-		cleanAddedRules: true,
-		
-		// useTouchScroll: Boolean
-		//		If touch support is available, this determines whether to
-		//		incorporate logic from the TouchScroll module (at the expense of
-		//		normal desktop/mouse or native mobile scrolling functionality).
-		useTouchScroll: true,
-
-		// cleanEmptyObservers: Boolean
-		//		Whether to clean up observers for empty result sets.
-		cleanEmptyObservers: true,
-
-		// highlightDuration: Integer
-		//		The amount of time (in milliseconds) that a row should remain
-		//		highlighted after it has been updated.
-		highlightDuration: 250,
-		
-		postscript: function(params, srcNodeRef){
-			// perform setup and invoke create in postScript to allow descendants to
-			// perform logic before create/postCreate happen (a la dijit/_WidgetBase)
-			var grid = this;
-			
-			(this._Row = function(id, object, element){
-				this.id = id;
-				this.data = object;
-				this.element = element;
-			}).prototype.remove = function(){
-				grid.removeRow(this.element);
-			};
-			
-			if(srcNodeRef){
-				// normalize srcNodeRef and store on instance during create process.
-				// Doing this in postscript is a bit earlier than dijit would do it,
-				// but allows subclasses to access it pre-normalized during create.
-				this.srcNodeRef = srcNodeRef =
-					srcNodeRef.nodeType ? srcNodeRef : byId(srcNodeRef);
-			}
-			this.create(params, srcNodeRef);
-		},
-		listType: "list",
-		
-		create: function(params, srcNodeRef){
-			var domNode = this.domNode = srcNodeRef || put("div"),
-				cls;
-			
-			if(params){
-				this.params = params;
-				declare.safeMixin(this, params);
-				
-				// Check for initial class or className in params or on domNode
-				cls = params["class"] || params.className || domNode.className;
-				
-				// handle sort param - TODO: revise @ 0.4 when _sort -> sort
-				this._sort = params.sort || [];
-				delete this.sort; // ensure back-compat method isn't shadowed
-			}else{
-				this._sort = [];
-			}
-			
-			// ensure arrays and hashes are initialized
-			this.observers = [];
-			this._numObservers = 0;
-			this._listeners = [];
-			this._rowIdToObject = {};
-			
-			this.postMixInProperties && this.postMixInProperties();
-			
-			// Apply id to widget and domNode,
-			// from incoming node, widget params, or autogenerated.
-			this.id = domNode.id = domNode.id || this.id || generateId();
-			
-			// Perform initial rendering, and apply classes if any were specified.
-			this.buildRendering();
-			if(cls){ setClass.call(this, cls); }
-			
-			this.postCreate();
-			
-			// remove srcNodeRef instance property post-create
-			delete this.srcNodeRef;
-			// to preserve "it just works" behavior, call startup if we're visible
-			if(this.domNode.offsetHeight){
-				this.startup();
-			}
-		},
-		buildRendering: function(){
-			var domNode = this.domNode,
-				self = this,
-				headerNode, spacerNode, bodyNode, footerNode, isRTL;
-			
-			// Detect RTL on html/body nodes; taken from dojo/dom-geometry
-			isRTL = this.isRTL = (document.body.dir || document.documentElement.dir ||
-				document.body.style.direction).toLowerCase() == "rtl";
-			
-			// Clear out className (any pre-applied classes will be re-applied via the
-			// class / className setter), then apply standard classes/attributes
-			domNode.className = "";
-			
-			put(domNode, "[role=grid].ui-widget.dgrid.dgrid-" + this.listType);
-			
-			// Place header node (initially hidden if showHeader is false).
-			headerNode = this.headerNode = put(domNode, 
-				"div.dgrid-header.dgrid-header-row.ui-widget-header" +
-				(this.showHeader ? "" : ".dgrid-header-hidden"));
-			if(has("quirks") || has("ie") < 8){
-				spacerNode = put(domNode, "div.dgrid-spacer");
-			}
-			bodyNode = this.bodyNode = put(domNode, "div.dgrid-scroller");
-			
-			// firefox 4 until at least 10 adds overflow: auto elements to the tab index by default for some
-			// reason; force them to be not tabbable
-			bodyNode.tabIndex = -1;
-			
-			this.headerScrollNode = put(domNode, "div.dgrid-header-scroll.dgrid-scrollbar-width.ui-widget-header");
-			
-			// Place footer node (initially hidden if showFooter is false).
-			footerNode = this.footerNode = put("div.dgrid-footer" +
-				(this.showFooter ? "" : ".dgrid-footer-hidden"));
-			put(domNode, footerNode);
-			
-			if(isRTL){
-				domNode.className += " dgrid-rtl" + (has("webkit") ? "" : " dgrid-rtl-nonwebkit");
-			}
-			
-			listen(bodyNode, "scroll", function(event){
-				if(self.showHeader){
-					// keep the header aligned with the body
-					headerNode.scrollLeft = event.scrollLeft || bodyNode.scrollLeft;
-				}
-				// re-fire, since browsers are not consistent about propagation here
-				event.stopPropagation();
-				listen.emit(domNode, "scroll", {scrollTarget: bodyNode});
-			});
-			this.configStructure();
-			this.renderHeader();
-			
-			this.contentNode = this.touchNode = put(this.bodyNode, "div.dgrid-content.ui-widget-content");
-			// add window resize handler, with reference for later removal if needed
-			this._listeners.push(this._resizeHandle = listen(window, "resize",
-				miscUtil.throttleDelayed(winResizeHandler, this)));
-		},
-		
-		postCreate: has("touch") ? function(){
-			if(this.useTouchScroll){
-				this.inherited(arguments);
-			}
-		} : function(){},
-		
-		startup: function(){
-			// summary:
-			//		Called automatically after postCreate if the component is already
-			//		visible; otherwise, should be called manually once placed.
-			
-			if(this._started){ return; } // prevent double-triggering
-			this.inherited(arguments);
-			this._started = true;
-			this.resize();
-			// apply sort (and refresh) now that we're ready to render
-			this.set("sort", this._sort);
-		},
-		
-		configStructure: function(){
-			// does nothing in List, this is more of a hook for the Grid
-		},
-		resize: function(){
-			var
-				bodyNode = this.bodyNode,
-				headerNode = this.headerNode,
-				footerNode = this.footerNode,
-				headerHeight = headerNode.offsetHeight,
-				footerHeight = this.showFooter ? footerNode.offsetHeight : 0,
-				quirks = has("quirks") || has("ie") < 7;
-			
-			this.headerScrollNode.style.height = bodyNode.style.marginTop = headerHeight + "px";
-			bodyNode.style.marginBottom = footerHeight + "px";
-			
-			if(quirks){
-				// in IE6 and quirks mode, the "bottom" CSS property is ignored.
-				// We guard against negative values in case of issues with external CSS.
-				bodyNode.style.height = ""; // reset first
-				bodyNode.style.height =
-					Math.max((this.domNode.offsetHeight - headerHeight - footerHeight), 0) + "px";
-				if (footerHeight) {
-					// Work around additional glitch where IE 6 / quirks fails to update
-					// the position of the bottom-aligned footer; this jogs its memory.
-					footerNode.style.bottom = '1px';
-					setTimeout(function(){ footerNode.style.bottom = ''; }, 0);
-				}
-			}
-			
-			if(!scrollbarWidth){
-				// Measure the browser's scrollbar width using a DIV we'll delete right away
-				scrollbarWidth = has("dom-scrollbar-width");
-				scrollbarHeight = has("dom-scrollbar-height");
-				
-				// Avoid issues with certain widgets inside in IE7, and
-				// ColumnSet scroll issues with all supported IE versions
-				if(has("ie")){
-					scrollbarWidth++;
-					scrollbarHeight++;
-				}
-				
-				// add rules that can be used where scrollbar width/height is needed
-				miscUtil.addCssRule(".dgrid-scrollbar-width", "width: " + scrollbarWidth + "px");
-				miscUtil.addCssRule(".dgrid-scrollbar-height", "height: " + scrollbarHeight + "px");
-				
-				if(scrollbarWidth != 17 && !quirks){
-					// for modern browsers, we can perform a one-time operation which adds
-					// a rule to account for scrollbar width in all grid headers.
-					miscUtil.addCssRule(".dgrid-header", "right: " + scrollbarWidth + "px");
-					// add another for RTL grids
-					miscUtil.addCssRule(".dgrid-rtl-nonwebkit .dgrid-header", "left: " + scrollbarWidth + "px");
-				}
-			}
-			
-			if(quirks){
-				// old IE doesn't support left + right + width:auto; set width directly
-				headerNode.style.width = bodyNode.clientWidth + "px";
-				setTimeout(function(){
-					// sync up (after the browser catches up with the new width)
-					headerNode.scrollLeft = bodyNode.scrollLeft;
-				}, 0);
-			}
-		},
-		
-		addCssRule: function(selector, css){
-			// summary:
-			//		Version of util/misc.addCssRule which tracks added rules and removes
-			//		them when the List is destroyed.
-			
-			var rule = miscUtil.addCssRule(selector, css);
-			if(this.cleanAddedRules){
-				// Although this isn't a listener, it shares the same remove contract
-				this._listeners.push(rule);
-			}
-			return rule;
-		},
-		
-		on: function(eventType, listener){
-			// delegate events to the domNode
-			var signal = listen(this.domNode, eventType, listener);
-			if(!has("dom-addeventlistener")){
-				this._listeners.push(signal);
-			}
-			return signal;
-		},
-		
-		cleanup: function(){
-			// summary:
-			//		Clears out all rows currently in the list.
-			
-			var observers = this.observers,
-				i;
-			for(i in this._rowIdToObject){
-				if(this._rowIdToObject[i] != this.columns){
-					var rowElement = byId(i);
-					if(rowElement){
-						this.removeRow(rowElement, true);
-					}
-				}
-			}
-			// remove any store observers
-			for(i = 0;i < observers.length; i++){
-				var observer = observers[i];
-				observer && observer.cancel();
-			}
-			this.observers = [];
-			this._numObservers = 0;
-			this.preload = null;
-		},
-		destroy: function(){
-			// summary:
-			//		Destroys this grid
-			
-			// Remove any event listeners and other such removables
-			if(this._listeners){ // Guard against accidental subsequent calls to destroy
-				for(var i = this._listeners.length; i--;){
-					this._listeners[i].remove();
-				}
-				delete this._listeners;
-			}
-			
-			this.cleanup();
-			// destroy DOM
-			put(this.domNode, "!");
-			this.inherited(arguments);
-		},
-		refresh: function(){
-			// summary:
-			//		refreshes the contents of the grid
-			this.cleanup();
-			this._rowIdToObject = {};
-			this._autoId = 0;
-			
-			// make sure all the content has been removed so it can be recreated
-			this.contentNode.innerHTML = "";
-			// Ensure scroll position always resets (especially for TouchScroll).
-			this.scrollTo({ x: 0, y: 0 });
-		},
-		
-		newRow: function(object, parentNode, beforeNode, i, options){
-			if(parentNode){
-				var row = this.insertRow(object, parentNode, beforeNode, i, options);
-				put(row, ".ui-state-highlight");
-				setTimeout(function(){
-					put(row, "!ui-state-highlight");
-				}, this.highlightDuration);
-				return row;
-			}
-		},
-		adjustRowIndices: function(firstRow){
-			// this traverses through rows to maintain odd/even classes on the rows when indexes shift;
-			var next = firstRow;
-			var rowIndex = next.rowIndex;
-			if(rowIndex > -1){ // make sure we have a real number in case this is called on a non-row
-				do{
-					// Skip non-numeric, non-rows
-					if(next.rowIndex > -1){
-						if(this.maintainOddEven){
-							if((next.className + ' ').indexOf("dgrid-row ") > -1){
-								put(next, '.' + (rowIndex % 2 == 1 ? oddClass : evenClass) + '!' + (rowIndex % 2 == 0 ? oddClass : evenClass));
-							}
-						}
-						next.rowIndex = rowIndex++;
-					}
-				}while((next = next.nextSibling) && next.rowIndex != rowIndex);
-			}
-		},
-		renderArray: function(results, beforeNode, options){
-			// summary:
-			//		This renders an array or collection of objects as rows in the grid, before the
-			//		given node. This will listen for changes in the collection if an observe method
-			//		is available (as it should be if it comes from an Observable data store).
-			options = options || {};
-			var self = this,
-				start = options.start || 0,
-				observers = this.observers,
-				rows, container, observerIndex;
-			
-			if(!beforeNode){
-				this._lastCollection = results;
-			}
-			if(results.observe){
-				// observe the results for changes
-				self._numObservers++;
-				observerIndex = observers.push(results.observe(function(object, from, to){
-					var row, firstRow, nextNode, parentNode;
-					
-					function advanceNext() {
-						nextNode = (nextNode.connected || nextNode).nextSibling;
-					}
-					
-					// a change in the data took place
-					if(from > -1 && rows[from]){
-						// remove from old slot
-						row = rows.splice(from, 1)[0];
-						// check to make the sure the node is still there before we try to remove it, (in case it was moved to a different place in the DOM)
-						if(row.parentNode == container){
-							firstRow = row.nextSibling;
-							if(firstRow){ // it's possible for this to have been already removed if it is in overlapping query results
-								if(from != to){ // if from and to are identical, it is an in-place update and we don't want to alter the rowIndex at all
-									firstRow.rowIndex--; // adjust the rowIndex so adjustRowIndices has the right starting point
-								}
-							}
-							self.removeRow(row); // now remove
-						}
-						// the removal of rows could cause us to need to page in more items
-						if(self._processScroll){
-							self._processScroll();
-						}
-					}
-					if(to > -1){
-						// Add to new slot (either before an existing row, or at the end)
-						// First determine the DOM node that this should be placed before.
-						if(rows.length){
-							nextNode = rows[to];
-							if(!nextNode){
-								nextNode = rows[to - 1];
-								if(nextNode){
-									// Make sure to skip connected nodes, so we don't accidentally
-									// insert a row in between a parent and its children.
-									advanceNext();
-								}
-							}
-						}else{
-							// There are no rows.  Allow for subclasses to insert new rows somewhere other than
-							// at the end of the parent node.
-							nextNode = self._getFirstRowSibling && self._getFirstRowSibling(container);
-						}
-						// Make sure we don't trip over a stale reference to a
-						// node that was removed, or try to place a node before
-						// itself (due to overlapped queries)
-						if(row && nextNode && row.id === nextNode.id){
-							advanceNext();
-						}
-						if(nextNode && !nextNode.parentNode){
-							nextNode = byId(nextNode.id);
-						}
-						parentNode = (beforeNode && beforeNode.parentNode) ||
-							(nextNode && nextNode.parentNode) || self.contentNode;
-						row = self.newRow(object, parentNode, nextNode, options.start + to, options);
-						
-						if(row){
-							row.observerIndex = observerIndex;
-							rows.splice(to, 0, row);
-							if(!firstRow || to < from){
-								// the inserted row is first, so we update firstRow to point to it
-								var previous = row.previousSibling;
-								// if we are not in sync with the previous row, roll the firstRow back one so adjustRowIndices can sync everything back up.
-								firstRow = !previous || previous.rowIndex + 1 == row.rowIndex || row.rowIndex == 0 ?
-									row : previous;
-							}
-						}
-						options.count++;
-					}
-					from != to && firstRow && self.adjustRowIndices(firstRow);
-					self._onNotification(rows, object, from, to);
-				}, true)) - 1;
-			}
-			var rowsFragment = document.createDocumentFragment(),
-				lastRow;
-			
-			function mapEach(object){
-				lastRow = self.insertRow(object, rowsFragment, null, start++, options);
-				lastRow.observerIndex = observerIndex;
-				return lastRow;
-			}
-			function whenError(error){
-				if(typeof observerIndex !== "undefined"){
-					observers[observerIndex].cancel();
-					observers[observerIndex] = 0;
-					self._numObservers--;
-				}
-				if(error){
-					throw error;
-				}
-			}
-			function whenDone(resolvedRows){
-				container = beforeNode ? beforeNode.parentNode : self.contentNode;
-				if(container && container.parentNode &&
-						(container !== self.contentNode || resolvedRows.length)){
-					container.insertBefore(rowsFragment, beforeNode || null);
-					lastRow = resolvedRows[resolvedRows.length - 1];
-					lastRow && self.adjustRowIndices(lastRow);
-				}else if(observers[observerIndex] && self.cleanEmptyObservers){
-					// Remove the observer and don't bother inserting;
-					// rows are already out of view or there were none to track
-					whenError();
-				}
-				return (rows = resolvedRows);
-			}
-			
-			// now render the results
-			if(results.map){
-				rows = results.map(mapEach, console.error);
-				if(rows.then){
-					return rows.then(whenDone, whenError);
-				}
-			}else{
-				rows = [];
-				for(var i = 0, l = results.length; i < l; i++){
-					rows[i] = mapEach(results[i]);
-				}
-			}
-			
-			return whenDone(rows);
-		},
-
-		_onNotification: function(rows, object, from, to){
-			// summary:
-			//		Protected method called whenever a store notification is observed.
-			//		Intended to be extended as necessary by mixins/extensions.
-		},
-
-		renderHeader: function(){
-			// no-op in a plain list
-		},
-		
-		_autoId: 0,
-		insertRow: function(object, parent, beforeNode, i, options){
-			// summary:
-			//		Creates a single row in the grid.
-			
-			// Include parentId within row identifier if one was specified in options.
-			// (This is used by tree to allow the same object to appear under
-			// multiple parents.)
-			var parentId = options.parentId,
-				id = this.id + "-row-" + (parentId ? parentId + "-" : "") + 
-					((this.store && this.store.getIdentity) ? 
-						this.store.getIdentity(object) : this._autoId++),
-				row = byId(id),
-				previousRow = row && row.previousSibling;
-			
-			if(row){// if it existed elsewhere in the DOM, we will remove it, so we can recreate it
-				this.removeRow(row);
-			}
-			row = this.renderRow(object, options);
-			row.className = (row.className || "") + " ui-state-default dgrid-row " + (i % 2 == 1 ? oddClass : evenClass);
-			// get the row id for easy retrieval
-			this._rowIdToObject[row.id = id] = object;
-			parent.insertBefore(row, beforeNode || null);
-			if(previousRow){
-				// in this case, we are pulling the row from another location in the grid, and we need to readjust the rowIndices from the point it was removed
-				this.adjustRowIndices(previousRow);
-			}
-			row.rowIndex = i;
-			return row;
-		},
-		renderRow: function(value, options){
-			// summary:
-			//		Responsible for returning the DOM for a single row in the grid.
-			
-			return put("div", "" + value);
-		},
-		removeRow: function(rowElement, justCleanup){
-			// summary:
-			//		Simply deletes the node in a plain List.
-			//		Column plugins may aspect this to implement their own cleanup routines.
-			// rowElement: Object|DOMNode
-			//		Object or element representing the row to be removed.
-			// justCleanup: Boolean
-			//		If true, the row element will not be removed from the DOM; this can
-			//		be used by extensions/plugins in cases where the DOM will be
-			//		massively cleaned up at a later point in time.
-			
-			rowElement = rowElement.element || rowElement;
-			delete this._rowIdToObject[rowElement.id];
-			if(!justCleanup){
-				put(rowElement, "!");
-			}
-		},
-		
-		row: function(target){
-			// summary:
-			//		Get the row object by id, object, node, or event
-			var id;
-			
-			if(target instanceof this._Row){ return target; } // no-op; already a row
-			
-			if(target.target && target.target.nodeType){
-				// event
-				target = target.target;
-			}
-			if(target.nodeType){
-				var object;
-				do{
-					var rowId = target.id;
-					if((object = this._rowIdToObject[rowId])){
-						return new this._Row(rowId.substring(this.id.length + 5), object, target); 
-					}
-					target = target.parentNode;
-				}while(target && target != this.domNode);
-				return;
-			}
-			if(typeof target == "object"){
-				// assume target represents a store item
-				id = this.store.getIdentity(target);
-			}else{
-				// assume target is a row ID
-				id = target;
-				target = this._rowIdToObject[this.id + "-row-" + id];
-			}
-			return new this._Row(id, target, byId(this.id + "-row-" + id));
-		},
-		cell: function(target){
-			// this doesn't do much in a plain list
-			return {
-				row: this.row(target)
-			};
-		},
-		
-		_move: function(item, steps, targetClass, visible){
-			var nextSibling, current, element;
-			// Start at the element indicated by the provided row or cell object.
-			element = current = item.element;
-			steps = steps || 1;
-			
-			do{
-				// Outer loop: move in the appropriate direction.
-				if((nextSibling = current[steps < 0 ? "previousSibling" : "nextSibling"])){
-					do{
-						// Inner loop: advance, and dig into children if applicable.
-						current = nextSibling;
-						if(current && (current.className + " ").indexOf(targetClass + " ") > -1){
-							// Element with the appropriate class name; count step, stop digging.
-							element = current;
-							steps += steps < 0 ? 1 : -1;
-							break;
-						}
-						// If the next sibling isn't a match, drill down to search, unless
-						// visible is true and children are hidden.
-					}while((nextSibling = (!visible || !current.hidden) && current[steps < 0 ? "lastChild" : "firstChild"]));
-				}else{
-					current = current.parentNode;
-					if(current === this.bodyNode || current === this.headerNode){
-						// Break out if we step out of the navigation area entirely.
-						break;
-					}
-				}
-			}while(steps);
-			// Return the final element we arrived at, which might still be the
-			// starting element if we couldn't navigate further in that direction.
-			return element;
-		},
-		
-		up: function(row, steps, visible){
-			// summary:
-			//		Returns the row that is the given number of steps (1 by default)
-			//		above the row represented by the given object.
-			// row:
-			//		The row to navigate upward from.
-			// steps:
-			//		Number of steps to navigate up from the given row; default is 1.
-			// visible:
-			//		If true, rows that are currently hidden (i.e. children of
-			//		collapsed tree rows) will not be counted in the traversal.
-			// returns:
-			//		A row object representing the appropriate row.  If the top of the
-			//		list is reached before the given number of steps, the first row will
-			//		be returned.
-			if(!row.element){ row = this.row(row); }
-			return this.row(this._move(row, -(steps || 1), "dgrid-row", visible));
-		},
-		down: function(row, steps, visible){
-			// summary:
-			//		Returns the row that is the given number of steps (1 by default)
-			//		below the row represented by the given object.
-			// row:
-			//		The row to navigate downward from.
-			// steps:
-			//		Number of steps to navigate down from the given row; default is 1.
-			// visible:
-			//		If true, rows that are currently hidden (i.e. children of
-			//		collapsed tree rows) will not be counted in the traversal.
-			// returns:
-			//		A row object representing the appropriate row.  If the bottom of the
-			//		list is reached before the given number of steps, the last row will
-			//		be returned.
-			if(!row.element){ row = this.row(row); }
-			return this.row(this._move(row, steps || 1, "dgrid-row", visible));
-		},
-		
-		scrollTo: has("touch") ? function(options){
-			// If TouchScroll is the superclass, defer to its implementation.
-			return this.useTouchScroll ? this.inherited(arguments) :
-				desktopScrollTo.call(this, options);
-		} : desktopScrollTo,
-		
-		getScrollPosition: has("touch") ? function(){
-			// If TouchScroll is the superclass, defer to its implementation.
-			return this.useTouchScroll ? this.inherited(arguments) :
-				desktopGetScrollPosition.call(this);
-		} : desktopGetScrollPosition,
-		
-		get: function(/*String*/ name /*, ... */){
-			// summary:
-			//		Get a property on a List instance.
-			//	name:
-			//		The property to get.
-			//	returns:
-			//		The property value on this List instance.
-			// description:
-			//		Get a named property on a List object. The property may
-			//		potentially be retrieved via a getter method in subclasses. In the base class
-			//		this just retrieves the object's property.
-			
-			var fn = "_get" + name.charAt(0).toUpperCase() + name.slice(1);
-			
-			if(typeof this[fn] === "function"){
-				return this[fn].apply(this, [].slice.call(arguments, 1));
-			}
-			
-			// Alert users that try to use Dijit-style getter/setters so they don’t get confused
-			// if they try to use them and it does not work
-			if(!has("dojo-built") && typeof this[fn + "Attr"] === "function"){
-				console.warn("dgrid: Use " + fn + " instead of " + fn + "Attr for getting " + name);
-			}
-			
-			return this[name];
-		},
-		
-		set: function(/*String*/ name, /*Object*/ value /*, ... */){
-			//	summary:
-			//		Set a property on a List instance
-			//	name:
-			//		The property to set.
-			//	value:
-			//		The value to set in the property.
-			//	returns:
-			//		The function returns this List instance.
-			//	description:
-			//		Sets named properties on a List object.
-			//		A programmatic setter may be defined in subclasses.
-			//
-			//		set() may also be called with a hash of name/value pairs, ex:
-			//	|	myObj.set({
-			//	|		foo: "Howdy",
-			//	|		bar: 3
-			//	|	})
-			//		This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
-			
-			if(typeof name === "object"){
-				for(var k in name){
-					this.set(k, name[k]);
-				}
-			}else{
-				var fn = "_set" + name.charAt(0).toUpperCase() + name.slice(1);
-				
-				if(typeof this[fn] === "function"){
-					this[fn].apply(this, [].slice.call(arguments, 1));
-				}else{
-					// Alert users that try to use Dijit-style getter/setters so they don’t get confused
-					// if they try to use them and it does not work
-					if(!has("dojo-built") && typeof this[fn + "Attr"] === "function"){
-						console.warn("dgrid: Use " + fn + " instead of " + fn + "Attr for setting " + name);
-					}
-					
-					this[name] = value;
-				}
-			}
-			
-			return this;
-		},
-		
-		// Accept both class and className programmatically to set domNode class.
-		_getClass: getClass,
-		_setClass: setClass,
-		_getClassName: getClass,
-		_setClassName: setClass,
-		
-		_setSort: function(property, descending){
-			// summary:
-			//		Sort the content
-			// property: String|Array
-			//		String specifying field to sort by, or actual array of objects
-			//		with attribute and descending properties
-			// descending: boolean
-			//		In the case where property is a string, this argument
-			//		specifies whether to sort ascending (false) or descending (true)
-			
-			this._sort = typeof property != "string" ? property :
-				[{attribute: property, descending: descending}];
-			
-			this.refresh();
-			
-			if(this._lastCollection){
-				if(property.length){
-					// if an array was passed in, flatten to just first sort attribute
-					// for default array sort logic
-					if(typeof property != "string"){
-						descending = property[0].descending;
-						property = property[0].attribute;
-					}
-					
-					this._lastCollection.sort(function(a,b){
-						var aVal = a[property], bVal = b[property];
-						// fall back undefined values to "" for more consistent behavior
-						if(aVal === undefined){ aVal = ""; }
-						if(bVal === undefined){ bVal = ""; }
-						return aVal == bVal ? 0 : (aVal > bVal == !descending ? 1 : -1);
-					});
-				}
-				this.renderArray(this._lastCollection);
-			}
-		},
-		// TODO: remove the following two (and rename _sort to sort) in 0.4
-		sort: function(property, descending){
-			kernel.deprecated("sort(...)", 'use set("sort", ...) instead', "dgrid 0.4");
-			this.set("sort", property, descending);
-		},
-		_getSort: function(){
-			return this._sort;
-		},
-		
-		_setShowHeader: function(show){
-			// this is in List rather than just in Grid, primarily for two reasons:
-			// (1) just in case someone *does* want to show a header in a List
-			// (2) helps address IE < 8 header display issue in List
-			
-			var headerNode = this.headerNode;
-			
-			this.showHeader = show;
-			
-			// add/remove class which has styles for "hiding" header
-			put(headerNode, (show ? "!" : ".") + "dgrid-header-hidden");
-			
-			this.renderHeader();
-			this.resize(); // resize to account for (dis)appearance of header
-			
-			if(show){
-				// Update scroll position of header to make sure it's in sync.
-				headerNode.scrollLeft = this.getScrollPosition().x;
-			}
-		},
-		setShowHeader: function(show){
-			kernel.deprecated("setShowHeader(...)", 'use set("showHeader", ...) instead', "dgrid 0.4");
-			this.set("showHeader", show);
-		},
-		
-		_setShowFooter: function(show){
-			this.showFooter = show;
-			
-			// add/remove class which has styles for hiding footer
-			put(this.footerNode, (show ? "!" : ".") + "dgrid-footer-hidden");
-			
-			this.resize(); // to account for (dis)appearance of footer
-		}
-	});
-});

+ 0 - 3
esp/files/dgrid/OnDemandGrid.js

@@ -1,3 +0,0 @@
-define(["dojo/_base/declare", "./Grid", "./OnDemandList"], function(declare, Grid, OnDemandList){
-	return declare([Grid, OnDemandList], {});
-});

+ 0 - 626
esp/files/dgrid/OnDemandList.js

@@ -1,626 +0,0 @@
-define(["./List", "./_StoreMixin", "dojo/_base/declare", "dojo/_base/lang", "dojo/_base/Deferred", "dojo/on", "./util/misc", "put-selector/put"],
-function(List, _StoreMixin, declare, lang, Deferred, listen, miscUtil, put){
-
-return declare([List, _StoreMixin], {
-	// summary:
-	//		Extends List to include virtual scrolling functionality, querying a
-	//		dojo/store instance for the appropriate range when the user scrolls.
-	
-	// minRowsPerPage: Integer
-	//		The minimum number of rows to request at one time.
-	minRowsPerPage: 25,
-	
-	// maxRowsPerPage: Integer
-	//		The maximum number of rows to request at one time.
-	maxRowsPerPage: 250,
-	
-	// maxEmptySpace: Integer
-	//		Defines the maximum size (in pixels) of unrendered space below the
-	//		currently-rendered rows. Setting this to less than Infinity can be useful if you
-	//		wish to limit the initial vertical scrolling of the grid so that the scrolling is
-	// 		not excessively sensitive. With very large grids of data this may make scrolling
-	//		easier to use, albiet it can limit the ability to instantly scroll to the end.
-	maxEmptySpace: Infinity,	
-	
-	// bufferRows: Integer
-	//	  The number of rows to keep ready on each side of the viewport area so that the user can
-	//	  perform local scrolling without seeing the grid being built. Increasing this number can
-	//	  improve perceived performance when the data is being retrieved over a slow network.
-	bufferRows: 10,
-	
-	// farOffRemoval: Integer
-	//		Defines the minimum distance (in pixels) from the visible viewport area
-	//		rows must be in order to be removed.  Setting to Infinity causes rows
-	//		to never be removed.
-	farOffRemoval: 2000,
-	
-	// queryRowsOverlap: Integer
-	//		Indicates the number of rows to overlap queries. This helps keep
-	//		continuous data when underlying data changes (and thus pages don't
-	//		exactly align)
-	queryRowsOverlap: 1,
-	
-	// pagingMethod: String
-	//		Method (from dgrid/util/misc) to use to either throttle or debounce
-	//		requests.  Default is "debounce" which will cause the grid to wait until
-	//		the user pauses scrolling before firing any requests; can be set to
-	//		"throttleDelayed" instead to progressively request as the user scrolls,
-	//		which generally incurs more overhead but might appear more responsive.
-	pagingMethod: "debounce",
-	
-	// pagingDelay: Integer
-	//		Indicates the delay (in milliseconds) imposed upon pagingMethod, to wait
-	//		before paging in more data on scroll events. This can be increased to
-	//		reduce client-side overhead or the number of requests sent to a server.
-	pagingDelay: miscUtil.defaultDelay,
-	
-	// keepScrollPosition: Boolean
-	//		When refreshing the list, controls whether the scroll position is
-	//		preserved, or reset to the top.  This can also be overridden for
-	//		specific calls to refresh.
-	keepScrollPosition: false,
-	
-	rowHeight: 22,
-	
-	postCreate: function(){
-		this.inherited(arguments);
-		var self = this;
-		// check visibility on scroll events
-		listen(this.bodyNode, "scroll",
-			miscUtil[this.pagingMethod](function(event){ self._processScroll(event); },
-				null, this.pagingDelay));
-	},
-	
-	renderQuery: function(query, preloadNode, options){
-		// summary:
-		//		Creates a preload node for rendering a query into, and executes the query
-		//		for the first page of data. Subsequent data will be downloaded as it comes
-		//		into view.
-		var self = this,
-			preload = {
-				query: query,
-				count: 0,
-				node: preloadNode,
-				options: options
-			},
-			priorPreload = this.preload,
-			results;
-		
-		if(!preloadNode){
-			// Initial query; set up top and bottom preload nodes
-			var topPreload = {
-				node: put(this.contentNode, "div.dgrid-preload", {
-					rowIndex: 0
-				}),
-				count: 0,
-				query: query,
-				next: preload,
-				options: options
-			};
-			topPreload.node.style.height = "0";
-			preload.node = preloadNode = put(this.contentNode, "div.dgrid-preload");
-			preload.previous = topPreload;
-		}
-		// this preload node is used to represent the area of the grid that hasn't been
-		// downloaded yet
-		preloadNode.rowIndex = this.minRowsPerPage;
-
-		if(priorPreload){
-			// the preload nodes (if there are multiple) are represented as a linked list, need to insert it
-			if((preload.next = priorPreload.next) && 
-					// check to make sure that the current scroll position is below this preload
-					this.bodyNode.scrollTop >= priorPreload.node.offsetTop){ 
-				// the prior preload is above/before in the linked list
-				preload.previous = priorPreload;
-			}else{
-				// the prior preload is below/after in the linked list
-				preload.next = priorPreload;
-				preload.previous = priorPreload.previous;
-			}
-			// adjust the previous and next links so the linked list is proper
-			preload.previous.next = preload;
-			preload.next.previous = preload; 
-		}else{
-			this.preload = preload;
-		}
-		
-		var loadingNode = put(preloadNode, "-div.dgrid-loading"),
-			innerNode = put(loadingNode, "div.dgrid-below");
-		innerNode.innerHTML = this.loadingMessage;
-
-		function errback(err) {
-			// Used as errback for when calls;
-			// remove the loadingNode and re-throw if an error was passed
-			put(loadingNode, "!");
-			
-			if(err){
-				if(self._refreshDeferred){
-					self._refreshDeferred.reject(err);
-					delete self._refreshDeferred;
-				}
-				throw err;
-			}
-		}
-
-		// Establish query options, mixing in our own.
-		// (The getter returns a delegated object, so simply using mixin is safe.)
-		options = lang.mixin(this.get("queryOptions"), options, 
-			{ start: 0, count: this.minRowsPerPage },
-			"level" in query ? { queryLevel: query.level } : null);
-		
-		// Protect the query within a _trackError call, but return the QueryResults
-		this._trackError(function(){ return results = query(options); });
-		
-		if(typeof results === "undefined"){
-			// Synchronous error occurred (but was caught by _trackError)
-			errback();
-			return;
-		}
-		
-		// Render the result set
-		Deferred.when(self.renderArray(results, preloadNode, options), function(trs){
-			var total = typeof results.total === "undefined" ?
-				results.length : results.total;
-			return Deferred.when(total, function(total){
-				var trCount = trs.length,
-					parentNode = preloadNode.parentNode,
-					noDataNode = self.noDataNode;
-				
-				put(loadingNode, "!");
-				if(!("queryLevel" in options)){
-					self._total = total;
-				}
-				// now we need to adjust the height and total count based on the first result set
-				if(total === 0){
-					if(noDataNode){
-						put(noDataNode, "!");
-						delete self.noDataNode;
-					}
-					self.noDataNode = noDataNode = put("div.dgrid-no-data");
-					parentNode.insertBefore(noDataNode, self._getFirstRowSibling(parentNode));
-					noDataNode.innerHTML = self.noDataMessage;
-				}
-				var height = 0;
-				for(var i = 0; i < trCount; i++){
-					height += self._calcRowHeight(trs[i]);
-				}
-				// only update rowHeight if we actually got results and are visible
-				if(trCount && height){ self.rowHeight = height / trCount; }
-				
-				total -= trCount;
-				preload.count = total;
-				preloadNode.rowIndex = trCount;
-				if(total){
-					preloadNode.style.height = Math.min(total * self.rowHeight, self.maxEmptySpace) + "px";
-				}else{
-					// if total is 0, IE quirks mode can't handle 0px height for some reason, I don't know why, but we are setting display: none for now
-					preloadNode.style.display = "none";
-				}
-				
-				if (self._previousScrollPosition) {
-					// Restore position after a refresh operation w/ keepScrollPosition
-					self.scrollTo(self._previousScrollPosition);
-					delete self._previousScrollPosition;
-				}
-				
-				// Redo scroll processing in case the query didn't fill the screen,
-				// or in case scroll position was restored
-				self._processScroll();
-				
-				// If _refreshDeferred is still defined after calling _processScroll,
-				// resolve it now (_processScroll will remove it and resolve it itself
-				// otherwise)
-				if(self._refreshDeferred){
-					self._refreshDeferred.resolve(results);
-					delete self._refreshDeferred;
-				}
-				
-				return trs;
-			}, errback);
-		}, errback);
-		
-		return results;
-	},
-	
-	refresh: function(options){
-		// summary:
-		//		Refreshes the contents of the grid.
-		// options: Object?
-		//		Optional object, supporting the following parameters:
-		//		* keepScrollPosition: like the keepScrollPosition instance property;
-		//			specifying it in the options here will override the instance
-		//			property's value for this specific refresh call only.
-		
-		var self = this,
-			keep = (options && options.keepScrollPosition),
-			dfd, results;
-		
-		// Fall back to instance property if option is not defined
-		if(typeof keep === "undefined"){ keep = this.keepScrollPosition; }
-		
-		// Store scroll position to be restored after new total is received
-		if(keep){ this._previousScrollPosition = this.getScrollPosition(); }
-		
-		this.inherited(arguments);
-		if(this.store){
-			// render the query
-			dfd = this._refreshDeferred = new Deferred();
-			
-			// renderQuery calls _trackError internally
-			results = self.renderQuery(function(queryOptions){
-				return self.store.query(self.query, queryOptions);
-			});
-			if(typeof results === "undefined"){
-				// Synchronous error occurred; reject the refresh promise.
-				dfd.reject();
-			}
-			
-			// Internally, _refreshDeferred will always be resolved with an object
-			// containing `results` (QueryResults) and `rows` (the rendered rows);
-			// externally the promise will resolve simply with the QueryResults, but
-			// the event will be emitted with both under respective properties.
-			return dfd.then(function(results){
-				// Emit on a separate turn to enable event to be used consistently for
-				// initial render, regardless of whether the backing store is async
-				setTimeout(function() {
-					listen.emit(self.domNode, "dgrid-refresh-complete", {
-						bubbles: true,
-						cancelable: false,
-						grid: self,
-						results: results // QueryResults object (may be a wrapped promise)
-					});
-				}, 0);
-				
-				// Delete the Deferred immediately so nothing tries to re-resolve
-				delete self._refreshDeferred;
-				
-				// Resolve externally with just the QueryResults
-				return results;
-			}, function(err){
-				delete self._refreshDeferred;
-				throw err;
-			});
-		}
-	},
-	
-	resize: function(){
-		this.inherited(arguments);
-		this._processScroll();
-	},
-
-	_getFirstRowSibling: function(container){
-		// summary:
-		//		Returns the DOM node that a new row should be inserted before
-		//		when there are no other rows in the current result set.
-		//		In the case of OnDemandList, this will always be the last child
-		//		of the container (which will be a trailing preload node).
-		return container.lastChild;
-	},
-	
-	_calcRowHeight: function(rowElement){
-		// summary:
-		//		Calculate the height of a row. This is a method so it can be overriden for
-		//		plugins that add connected elements to a row, like the tree
-		
-		var sibling = rowElement.previousSibling;
-		sibling = sibling && !/\bdgrid-preload\b/.test(sibling.className) && sibling;
-		
-		// If a previous row exists, compare the top of this row with the
-		// previous one (in case "rows" are actually rendering side-by-side).
-		// If no previous row exists, this is either the first or only row,
-		// in which case we count its own height.
-		return sibling ? rowElement.offsetTop - sibling.offsetTop :
-			rowElement.offsetHeight;
-	},
-	
-	lastScrollTop: 0,
-	_processScroll: function(evt){
-		// summary:
-		//		Checks to make sure that everything in the viewable area has been
-		//		downloaded, and triggering a request for the necessary data when needed.
-		var grid = this,
-			scrollNode = grid.bodyNode,
-			// grab current visible top from event if provided, otherwise from node
-			visibleTop = (evt && evt.scrollTop) || this.getScrollPosition().y,
-			visibleBottom = scrollNode.offsetHeight + visibleTop,
-			priorPreload, preloadNode, preload = grid.preload,
-			lastScrollTop = grid.lastScrollTop,
-			requestBuffer = grid.bufferRows * grid.rowHeight,
-			searchBuffer = requestBuffer - grid.rowHeight, // Avoid rounding causing multiple queries
-			// References related to emitting dgrid-refresh-complete if applicable
-			refreshDfd,
-			lastResults,
-			lastRows,
-			preloadSearchNext = true;
-		
-		// XXX: I do not know why this happens.
-		// munging the actual location of the viewport relative to the preload node by a few pixels in either
-		// direction is necessary because at least WebKit on Windows seems to have an error that causes it to
-		// not quite get the entire element being focused in the viewport during keyboard navigation,
-		// which means it becomes impossible to load more data using keyboard navigation because there is
-		// no more data to scroll to to trigger the fetch.
-		// 1 is arbitrary and just gets it to work correctly with our current test cases; don’t wanna go
-		// crazy and set it to a big number without understanding more about what is going on.
-		// wondering if it has to do with border-box or something, but changing the border widths does not
-		// seem to make it break more or less, so I do not know…
-		var mungeAmount = 1;
-		
-		grid.lastScrollTop = visibleTop;
-
-		function removeDistantNodes(preload, distanceOff, traversal, below){
-			// we check to see the the nodes are "far off"
-			var farOffRemoval = grid.farOffRemoval,
-				preloadNode = preload.node;
-			// by checking to see if it is the farOffRemoval distance away
-			if(distanceOff > 2 * farOffRemoval){
-				// ok, there is preloadNode that is far off, let's remove rows until we get to in the current viewpoint
-				var row, nextRow = preloadNode[traversal];
-				var reclaimedHeight = 0;
-				var count = 0;
-				var toDelete = [];
-				while((row = nextRow)){
-					var rowHeight = grid._calcRowHeight(row);
-					if(reclaimedHeight + rowHeight + farOffRemoval > distanceOff || (nextRow.className.indexOf("dgrid-row") < 0 && nextRow.className.indexOf("dgrid-loading") < 0)){
-						// we have reclaimed enough rows or we have gone beyond grid rows, let's call it good
-						break;
-					}
-					var nextRow = row[traversal]; // have to do this before removing it
-					reclaimedHeight += rowHeight;
-					count += row.count || 1;
-					// we just do cleanup here, as we will do a more efficient node destruction in the setTimeout below
-					grid.removeRow(row, true);
-					toDelete.push(row);
-				}
-				// now adjust the preloadNode based on the reclaimed space
-				preload.count += count;
-				if(below){
-					preloadNode.rowIndex -= count;
-					adjustHeight(preload);
-				}else{
-					// if it is above, we can calculate the change in exact row changes, which we must do to not mess with the scrolling
-					preloadNode.style.height = (preloadNode.offsetHeight + reclaimedHeight) + "px";
-				}
-				// we remove the elements after expanding the preload node so that the contraction doesn't alter the scroll position
-				var trashBin = put("div", toDelete);
-				setTimeout(function(){
-					// we can defer the destruction until later
-					put(trashBin, "!");
-				},1);
-			}
-		}
-		
-		function adjustHeight(preload, noMax){
-			preload.node.style.height = Math.min(preload.count * grid.rowHeight, noMax ? Infinity : grid.maxEmptySpace) + "px";
-		}
-		function traversePreload(preload, moveNext){
-			do{
-				preload = moveNext ? preload.next : preload.previous;
-			}while(preload && !preload.node.offsetWidth);// skip past preloads that are not currently connected
-			return preload;
-		}
-		while(preload && !preload.node.offsetWidth){
-			// skip past preloads that are not currently connected
-			preload = preload.previous;
-		}
-		// there can be multiple preloadNodes (if they split, or multiple queries are created),
-		//	so we can traverse them until we find whatever is in the current viewport, making
-		//	sure we don't backtrack
-		while(preload && preload != priorPreload){
-			priorPreload = grid.preload;
-			grid.preload = preload;
-			preloadNode = preload.node;
-			var preloadTop = preloadNode.offsetTop;
-			var preloadHeight;
-			
-			if(visibleBottom + mungeAmount + searchBuffer < preloadTop){
-				// the preload is below the line of sight
-				preload = traversePreload(preload, (preloadSearchNext = false));
-			}else if(visibleTop - mungeAmount - searchBuffer > (preloadTop + (preloadHeight = preloadNode.offsetHeight))){
-				// the preload is above the line of sight
-				preload = traversePreload(preload, (preloadSearchNext = true));
-			}else{
-				// the preload node is visible, or close to visible, better show it
-				var offset = ((preloadNode.rowIndex ? visibleTop - requestBuffer : visibleBottom) - preloadTop) / grid.rowHeight;
-				var count = (visibleBottom - visibleTop + 2 * requestBuffer) / grid.rowHeight;
-				// utilize momentum for predictions
-				var momentum = Math.max(Math.min((visibleTop - lastScrollTop) * grid.rowHeight, grid.maxRowsPerPage/2), grid.maxRowsPerPage/-2);
-				count += Math.min(Math.abs(momentum), 10);
-				if(preloadNode.rowIndex == 0){
-					// at the top, adjust from bottom to top
-					offset -= count;
-				}
-				offset = Math.max(offset, 0);
-				if(offset < 10 && offset > 0 && count + offset < grid.maxRowsPerPage){
-					// connect to the top of the preloadNode if possible to avoid excessive adjustments
-					count += Math.max(0, offset);
-					offset = 0;
-				}
-				count = Math.min(Math.max(count, grid.minRowsPerPage),
-									grid.maxRowsPerPage, preload.count);
-				
-				if(count == 0){
-					preload = traversePreload(preload, preloadSearchNext);
-					continue;
-				}
-				
-				count = Math.ceil(count);
-				offset = Math.min(Math.floor(offset), preload.count - count);
-				var options = lang.mixin(grid.get("queryOptions"), preload.options);
-				preload.count -= count;
-				var beforeNode = preloadNode,
-					keepScrollTo, queryRowsOverlap = grid.queryRowsOverlap,
-					below = preloadNode.rowIndex > 0 && preload; 
-				if(below){
-					// add new rows below
-					var previous = preload.previous;
-					if(previous){
-						removeDistantNodes(previous, visibleTop - (previous.node.offsetTop + previous.node.offsetHeight), 'nextSibling');
-						if(offset > 0 && previous.node == preloadNode.previousSibling){
-							// all of the nodes above were removed
-							offset = Math.min(preload.count, offset);
-							preload.previous.count += offset;
-							adjustHeight(preload.previous, true);
-							preloadNode.rowIndex += offset;
-							queryRowsOverlap = 0;
-						}else{
-							count += offset;
-						}
-						preload.count -= offset;
-					}
-					options.start = preloadNode.rowIndex - queryRowsOverlap;
-					options.count = Math.min(count + queryRowsOverlap, grid.maxRowsPerPage);
-					preloadNode.rowIndex = options.start + options.count;
-				}else{
-					// add new rows above
-					if(preload.next){
-						// remove out of sight nodes first
-						removeDistantNodes(preload.next, preload.next.node.offsetTop - visibleBottom, 'previousSibling', true);
-						var beforeNode = preloadNode.nextSibling;
-						if(beforeNode == preload.next.node){
-							// all of the nodes were removed, can position wherever we want
-							preload.next.count += preload.count - offset;
-							preload.next.node.rowIndex = offset + count;
-							adjustHeight(preload.next);
-							preload.count = offset;
-							queryRowsOverlap = 0;
-						}else{
-							keepScrollTo = true;
-						}
-						
-					}
-					options.start = preload.count;
-					options.count = Math.min(count + queryRowsOverlap, grid.maxRowsPerPage);
-				}
-				if(keepScrollTo && beforeNode && beforeNode.offsetWidth){
-					keepScrollTo = beforeNode.offsetTop;
-				}
-
-				adjustHeight(preload);
-				// create a loading node as a placeholder while the data is loaded
-				var loadingNode = put(beforeNode, "-div.dgrid-loading[style=height:" + count * grid.rowHeight + "px]"),
-					innerNode = put(loadingNode, "div.dgrid-" + (below ? "below" : "above"));
-				innerNode.innerHTML = grid.loadingMessage;
-				loadingNode.count = count;
-				// use the query associated with the preload node to get the next "page"
-				if("level" in preload.query){
-					options.queryLevel = preload.query.level;
-				}
-				
-				// Avoid spurious queries (ideally this should be unnecessary...)
-				if(!("queryLevel" in options) && (options.start > grid._total || options.count < 0)){
-					continue;
-				}
-				
-				// Query now to fill in these rows.
-				// Keep _trackError-wrapped results separate, since if results is a
-				// promise, it will lose QueryResults functions when chained by `when`
-				var results = preload.query(options),
-					trackedResults = grid._trackError(function(){ return results; });
-				
-				if(trackedResults === undefined){
-					// Sync query failed
-					put(loadingNode, "!");
-					return;
-				}
-
-				// Isolate the variables in case we make multiple requests
-				// (which can happen if we need to render on both sides of an island of already-rendered rows)
-				(function(loadingNode, scrollNode, below, keepScrollTo, results){
-					lastRows = Deferred.when(grid.renderArray(results, loadingNode, options), function(rows){
-						lastResults = results;
-						
-						// can remove the loading node now
-						beforeNode = loadingNode.nextSibling;
-						put(loadingNode, "!");
-						if(keepScrollTo && beforeNode && beforeNode.offsetWidth){ // beforeNode may have been removed if the query results loading node was a removed as a distant node before rendering 
-							// if the preload area above the nodes is approximated based on average
-							// row height, we may need to adjust the scroll once they are filled in
-							// so we don't "jump" in the scrolling position
-							var pos = grid.getScrollPosition();
-							grid.scrollTo({
-								// Since we already had to query the scroll position,
-								// include x to avoid TouchScroll querying it again on its end.
-								x: pos.x,
-								y: pos.y + beforeNode.offsetTop - keepScrollTo,
-								// Don't kill momentum mid-scroll (for TouchScroll only).
-								preserveMomentum: true
-							});
-						}
-						
-						Deferred.when(results.total || results.length, function(total){
-							if(!("queryLevel" in options)){
-								grid._total = total;
-							}
-							if(below){
-								// if it is below, we will use the total from the results to update
-								// the count of the last preload in case the total changes as later pages are retrieved
-								// (not uncommon when total counts are estimated for db perf reasons)
-								
-								// recalculate the count
-								below.count = total - below.node.rowIndex;
-								// readjust the height
-								adjustHeight(below);
-							}
-						});
-						
-						// make sure we have covered the visible area
-						grid._processScroll();
-						return rows;
-					}, function (e) {
-						put(loadingNode, "!");
-						throw e;
-					});
-				}).call(this, loadingNode, scrollNode, below, keepScrollTo, results);
-				preload = preload.previous;
-			}
-		}
-		
-		// After iterating, if additional requests have been made mid-refresh,
-		// resolve the refresh promise based on the latest results obtained
-		if (lastRows && (refreshDfd = this._refreshDeferred)) {
-			delete this._refreshDeferred;
-			Deferred.when(lastRows, function() {
-				refreshDfd.resolve(lastResults);
-			});
-		}
-	},
-
-	removeRow: function(rowElement, justCleanup){
-		function chooseIndex(index1, index2){
-			return index1 != null ? index1 : index2;
-		}
-
-		if(rowElement){
-			// Clean up observers that need to be cleaned up.
-			var previousNode = rowElement.previousSibling,
-				nextNode = rowElement.nextSibling,
-				prevIndex = previousNode && chooseIndex(previousNode.observerIndex, previousNode.previousObserverIndex),
-				nextIndex = nextNode && chooseIndex(nextNode.observerIndex, nextNode.nextObserverIndex),
-				thisIndex = rowElement.observerIndex;
-
-			// Clear the observerIndex on the node being removed so it will not be considered any longer.
-			rowElement.observerIndex = undefined;
-			if(justCleanup){
-				// Save the indexes from the siblings for future calls to removeRow.
-				rowElement.nextObserverIndex = nextIndex;
-				rowElement.previousObserverIndex = prevIndex;
-			}
-
-			// Is this row's observer index different than those on either side?
-			if(this.cleanEmptyObservers && thisIndex > -1 && thisIndex !== prevIndex && thisIndex !== nextIndex){
-				// This is the last row that references the observer index.  Cancel the observer.
-				var observers = this.observers;
-				var observer = observers[thisIndex];
-				if(observer){
-					observer.cancel();
-					this._numObservers--;
-					observers[thisIndex] = 0; // remove it so we don't call cancel twice
-				}
-			}
-		}
-		// Finish the row removal.
-		this.inherited(arguments);
-	}
-});
-
-});

+ 0 - 136
esp/files/dgrid/README.md

@@ -1,136 +0,0 @@
-This project provides widgets for lists of data, including simple sets of scrolling rows,
-grids of data, on-demand lazy-loaded data, and various plugins for additional functionality. 
-This project also provides touch scrolling for mobile devices with native style
-momentum, bouncing, and scrollbars.
-
-The dgrid project is available under the same dual BSD/AFLv2 license as the Dojo Toolkit.
-
-# Installation
-
-## Automatic Download with CPM
-
-dgrid can be installed via [CPM](https://github.com/kriszyp/cpm)
-using the following command:
-
-    cpm install dgrid
-
-The above command will automatically find the highest tagged version of dgrid and
-install it.  Alternatively, the latest development version of dgrid can be
-installed by instructing CPM to install from the master branch:
-
-    cpm install dgrid master
-
-Note that while dgrid lists the dojo package as a dependency, it does not install
-dijit, as it is not a hard requirement.  Dijit can be additionally installed by
-running:
-
-    cpm install dijit
-
-## Manual Download
-
-Alternatively, dgrid and its dependencies can be downloaded individually:
-
-* [xstyle](https://github.com/kriszyp/xstyle)
-* [put-selector](https://github.com/kriszyp/put-selector)
-* [The Dojo Toolkit](http://dojotoolkit.org) SDK version 1.7 or higher
-    * Out of the DTK components, Dojo core is the only hard dependency for dgrid;
-      however, some of the test pages also use components from Dijit, and
-      Dojox (namely grid for a comparison test, and mobile for a mobile page).
-
-It is recommended to arrange all dependencies as siblings, resulting in a
-directory structure like the following:
-
-* `dgrid`
-* `dijit` (optional, dependency of some dgrid tests)
-* `dojo`
-* `dojox` (optional, dependency of some dgrid tests)
-* `put-selector`
-* `xstyle`
-* `util` (optional, e.g. if pursuing a custom build)
-
-dgrid works best with the latest revision of Dojo 1.7 or higher.  As of this
-writing, [Dojo 1.9.1](http://download.dojotoolkit.org/release-1.9.1/) is
-recommended.
-
-Note that while dgrid supports Dojo 1.8 and 1.9 and may take advantage of features
-or fix issues specific to them where possible, it does not have any hard dependency
-on APIs new to 1.8 or 1.9, so as to maintain compatibility with 1.7.
-
-# Documentation
-
-Documentation for dgrid components is available in the
-[dgrid GitHub project wiki](https://github.com/SitePen/dgrid/wiki).
-The wiki's content may still be obtained for offline reading by cloning
-the wiki repository, as indicated under the "Git Access" tab.
-
-In addition to the documentation on the wiki, if upgrading from a previous
-dgrid release, please be sure to read the changelog, found in CHANGES.md.
-
-# Testing
-
-dgrid uses [Intern](http://theintern.io/) as its test runner. Tests can
-either be run using the browser, or using [Sauce Labs](https://saucelabs.com/).
-More information on writing your own tests with Intern can be found in the
-[Intern wiki](https://github.com/theintern/intern/wiki). 
-
-## Setting up
-
-**Note:** Commands listed in this section are all written assuming they are
-run in the parent directory containing `dgrid`, `dojo`, etc.
-
-Install the latest *geezer* version of Intern, which supports IE 6, 7, and 8
-in addition to modern browsers.
-
-```
-npm install intern-geezer
-```
-
-## Running via the browser
-
-1. Open a browser to http://hostname/path_to_dgrid/test/intern/runTests.html
-2. View the console
-
-## Running via Sauce Labs
-
-Make sure the proper Sauce Labs credentials are set in the environment:
-
-```
-export SAUCE_USERNAME=<your_sauce_username>
-export SAUCE_ACCESS_KEY=<your_sauce_access_key>
-```
-
-Then kick off the runner with the following command:
-
-```
-node node_modules/intern-geezer/runner config=dgrid/test/intern/intern
-```
-
-# Community
-
-## Reporting Issues
-
-Bugs or enhancements can be filed by opening an issue in the
-[issue tracker on GitHub](https://github.com/SitePen/dgrid/issues?state=open).
-
-When reporting a bug, please provide the following information:
-
-* Affected browsers and Dojo versions
-* A clear list of steps to reproduce the problem
-* If the problem cannot be easily reproduced in an existing dgrid test page,
-  include a [Gist](https://gist.github.com/) with code for a page containing a
-  reduced test case
-
-If you would like to suggest a fix for a particular issue, you are welcome to
-fork dgrid, create a branch, and submit a pull request.  Please note that a
-[Dojo CLA](http://www.dojofoundation.org/about/cla) is required for any
-non-trivial modifications.
-
-## Getting Support
-
-Questions about dgrid usage can be discussed on the
-[dojo-interest mailing list](http://mail.dojotoolkit.org/mailman/listinfo/dojo-interest)
-or in the #dojo IRC channel on irc.freenode.net. Web interfaces are available
-from the [Dojo Toolkit Community page](https://dojotoolkit.org/community/).
-
-SitePen also offers [commercial support](https://www.sitepen.com/support/)
-for dgrid, as well as Dojo and a number of other JavaScript libraries.

+ 0 - 615
esp/files/dgrid/Selection.js

@@ -1,615 +0,0 @@
-define(["dojo/_base/kernel", "dojo/_base/declare", "dojo/_base/Deferred", "dojo/on", "dojo/has", "dojo/aspect", "./List", "dojo/has!touch?./util/touch", "put-selector/put", "dojo/query", "dojo/_base/sniff"],
-function(kernel, declare, Deferred, on, has, aspect, List, touchUtil, put){
-
-has.add("mspointer", function(global, doc, element){
-	return "onmspointerdown" in element;
-});
-
-// Add feature test for user-select CSS property for optionally disabling
-// text selection.
-// (Can't use dom.setSelectable prior to 1.8.2 because of bad sniffs, see #15990)
-has.add("css-user-select", function(global, doc, element){
-	var style = element.style,
-		prefixes = ["Khtml", "O", "ms", "Moz", "Webkit"],
-		i = prefixes.length,
-		name = "userSelect";
-
-	// Iterate prefixes from most to least likely
-	do{
-		if(typeof style[name] !== "undefined"){
-			// Supported; return property name
-			return name;
-		}
-	}while(i-- && (name = prefixes[i] + "UserSelect"));
-
-	// Not supported if we didn't return before now
-	return false;
-});
-
-// Also add a feature test for the onselectstart event, which offers a more
-// graceful fallback solution than node.unselectable.
-has.add("dom-selectstart", typeof document.onselectstart !== "undefined");
-
-var ctrlEquiv = has("mac") ? "metaKey" : "ctrlKey",
-	hasUserSelect = has("css-user-select"),
-	downType = has("mspointer") ? "MSPointerDown" : "mousedown",
-	upType = has("mspointer") ? "MSPointerUp" : "mouseup";
-
-function makeUnselectable(node, unselectable){
-	// Utility function used in fallback path for recursively setting unselectable
-	var value = node.unselectable = unselectable ? "on" : "",
-		elements = node.getElementsByTagName("*"),
-		i = elements.length;
-	
-	while(--i){
-		if(elements[i].tagName === "INPUT" || elements[i].tagName === "TEXTAREA"){
-			continue; // Don't prevent text selection in text input fields.
-		}
-		elements[i].unselectable = value;
-	}
-}
-
-function setSelectable(grid, selectable){
-	// Alternative version of dojo/dom.setSelectable based on feature detection.
-	
-	// For FF < 21, use -moz-none, which will respect -moz-user-select: text on
-	// child elements (e.g. form inputs).  In FF 21, none behaves the same.
-	// See https://developer.mozilla.org/en-US/docs/CSS/user-select
-	var node = grid.bodyNode,
-		value = selectable ? "text" : has("ff") < 21 ? "-moz-none" : "none";
-	
-	if(hasUserSelect){
-		node.style[hasUserSelect] = value;
-	}else if(has("dom-selectstart")){
-		// For browsers that don't support user-select but support selectstart (IE<10),
-		// we can hook up an event handler as necessary.  Since selectstart bubbles,
-		// it will handle any child elements as well.
-		// Note, however, that both this and the unselectable fallback below are
-		// incapable of preventing text selection from outside the targeted node.
-		if(!selectable && !grid._selectstartHandle){
-			grid._selectstartHandle = on(node, "selectstart", function(evt){
-				var tag = evt.target && evt.target.tagName;
-				
-				// Prevent selection except where a text input field is involved.
-				if(tag !== "INPUT" && tag !== "TEXTAREA"){
-					evt.preventDefault();
-				}
-			});
-		}else if(selectable && grid._selectstartHandle){
-			grid._selectstartHandle.remove();
-			delete grid._selectstartHandle;
-		}
-	}else{
-		// For browsers that don't support either user-select or selectstart (Opera),
-		// we need to resort to setting the unselectable attribute on all nodes
-		// involved.  Since this doesn't automatically apply to child nodes, we also
-		// need to re-apply it whenever rows are rendered.
-		makeUnselectable(node, !selectable);
-		if(!selectable && !grid._unselectableHandle){
-			grid._unselectableHandle = aspect.after(grid, "renderRow", function(row){
-				makeUnselectable(row, true);
-				return row;
-			});
-		}else if(selectable && grid._unselectableHandle){
-			grid._unselectableHandle.remove();
-			delete grid._unselectableHandle;
-		}
-	}
-}
-
-return declare(null, {
-	// summary:
-	//		Add selection capabilities to a grid. The grid will have a selection property and
-	//		fire "dgrid-select" and "dgrid-deselect" events.
-	
-	// selectionDelegate: String
-	//		Selector to delegate to as target of selection events.
-	selectionDelegate: ".dgrid-row",
-	
-	// selectionEvents: String
-	//		Event (or events, comma-delimited) to listen on to trigger select logic.
-	//		Note: this is ignored in the case of touch devices.
-	selectionEvents: downType + "," + upType + ",dgrid-cellfocusin",
-	
-	// deselectOnRefresh: Boolean
-	//		If true, the selection object will be cleared when refresh is called.
-	deselectOnRefresh: true,
-	
-	// allowSelectAll: Boolean
-	//		If true, allow ctrl/cmd+A to select all rows.
-	//		Also consulted by the selector plugin for showing select-all checkbox.
-	allowSelectAll: false,
-	
-	// selection:
-	//		An object where the property names correspond to 
-	//		object ids and values are true or false depending on whether an item is selected
-	selection: {},
-	
-	// selectionMode: String
-	//		The selection mode to use, can be "none", "multiple", "single", or "extended".
-	selectionMode: "extended",
-	
-	// allowTextSelection: Boolean
-	//		Whether to still allow text within cells to be selected.  The default
-	//		behavior is to allow text selection only when selectionMode is none;
-	//		setting this property to either true or false will explicitly set the
-	//		behavior regardless of selectionMode.
-	allowTextSelection: undefined,
-	
-	// _selectionTargetType: String
-	//		Indicates the property added to emitted events for selected targets;
-	//		overridden in CellSelection
-	_selectionTargetType: "rows",
-	
-	create: function(){
-		this.selection = {};
-		return this.inherited(arguments);
-	},
-	postCreate: function(){
-		this.inherited(arguments);
-		
-		this._initSelectionEvents();
-		
-		// Force selectionMode setter to run
-		var selectionMode = this.selectionMode;
-		this.selectionMode = "";
-		this._setSelectionMode(selectionMode);
-	},
-	
-	destroy: function(){
-		this.inherited(arguments);
-		
-		// Remove any extra handles added by Selection.
-		if(this._selectstartHandle){ this._selectstartHandle.remove(); }
-		if(this._unselectableHandle){ this._unselectableHandle.remove(); }
-		if(this._removeDeselectSignals){ this._removeDeselectSignals(); }
-	},
-	
-	_setSelectionMode: function(mode){
-		// summary:
-		//		Updates selectionMode, resetting necessary variables.
-		if(mode == this.selectionMode){ return; } // prevent unnecessary spinning
-		
-		// Start selection fresh when switching mode.
-		this.clearSelection();
-		
-		this.selectionMode = mode;
-		
-		// Compute name of selection handler for this mode once
-		// (in the form of _fooSelectionHandler)
-		this._selectionHandlerName = "_" + mode + "SelectionHandler";
-		
-		// Also re-run allowTextSelection setter in case it is in automatic mode.
-		this._setAllowTextSelection(this.allowTextSelection);
-	},
-	setSelectionMode: function(mode){
-		kernel.deprecated("setSelectionMode(...)", 'use set("selectionMode", ...) instead', "dgrid 0.4");
-		this.set("selectionMode", mode);
-	},
-	
-	_setAllowTextSelection: function(allow){
-		if(typeof allow !== "undefined"){
-			setSelectable(this, allow);
-		}else{
-			setSelectable(this, this.selectionMode === "none");
-		}
-		this.allowTextSelection = allow;
-	},
-	
-	_handleSelect: function(event, target){
-		// Don't run if selection mode doesn't have a handler (incl. "none"),
-		// or if coming from a dgrid-cellfocusin from a mousedown
-		if(!this[this._selectionHandlerName] ||
-				(event.type === "dgrid-cellfocusin" && event.parentType === "mousedown") ||
-				(event.type === upType && target != this._waitForMouseUp)){
-			return;
-		}
-		this._waitForMouseUp = null;
-		this._selectionTriggerEvent = event;
-		
-		// Don't call select handler for ctrl+navigation
-		if(!event.keyCode || !event.ctrlKey || event.keyCode == 32){
-			// If clicking a selected item, wait for mouseup so that drag n' drop
-			// is possible without losing our selection
-			if(!event.shiftKey && event.type === downType && this.isSelected(target)){
-				this._waitForMouseUp = target;
-			}else{
-				this[this._selectionHandlerName](event, target);
-			}
-		}
-		this._selectionTriggerEvent = null;
-	},
-	
-	_singleSelectionHandler: function(event, target){
-		// summary:
-		//		Selection handler for "single" mode, where only one target may be
-		//		selected at a time.
-		
-		var ctrlKey = event.keyCode ? event.ctrlKey : event[ctrlEquiv];
-		if(this._lastSelected === target){
-			// Allow ctrl to toggle selection, even within single select mode.
-			this.select(target, null, !ctrlKey || !this.isSelected(target));
-		}else{
-			this.clearSelection();
-			this.select(target);
-			this._lastSelected = target;
-		}
-	},
-	
-	_multipleSelectionHandler: function(event, target){
-		// summary:
-		//		Selection handler for "multiple" mode, where shift can be held to
-		//		select ranges, ctrl/cmd can be held to toggle, and clicks/keystrokes
-		//		without modifier keys will add to the current selection.
-		
-		var lastRow = this._lastSelected,
-			ctrlKey = event.keyCode ? event.ctrlKey : event[ctrlEquiv],
-			value;
-		
-		if(!event.shiftKey){
-			// Toggle if ctrl is held; otherwise select
-			value = ctrlKey ? null : true;
-			lastRow = null;
-		}
-		this.select(target, lastRow, value);
-
-		if(!lastRow){
-			// Update reference for potential subsequent shift+select
-			// (current row was already selected above)
-			this._lastSelected = target;
-		}
-	},
-	
-	_extendedSelectionHandler: function(event, target){
-		// summary:
-		//		Selection handler for "extended" mode, which is like multiple mode
-		//		except that clicks/keystrokes without modifier keys will clear
-		//		the previous selection.
-		
-		// Clear selection first for right-clicks outside selection and non-ctrl-clicks;
-		// otherwise, extended mode logic is identical to multiple mode
-		if(event.button === 2 ? !this.isSelected(target) :
-				!(event.keyCode ? event.ctrlKey : event[ctrlEquiv])){
-			this.clearSelection(null, true);
-		}
-		this._multipleSelectionHandler(event, target);
-	},
-	
-	_toggleSelectionHandler: function(event, target){
-		// summary:
-		//		Selection handler for "toggle" mode which simply toggles the selection
-		//		of the given target.  Primarily useful for touch input.
-		
-		this.select(target, null, null);
-	},
-
-	_initSelectionEvents: function(){
-		// summary:
-		//		Performs first-time hookup of event handlers containing logic
-		//		required for selection to operate.
-		
-		var grid = this,
-			selector = this.selectionDelegate;
-		
-		this._selectionEventQueues = {
-			deselect: [],
-			select: []
-		};
-		
-		if(has("touch") && !has("mspointer")){
-			// listen for touch taps if available
-			on(this.contentNode, touchUtil.selector(selector, touchUtil.tap), function(evt){
-				grid._handleSelect(evt, this);
-			});
-		}else{
-			// listen for actions that should cause selections
-			on(this.contentNode, on.selector(selector, this.selectionEvents), function(event){
-				grid._handleSelect(event, this);
-			});
-		}
-		
-		// Also hook up spacebar (for ctrl+space)
-		if(this.addKeyHandler){
-			this.addKeyHandler(32, function(event){
-				grid._handleSelect(event, event.target);
-			});
-		}
-		
-		// If allowSelectAll is true, bind ctrl/cmd+A to (de)select all rows,
-		// unless the event was received from an editor component.
-		// (Handler further checks against _allowSelectAll, which may be updated
-		// if selectionMode is changed post-init.)
-		if(this.allowSelectAll){
-			this.on("keydown", function(event) {
-				if(event[ctrlEquiv] && event.keyCode == 65 &&
-						!/\bdgrid-input\b/.test(event.target.className)){
-					event.preventDefault();
-					grid[grid.allSelected ? "clearSelection" : "selectAll"]();
-				}
-			});
-		}
-		
-		// Update aspects if there is a store change
-		if(this._setStore){
-			aspect.after(this, "_setStore", function(){
-				grid._updateDeselectionAspect();
-			});
-		}
-		this._updateDeselectionAspect();
-	},
-	
-	_updateDeselectionAspect: function(){
-		// summary:
-		//		Hooks up logic to handle deselection of removed items.
-		//		Aspects to an observable store's notify method if applicable,
-		//		or to the list/grid's removeRow method otherwise.
-		
-		var self = this,
-			store = this.store,
-			beforeSignal,
-			afterSignal;
-
-		function ifSelected(object, idToUpdate, methodName){
-			// Calls a method if the row corresponding to the object is selected.
-			var id = idToUpdate || (object && object[self.idProperty || "id"]);
-			if(id != null){
-				var row = self.row(id),
-					selection = row && self.selection[row.id];
-				// Is the row currently in the selection list.
-				if(selection){
-					self[methodName](row, null, selection);
-				}
-			}
-		}
-		
-		// Remove anything previously configured
-		if(this._removeDeselectSignals){
-			this._removeDeselectSignals();
-		}
-
-		// Is there currently an observable store?
-		if(store && store.notify){
-			beforeSignal = aspect.before(store, "notify", function(object, idToUpdate){
-				if(!object){
-					// Call deselect on the row if the object is being removed.  This allows the
-					// deselect event to reference the row element while it still exists in the DOM.
-					ifSelected(object, idToUpdate, "deselect");
-				}
-			});
-			afterSignal = aspect.after(store, "notify", function(object, idToUpdate){
-				// When List updates an item, the row element is removed and a new one inserted.
-				// If at this point the object is still in grid.selection, then call select on the row so the
-				// element's CSS is updated.  If the object was removed then the aspect-before has already deselected it.
-				ifSelected(object, idToUpdate, "select");
-			}, true);
-			
-			this._removeDeselectSignals = function(){
-				beforeSignal.remove();
-				afterSignal.remove();
-			};
-		}else{
-			beforeSignal = aspect.before(this, "removeRow", function(rowElement, justCleanup){
-				var row;
-				if(!justCleanup){
-					row = this.row(rowElement);
-					// if it is a real row removal for a selected item, deselect it
-					if(row && (row.id in this.selection)){
-						this.deselect(row);
-					}
-				}
-			});
-			this._removeDeselectSignals = function(){
-				beforeSignal.remove();
-			};
-		}
-	},
-	
-	allowSelect: function(row){
-		// summary:
-		//		A method that can be overriden to determine whether or not a row (or 
-		//		cell) can be selected. By default, all rows (or cells) are selectable.
-		return true;
-	},
-	
-	_fireSelectionEvent: function(type){
-		// summary:
-		//		Fires an event for the accumulated rows once a selection
-		//		operation is finished (whether singular or for a range)
-		
-		var queue = this._selectionEventQueues[type],
-			triggerEvent = this._selectionTriggerEvent,
-			eventObject;
-		
-		eventObject = {
-			bubbles: true,
-			grid: this
-		};
-		if(triggerEvent){
-			eventObject.parentType = triggerEvent.type;
-		}
-		eventObject[this._selectionTargetType] = queue;
-		
-		on.emit(this.contentNode, "dgrid-" + type, eventObject);
-		
-		// Clear the queue so that the next round of (de)selections starts anew
-		this._selectionEventQueues[type] = [];
-	},
-	
-	_fireSelectionEvents: function(){
-		var queues = this._selectionEventQueues,
-			type;
-		
-		for(type in queues){
-			if(queues[type].length){
-				this._fireSelectionEvent(type);
-			}
-		}
-	},
-	
-	_select: function(row, toRow, value){
-		// summary:
-		//		Contains logic for determining whether to select targets, but
-		//		does not emit events.  Called from select, deselect, selectAll,
-		//		and clearSelection.
-		
-		var selection,
-			previousValue,
-			element,
-			toElement,
-			traverser;
-		
-		if(typeof value === "undefined"){
-			// default to true
-			value = true;
-		} 
-		if(!row.element){
-			row = this.row(row);
-		}
-		
-		// Check whether we're allowed to select the given row before proceeding.
-		// If a deselect operation is being performed, this check is skipped,
-		// to avoid errors when changing column definitions, and since disabled
-		// rows shouldn't ever be selected anyway.
-		if(value === false || this.allowSelect(row)){
-			selection = this.selection;
-			previousValue = selection[row.id];
-			if(value === null){
-				// indicates a toggle
-				value = !previousValue;
-			}
-			element = row.element;
-			if(!value && !this.allSelected){
-				delete this.selection[row.id];
-			}else{
-				selection[row.id] = value;
-			}
-			if(element){
-				// add or remove classes as appropriate
-				if(value){
-					put(element, ".dgrid-selected.ui-state-active");
-				}else{
-					put(element, "!dgrid-selected!ui-state-active");
-				}
-			}
-			if(value !== previousValue && element){
-				// add to the queue of row events
-				this._selectionEventQueues[(value ? "" : "de") + "select"].push(row);
-			}
-			
-			if(toRow){
-				if(!toRow.element){
-					toRow = this.row(toRow);
-				}
-				toElement = toRow.element;
-				// find if it is earlier or later in the DOM
-				traverser = (toElement && (toElement.compareDocumentPosition ? 
-					toElement.compareDocumentPosition(element) == 2 :
-					toElement.sourceIndex > element.sourceIndex)) ? "down" : "up";
-				while(row.element != toElement && (row = this[traverser](row))){
-					this._select(row, null, value);
-				}
-			}
-		}
-	},
-	
-	select: function(row, toRow, value){
-		// summary:
-		//		Selects or deselects the given row or range of rows.
-		// row: Mixed
-		//		Row object (or something that can resolve to one) to (de)select
-		// toRow: Mixed
-		//		If specified, the inclusive range between row and toRow will
-		//		be (de)selected
-		// value: Boolean|Null
-		//		Whether to select (true/default), deselect (false), or toggle
-		//		(null) the row
-		
-		this._select(row, toRow, value);
-		this._fireSelectionEvents();
-	},
-	deselect: function(row, toRow){
-		// summary:
-		//		Deselects the given row or range of rows.
-		// row: Mixed
-		//		Row object (or something that can resolve to one) to deselect
-		// toRow: Mixed
-		//		If specified, the inclusive range between row and toRow will
-		//		be deselected
-		
-		this.select(row, toRow, false);
-	},
-	
-	clearSelection: function(exceptId, dontResetLastSelected){
-		// summary:
-		//		Deselects any currently-selected items.
-		// exceptId: Mixed?
-		//		If specified, the given id will not be deselected.
-		
-		this.allSelected = false;
-		for(var id in this.selection){
-			if(exceptId !== id){
-				this._select(id, null, false);
-			}
-		}
-		if(!dontResetLastSelected){
-			this._lastSelected = null;
-		}
-		this._fireSelectionEvents();
-	},
-	selectAll: function(){
-		this.allSelected = true;
-		this.selection = {}; // we do this to clear out pages from previous sorts
-		for(var i in this._rowIdToObject){
-			var row = this.row(this._rowIdToObject[i]);
-			this._select(row.id, null, true);
-		}
-		this._fireSelectionEvents();
-	},
-	
-	isSelected: function(object){
-		// summary:
-		//		Returns true if the indicated row is selected.
-		
-		if(typeof object === "undefined" || object === null){
-			return false;
-		}
-		if(!object.element){
-			object = this.row(object);
-		}
-		
-		// First check whether the given row is indicated in the selection hash;
-		// failing that, check if allSelected is true (testing against the
-		// allowSelect method if possible)
-		return (object.id in this.selection) ? !!this.selection[object.id] :
-			this.allSelected && (!object.data || this.allowSelect(object));
-	},
-	
-	refresh: function(){
-		if(this.deselectOnRefresh){
-			this.clearSelection();
-		}
-		this._lastSelected = null;
-		return this.inherited(arguments);
-	},
-	
-	renderArray: function(){
-		var grid = this,
-			rows = this.inherited(arguments);
-		
-		Deferred.when(rows, function(rows){
-			var selection = grid.selection,
-				i, row, selected;
-			for(i = 0; i < rows.length; i++){
-				row = grid.row(rows[i]);
-				selected = row.id in selection ? selection[row.id] : grid.allSelected;
-				if(selected){
-					grid._select(row, null, selected);
-				}
-			}
-			grid._fireSelectionEvents();
-		});
-		return rows;
-	}
-});
-
-});

+ 0 - 646
esp/files/dgrid/TouchScroll.js

@@ -1,646 +0,0 @@
-// FIXME:
-// * fully make use of transitions in glide routines
-
-define(["dojo/_base/declare", "dojo/on", "./util/touch", "./util/has-css3", "put-selector/put", "xstyle/css!./css/TouchScroll.css"],
-function(declare, on, touchUtil, has, put){
-	var
-		calcTimerRes = 50, // ms between drag velocity measurements
-		glideTimerRes = 30, // ms between glide animation ticks
-		current = {}, // records info for widget(s) currently being scrolled
-		previous = {}, // records info for widget(s) that were in the middle of being scrolled when someone decided to scroll again
-		glideThreshold = 1, // speed (in px) below which to stop glide - TODO: remove
-		scrollbarAdjustment = 8, // number of px to adjust scrollbar dimension calculations
-		// RegExps for parsing relevant x/y from translate and matrix values:
-		translateRx = /^translate(?:3d)?\((-?\d+)(?:\.\d*)?(?:px)?, (-?\d+)/,
-		matrixRx = /^matrix\(1, 0, 0, 1, (-?\d+)(?:\.\d*)?(?:px)?, (-?\d+)/,
-		// store has-features we need, for computing property/function names:
-		hasTransitions = has("css-transitions"),
-		hasTransitionEnd = has("transitionend"),
-		hasTransforms = has("css-transforms"),
-		hasTransforms3d = has("css-transforms3d"),
-		// and declare vars to store info on the properties/functions we'll need
-		cssPrefix, transitionPrefix, transformProp, translatePrefix, translateSuffix;
-	
-	if(hasTransforms3d){
-		translatePrefix = "translate3d(";
-		translateSuffix = ",0)";
-	}else if(hasTransforms){
-		translatePrefix = "translate(";
-		translateSuffix = ")";
-	}
-	
-	if(!hasTransitions || !translatePrefix){
-		console.warn("CSS3 features unavailable for touch scroll effects.");
-		return function(){};
-	}
-	
-	// figure out strings for use later in events
-	transformProp = hasTransforms3d || hasTransforms;
-	transformProp = transformProp === true ? "transform" : transformProp + "Transform";
-	transitionPrefix = hasTransitions === true ? "transition" :
-		hasTransitions + "Transition";
-	cssPrefix = hasTransforms === true ? "" :
-		"-" + hasTransforms.toLowerCase() + "-";
-	
-	function showScrollbars(widget, curr){
-		// Handles displaying of X/Y scrollbars as appropriate when a touchstart
-		// occurs.
-		
-		var node = widget.touchNode,
-			parentNode = node.parentNode,
-			adjustedParentWidth = parentNode.offsetWidth - scrollbarAdjustment,
-			adjustedParentHeight = parentNode.offsetHeight - scrollbarAdjustment,
-			// Also populate scroll/offset properties on curr for reuse,
-			// to avoid having to repeatedly hit the DOM.
-			scrollWidth = curr.scrollWidth = node.scrollWidth,
-			scrollHeight = curr.scrollHeight = node.scrollHeight,
-			parentWidth = curr.parentWidth = parentNode.offsetWidth,
-			parentHeight = curr.parentHeight = parentNode.offsetHeight,
-			scrollbarNode;
-		
-		if(scrollWidth > parentWidth){
-			if(!widget._scrollbarXNode){
-				scrollbarNode = put(parentNode, "div.touchscroll-x");
-			}
-			scrollbarNode = widget._scrollbarXNode =
-				widget._scrollbarXNode || put(scrollbarNode, "div.touchscroll-bar");
-			scrollbarNode.style.width =
-				adjustedParentWidth * adjustedParentWidth / scrollWidth + "px";
-			scrollbarNode.style.left = node.offsetLeft + "px";
-			put(parentNode, ".touchscroll-scrollable-x");
-			curr.scrollableX = true;
-		}else{
-			put(parentNode, "!touchscroll-scrollable-x");
-		}
-		if(scrollHeight > parentHeight){
-			if(!widget._scrollbarYNode){
-				scrollbarNode = put(parentNode, "div.touchscroll-y");
-			}
-			scrollbarNode = widget._scrollbarYNode =
-				widget._scrollbarYNode || put(scrollbarNode, "div.touchscroll-bar");
-			scrollbarNode.style.height =
-				adjustedParentHeight * adjustedParentHeight / scrollHeight + "px";
-			scrollbarNode.style.top = node.offsetTop + "px";
-			put(parentNode, ".touchscroll-scrollable-y");
-			curr.scrollableY = true;
-		}else{
-			put(parentNode, "!touchscroll-scrollable-y");
-		}
-		put(parentNode, "!touchscroll-fadeout");
-	}
-	
-	function scroll(widget, options){
-		// Handles updating of scroll position (from touchmove or glide).
-		var node = widget.touchNode,
-			curr = current[widget.id],
-			pos, hasX, hasY, x, y;
-		
-		if(typeof options !== "object"){
-			// Allow x, y to be passed directly w/o extra object creation.
-			// (e.g. from ontouchmove)
-			x = options;
-			y = arguments[2];
-			options = arguments[3];
-			hasX = hasY = true;
-		}else{
-			hasX = "x" in options;
-			hasY = "y" in options;
-			
-			// If either x or y weren't specified, pass through the current value.
-			if(!hasX || !hasY){
-				pos = widget.getScrollPosition();
-			}
-			x = hasX ? options.x : pos.x;
-			y = hasY ? options.y : pos.y;
-		}
-		
-		// Update transform on touchNode
-		node.style[transformProp] =
-			translatePrefix + -x + "px," + -y + "px" + translateSuffix;
-		
-		// Update scrollbar positions
-		if(curr && hasX && widget._scrollbarXNode){
-			widget._scrollbarXNode.style[transformProp] = translatePrefix +
-				(x * curr.parentWidth / curr.scrollWidth) + "px,0" + translateSuffix;
-		}
-		if(curr && hasY && widget._scrollbarYNode){
-			widget._scrollbarYNode.style[transformProp] = translatePrefix + "0," +
-				(y * curr.parentHeight / curr.scrollHeight) + "px" + translateSuffix;
-		}
-		
-		// Emit a scroll event that can be captured by handlers, passing along
-		// scroll information in the event itself (since we already have the info,
-		// and it'd be difficult to get from the node).
-		on.emit(widget.touchNode.parentNode, "scroll", {
-			scrollLeft: x,
-			scrollTop: y
-		});
-	}
-	
-	function getScrollStyle(widget){
-		// Returns match object for current scroll position based on transform.
-		if(current[widget.id]){
-			// Mid-transition: determine current X/Y from computed values.
-			return matrixRx.exec(window.getComputedStyle(widget.touchNode)[transformProp]);
-		}
-		// Otherwise, determine current X/Y from applied style.
-		return translateRx.exec(widget.touchNode.style[transformProp]);
-	}
-	
-	function resetEffects(options){
-		// Function to cut glide/bounce short, called in context of an object
-		// from the current hash; attached only when a glide or bounce occurs.
-		// Called on touchstart, when touch scrolling is canceled, when
-		// momentum/bounce finishes, and by scrollTo on instances (in case it's
-		// called directly during a glide/bounce).
-		
-		var widget = this.widget,
-			nodes = [this.node, widget._scrollbarXNode, widget._scrollbarYNode],
-			i = nodes.length;
-		
-		// Clear glide timer.
-		if(this.timer){
-			clearTimeout(this.timer);
-			this.timer = null;
-		}
-		
-		// Clear transition handlers, as we're about to cut it short.
-		if(this.transitionHandler){
-			// Unhook any existing transitionend handler, since we'll be
-			// canceling the transition.
-			this.transitionHandler.remove();
-			}
-		
-		// Clear transition duration on main node and scrollbars.
-		while(i--){
-			if(nodes[i]){ nodes[i].style[transitionPrefix + "Duration"] = "0"; }
-		}
-		
-		// Fade out scrollbars unless indicated otherwise (e.g. re-touch).
-		if(!options || !options.preserveScrollbars){
-			put(this.node.parentNode, ".touchscroll-fadeout");
-		}
-		
-		// Remove this method so it can't be called again.
-		delete this.resetEffects;
-	}
-	
-	// functions for handling touch events on node to be scrolled
-	
-	function ontouchstart(evt){
-		var widget = evt.widget,
-			node = widget.touchNode,
-			id = widget.id,
-			posX = 0,
-			posY = 0,
-			touch, match, curr;
-		
-		// Check touches count (which hasn't counted this event yet);
-		// ignore touch events on inappropriate number of contact points.
-		if(touchUtil.countCurrentTouches(evt, node) !== widget.touchesToScroll){
-			return;
-		}
-		
-		match = getScrollStyle(widget);
-		if(match){
-			posX = +match[1];
-			posY = +match[2];
-		}
-		if((curr = current[id])){
-			// stop any active glide or bounce, since it's been re-touched
-			if(curr.resetEffects){
-				curr.resetEffects({ preserveScrollbars: true });
-			}
-			
-			node.style[transformProp] =
-				translatePrefix + posX + "px," + posY + "px" + translateSuffix;
-			
-			previous[id] = curr;
-		}
-		
-		touch = evt.targetTouches[0];
-		curr = current[id] = {
-			widget: widget,
-			node: node,
-			// Subtract touch coords now, then add back later, so that translation
-			// goes further negative when moving upwards.
-			startX: posX - touch.pageX,
-			startY: posY - touch.pageY,
-			// Initialize lastX/Y, in case of a fast flick (< 1 full calc cycle).
-			lastX: posX,
-			lastY: posY,
-			// Also store original pageX/Y for threshold check.
-			pageX: touch.pageX,
-			pageY: touch.pageY,
-			tickFunc: function(){ calcTick(id); }
-		};
-		curr.timer = setTimeout(curr.tickFunc, calcTimerRes);
-	}
-	function ontouchmove(evt){
-		var widget = evt.widget,
-			id = widget.id,
-			touchesToScroll = widget.touchesToScroll,
-			curr = current[id],
-			activeTouches, targetTouches, touch, nx, ny, minX, minY, i;
-		
-		// Ignore touchmove events with inappropriate number of contact points.
-		if(!curr || (activeTouches = touchUtil.countCurrentTouches(evt, widget.touchNode)) !== touchesToScroll){
-			// Also cancel touch scrolling if there are too many contact points.
-			if(activeTouches > touchesToScroll){
-				widget.cancelTouchScroll();
-			}
-			return;
-		}
-		
-		targetTouches = evt.targetTouches;
-		touch = targetTouches[0];
-		
-		// Show touch scrollbars on first sign of drag.
-		if(!curr.scrollbarsShown){
-			if(previous[id] || (
-					Math.abs(touch.pageX - curr.pageX) > widget.scrollThreshold ||
-					Math.abs(touch.pageY - curr.pageY) > widget.scrollThreshold)){
-				showScrollbars(widget, curr);
-				curr.scrollbarsShown = true;
-				
-				// Add flag to involved touches to provide indication to other handlers.
-				for(i = targetTouches.length; i--;){
-					targetTouches[i].touchScrolled = true;
-				}
-			}
-		}
-		
-		if(curr.scrollbarsShown && (curr.scrollableX || curr.scrollableY)){
-			// If area can be scrolled, prevent default behavior and perform scroll.
-			evt.preventDefault();
-			
-			nx = curr.scrollableX ? curr.startX + touch.pageX : 0;
-			ny = curr.scrollableY ? curr.startY + touch.pageY : 0;
-			
-			minX = curr.scrollableX ? -(curr.scrollWidth - curr.parentWidth) : 0;
-			minY = curr.scrollableY ? -(curr.scrollHeight - curr.parentHeight) : 0;
-			
-			// If dragged beyond edge, halve the distance between.
-			if(nx > 0){
-				nx = nx / 2;
-			}else if(nx < minX){
-				nx = minX - (minX - nx) / 2;
-			}
-			if(ny > 0){
-				ny = ny / 2;
-			}else if(ny < minY){
-				ny = minY - (minY - ny) / 2;
-			}
-			
-			scroll(widget, -nx, -ny); // call scroll with positive coordinates
-		}
-	}
-	function ontouchend(evt){
-		var widget = evt.widget,
-			id = widget.id,
-			curr = current[id];
-		
-		if(!curr || touchUtil.countCurrentTouches(evt, widget.touchNode) != widget.touchesToScroll - 1){
-			return;
-		}
-		startGlide(id);
-	}
-	
-	// glide-related functions
-	
-	function calcTick(id){
-		// Calculates current speed of touch drag
-		var curr = current[id],
-			node, match, x, y;
-		
-		if(!curr){ return; } // no currently-scrolling widget; abort
-		
-		node = curr.node;
-		match = translateRx.exec(node.style[transformProp]);
-		
-		if(match){
-			x = +match[1];
-			y = +match[2];
-			
-			// If previous reference point already exists, calculate velocity
-			curr.velX = x - curr.lastX;
-			curr.velY = y - curr.lastY;
-			
-			// set previous reference point for future iteration or calculation
-			curr.lastX = x;
-			curr.lastY = y;
-		} else {
-			curr.lastX = curr.lastY = 0;
-		}
-		curr.timer = setTimeout(curr.tickFunc, calcTimerRes);
-	}
-	
-	function bounce(id, lastX, lastY){
-		// Function called when a scroll ends, to handle rubber-banding beyond edges.
-		var curr = current[id],
-			widget = curr.widget,
-			node = curr.node,
-			scrollbarNode,
-			x = curr.scrollableX ?
-				Math.max(Math.min(0, lastX), -(curr.scrollWidth - curr.parentWidth)) :
-				lastX,
-			y = curr.scrollableY ?
-				Math.max(Math.min(0, lastY), -(curr.scrollHeight - curr.parentHeight)) :
-				lastY;
-		
-		function end(){
-			// Performs reset operations upon end of scroll process.
-			
-			// Since transitions have run, delete transitionHandler up-front
-			// (since it auto-removed itself anyway), then let
-			// resetEffects do the rest of its usual job.
-			delete curr.transitionHandler;
-			curr.resetEffects();
-			delete current[id];
-		}
-		
-		// Timeout will have been cleared before bounce call, so remove timer.
-		delete curr.timer;
-		
-		if (x != lastX || y != lastY){
-			curr.transitionHandler = on.once(node, hasTransitionEnd, end);
-			node.style[transitionPrefix + "Duration"] = widget.bounceDuration + "ms";
-			node.style[transformProp] =
-				translatePrefix + x + "px," + y + "px" + translateSuffix;
-			
-			// Also handle transitions for scrollbars.
-			if(x != lastX && curr.scrollableX){
-				scrollbarNode = curr.widget._scrollbarXNode;
-				scrollbarNode.style[transitionPrefix + "Duration"] =
-					widget.bounceDuration + "ms";
-				if(lastX > x){
-					// Further left; bounce back right
-					scrollbarNode.style[transformProp] =
-						translatePrefix + "0,0" + translateSuffix;
-				}else{
-					// Further right; bounce back left
-					scrollbarNode.style[transformProp] =
-						translatePrefix +
-						(scrollbarNode.parentNode.offsetWidth - scrollbarNode.offsetWidth) +
-						"px,0" + translateSuffix;
-				}
-			}
-			if(y != lastY && curr.scrollableY){
-				scrollbarNode = curr.widget._scrollbarYNode;
-				scrollbarNode.style[transitionPrefix + "Duration"] =
-					widget.bounceDuration + "ms";
-				if(lastY > y){
-					// Above top; bounce back down
-					scrollbarNode.style[transformProp] =
-						translatePrefix + "0,0" + translateSuffix;
-				}else{
-					// Below bottom; bounce back up
-					scrollbarNode.style[transformProp] =
-						translatePrefix + "0," +
-						(scrollbarNode.parentNode.offsetHeight - scrollbarNode.offsetHeight) +
-						"px" + translateSuffix;
-				}
-			}
-		}else{
-			end(); // no rubber-banding necessary; just reset
-		}
-	}
-	
-	function startGlide(id){
-		// starts glide operation when drag ends
-		var curr = current[id],
-			prev = previous[id],
-			match, posX, posY,
-			INERTIA_ACCELERATION = 1.15;
-		
-		delete previous[id];
-		
-		if(curr.timer){ clearTimeout(curr.timer); }
-		
-		// Enable usage of resetEffects during glide or bounce.
-		curr.resetEffects = resetEffects;
-		
-		// calculate velocity based on time and displacement since last tick
-		match = translateRx.exec(curr.node.style[transformProp]);
-		if(match){
-			posX = +match[1];
-			posY = +match[2];
-		} else {
-			posX = posY = 0;
-		}
-		
-		// If there is no glide to perform (no exit velocity), or if we are
-		// beyond boundaries on all applicable edges, immediately bounce back.
-		if((!curr.velX && !curr.velY) ||
-				((posX >= 0 || posX <= -(curr.scrollWidth - curr.parentWidth)) &&
-				(posY >= 0 || posY <= -(curr.scrollHeight - curr.parentHeight)))){
-			bounce(id, posX, posY);
-			return;
-		}
-		
-		function sameSign(a, b){
-			return ((a.velX <= 0 && b.velX <= 0) || (a.velX >= 0 && b.velX >= 0)) &&
-					((a.velY <= 0 && b.velY <= 0) || (a.velY >= 0 && b.velY >= 0));
-		}
-		
-		if(prev && (prev.velX || prev.velY) && sameSign(curr, prev)){
-			curr.velX = (curr.velX + prev.velX) * INERTIA_ACCELERATION;
-			curr.velY = (curr.velY + prev.velY) * INERTIA_ACCELERATION;
-		}
-		
-		// update lastX/Y with current position, for glide calculations
-		curr.lastX = posX;
-		curr.lastY = posY;
-		curr.calcFunc = function(){ calcGlide(id); };
-		curr.timer = setTimeout(curr.calcFunc, glideTimerRes);
-	}
-	function calcGlide(id){
-		// performs glide and decelerates according to widget's glideDecel method
-		var curr = current[id],
-			node, parentNode, widget, i,
-			nx, ny, nvx, nvy, // old/new coords and new velocities
-			BOUNCE_DECELERATION_AMOUNT = 6;
-		
-		if(!curr){ return; }
-		
-		node = curr.node;
-		parentNode = node.parentNode;
-		widget = curr.widget;
-		nvx = widget.glideDecel(curr.velX);
-		nvy = widget.glideDecel(curr.velY);
-		
-		if(Math.abs(nvx) >= glideThreshold || Math.abs(nvy) >= glideThreshold){
-			// still above stop threshold; update transformation
-			nx = curr.lastX + nvx;
-			ny = curr.lastY + nvy;
-			
-			// If glide has traveled beyond any edges, institute rubber-band effect
-			// by further decelerating.
-			if(nx > 0 || nx < -(curr.scrollWidth - curr.parentWidth)){
-				for(i = BOUNCE_DECELERATION_AMOUNT; i--;){
-					nvx = widget.glideDecel(nvx);
-				}
-			}
-			if(ny > 0 || ny < -(curr.scrollHeight - curr.parentHeight)){
-				for(i = BOUNCE_DECELERATION_AMOUNT; i--;){
-					nvy = widget.glideDecel(nvy);
-				}
-			}
-			
-			// still scrollable; update offsets/velocities and schedule next tick
-			scroll(widget, -nx, -ny); // call scroll with positive coordinates
-			// update information
-			curr.lastX = nx;
-			curr.lastY = ny;
-			curr.velX = nvx;
-			curr.velY = nvy;
-			curr.timer = setTimeout(curr.calcFunc, glideTimerRes);
-		}else{
-			bounce(id, curr.lastX, curr.lastY);
-		}
-	}
-	
-	return declare(null, {
-		// touchesToScroll: Number
-		//		Number of touches to require on the component's touch target node
-		//		in order to trigger scrolling behavior.
-		touchesToScroll: 1,
-		
-		// touchNode: DOMNode?
-		//		Node upon which scroll behavior will be based; transformations will be
-		//		applied to this node, and events and some DOM/styles will be applied
-		//		to its *parent*.  If not specified, defaults to containerNode.
-		touchNode: null,
-		
-		// scrollThreshold: Number
-		//		Minimum number of pixels to wait for user to scroll (in any direction)
-		//		before initiating scroll.
-		scrollThreshold: 10,
-		
-		// bounceDuration: Number
-		//		Number of milliseconds which "rubber-banding" transitions
-		//		(i.e. bouncing back from beyond edges) should take.
-		bounceDuration: 300,
-		
-		postCreate: function(){
-			this._initTouch();
-			this.inherited(arguments);
-		},
-		
-		_initTouch: function(){
-			var node = this.touchNode = this.touchNode || this.containerNode,
-				widget = this,
-				parentNode;
-			
-			if(!node || !node.parentNode){
-				// Bail out if we have no touchNode or containerNode, or if we don't
-				// seem to have a parent node to work with.
-				console.warn("TouchScroll requires a nested node upon which to operate.");
-				return;
-			}
-			
-			parentNode = node.parentNode;
-			
-			// Set overflow to hidden in order to prevent any native scroll logic.
-			parentNode.style.overflow = "hidden";
-			
-			node.style[transitionPrefix + "Property"] = cssPrefix + "transform";
-			node.style[transitionPrefix + "TimingFunction"] =
-				"cubic-bezier(0.33, 0.66, 0.66, 1)";
-			
-			function cancelTouchScroll(){
-				widget.cancelTouchScroll();
-			}
-			
-			function wrapHandler(func){
-				return function(evt){
-					evt.widget = widget;
-					evt.cancelTouchScroll = cancelTouchScroll;
-					func.call(this, evt);
-				};
-			}
-			
-			this._touchScrollListeners = [
-				on(parentNode, "touchstart", wrapHandler(ontouchstart)),
-				on(parentNode, "touchmove", wrapHandler(ontouchmove)),
-				on(parentNode, "touchend,touchcancel", wrapHandler(ontouchend))
-			];
-		},
-		
-		destroy: function(){
-			var i = this._touchScrollListeners.length;
-			while(i--){
-				this._touchScrollListeners[i].remove();
-			}
-			delete current[this.id];
-			
-			this.inherited(arguments);
-		},
-		
-		scrollTo: function(options){
-			// summary:
-			//      Scrolls the widget to a specific position.
-			// options: Object
-			//		Object containing target x and/or y position to scroll to
-			//		(if unspecified, scroll in that direction will be preserved).
-			//		Also supports the following other options:
-			//		* preserveMomentum: if true, will not reset any active
-			//			momentum or bounce on the widget
-			
-			var curr = current[this.id],
-				touchNode = this.touchNode,
-				parentNode = touchNode.parentNode;
-			
-			if(!options.preserveMomentum && curr && curr.resetEffects){
-				// Stop any glide or bounce occurring before scrolling.
-				curr.resetEffects();
-			}
-			
-			// Constrain coordinates within scrollable boundaries.
-			if(options.x){
-				options.x = Math.max(0, Math.min(options.x,
-					touchNode.scrollWidth - parentNode.offsetWidth));
-			}
-			if(options.y){
-				options.y = Math.max(0, Math.min(options.y,
-					touchNode.scrollHeight - parentNode.offsetHeight));
-			}
-			
-			scroll(this, options);
-		},
-		
-		getScrollPosition: function(){
-			// summary:
-			//      Determines current translation from computed style
-			//      (if mid-transition), or applied style.
-			var match = getScrollStyle(this);
-			return match ? { x: -match[1], y: -match[2] } : { x: 0, y: 0 };
-		},
-		
-		cancelTouchScroll: function(){
-			// summary:
-			//		Removes any existing scroll information for this component from the
-			//		current map, effectively canceling any TouchScroll behavior for
-			//		that particular touch gesture.
-			
-			var curr = current[this.id];
-			if(!curr){ return; }
-			
-			if(curr.resetEffects){ curr.resetEffects(); }
-			else{
-				if(curr.timer){ clearTimeout(curr.timer); }
-				put(curr.node.parentNode, ".touchscroll-fadeout");
-			}
-			
-			delete current[this.id];
-		},
-		
-		glideDecel: function(n){
-			// summary:
-			//		Deceleration algorithm. Given a number representing velocity,
-			//		returns a new velocity to impose for the next "tick".
-			//		(Don't forget that velocity can be positive or negative!)
-			return n * 0.9; // Number
-		}
-	});
-});

+ 0 - 351
esp/files/dgrid/_StoreMixin.js

@@ -1,351 +0,0 @@
-define(["dojo/_base/kernel", "dojo/_base/declare", "dojo/_base/lang", "dojo/_base/Deferred", "dojo/on", "dojo/aspect", "put-selector/put"],
-function(kernel, declare, lang, Deferred, listen, aspect, put){
-	// This module isolates the base logic required by store-aware list/grid
-	// components, e.g. OnDemandList/Grid and the Pagination extension.
-	
-	// Noop function, needed for _trackError when callback due to a bug in 1.8
-	// (see http://bugs.dojotoolkit.org/ticket/16667)
-	function noop(value){ return value; }
-	
-	function emitError(err){
-		// called by _trackError in context of list/grid, if an error is encountered
-		if(typeof err !== "object"){
-			// Ensure we actually have an error object, so we can attach a reference.
-			err = new Error(err);
-		}else if(err.dojoType === "cancel"){
-			// Don't fire dgrid-error events for errors due to canceled requests
-			// (unfortunately, the Deferred instrumentation will still log them)
-			return;
-		}
-		// TODO: remove this @ 0.4 (prefer grid property directly on event object)
-		err.grid = this;
-		
-		if(listen.emit(this.domNode, "dgrid-error", {
-				grid: this,
-				error: err,
-				cancelable: true,
-				bubbles: true })){
-			console.error(err);
-		}
-	}
-	
-	return declare(null, {
-		// store: Object
-		//		The object store (implementing the dojo/store API) from which data is
-		//		to be fetched.
-		store: null,
-		
-		// query: Object
-		//		Specifies query parameter(s) to pass to store.query calls.
-		query: null,
-		
-		// queryOptions: Object
-		//		Specifies additional query options to mix in when calling store.query;
-		//		sort, start, and count are already handled.
-		queryOptions: null,
-		
-		// getBeforePut: boolean
-		//		If true, a get request will be performed to the store before each put
-		//		as a baseline when saving; otherwise, existing row data will be used.
-		getBeforePut: true,
-		
-		// noDataMessage: String
-		//		Message to be displayed when no results exist for a query, whether at
-		//		the time of the initial query or upon subsequent observed changes.
-		//		Defined by _StoreMixin, but to be implemented by subclasses.
-		noDataMessage: "",
-		
-		// loadingMessage: String
-		//		Message displayed when data is loading.
-		//		Defined by _StoreMixin, but to be implemented by subclasses.
-		loadingMessage: "",
-		
-		constructor: function(){
-			// Create empty objects on each instance, not the prototype
-			this.query = {};
-			this.queryOptions = {};
-			this.dirty = {};
-			this._updating = {}; // Tracks rows that are mid-update
-			this._columnsWithSet = {};
-
-			// Reset _columnsWithSet whenever column configuration is reset
-			aspect.before(this, "configStructure", lang.hitch(this, function(){
-				this._columnsWithSet = {};
-			}));
-		},
-		
-		postCreate: function(){
-			this.inherited(arguments);
-			if(this.store){
-				this._updateNotifyHandle(this.store);
-			}
-		},
-		
-		destroy: function(){
-			this.inherited(arguments);
-			if(this._notifyHandle){
-				this._notifyHandle.remove();
-			}
-		},
-		
-		_configColumn: function(column){
-			// summary:
-			//		Implements extension point provided by Grid to store references to
-			//		any columns with `set` methods, for use during `save`.
-			if (column.set){
-				this._columnsWithSet[column.field] = column;
-			}
-		},
-		
-		_updateNotifyHandle: function(store){
-			// summary:
-			//		Unhooks any previously-existing store.notify handle, and
-			//		hooks up a new one for the given store.
-			
-			if(this._notifyHandle){
-				// Unhook notify handler from previous store
-				this._notifyHandle.remove();
-				delete this._notifyHandle;
-			}
-			if(store && typeof store.notify === "function"){
-				this._notifyHandle = aspect.after(store, "notify",
-					lang.hitch(this, "_onNotify"), true);
-			}
-		},
-		
-		_setStore: function(store, query, queryOptions){
-			// summary:
-			//		Assigns a new store (and optionally query/queryOptions) to the list,
-			//		and tells it to refresh.
-			
-			this._updateNotifyHandle(store);
-			
-			this.store = store;
-			this.dirty = {}; // discard dirty map, as it applied to a previous store
-			this.set("query", query, queryOptions);
-		},
-		_setQuery: function(query, queryOptions){
-			// summary:
-			//		Assigns a new query (and optionally queryOptions) to the list,
-			//		and tells it to refresh.
-			
-			var sort = queryOptions && queryOptions.sort;
-			
-			this.query = query !== undefined ? query : this.query;
-			this.queryOptions = queryOptions || this.queryOptions;
-			
-			// If we have new sort criteria, pass them through sort
-			// (which will update _sort and call refresh in itself).
-			// Otherwise, just refresh.
-			sort ? this.set("sort", sort) : this.refresh();
-		},
-		setStore: function(store, query, queryOptions){
-			kernel.deprecated("setStore(...)", 'use set("store", ...) instead', "dgrid 0.4");
-			this.set("store", store, query, queryOptions);
-		},
-		setQuery: function(query, queryOptions){
-			kernel.deprecated("setQuery(...)", 'use set("query", ...) instead', "dgrid 0.4");
-			this.set("query", query, queryOptions);
-		},
-		
-		_getQueryOptions: function(){
-			// summary:
-			//		Get a fresh queryOptions object, also including the current sort
-			var options = lang.delegate(this.queryOptions, {});
-			if(this._sort.length){
-				// Prevents SimpleQueryEngine from doing unnecessary "null" sorts (which can
-				// change the ordering in browsers that don't use a stable sort algorithm, eg Chrome)
-				options.sort = this._sort;
-			}
-			return options;
-		},
-		_getQuery: function(){
-			// summary:
-			//		Implemented consistent with _getQueryOptions so that if query is
-			//		an object, this returns a protected (delegated) object instead of
-			//		the original.
-			var q = this.query;
-			return typeof q == "object" && q != null ? lang.delegate(q, {}) : q;
-		},
-		
-		_setSort: function(property, descending){
-			// summary:
-			//		Sort the content
-			
-			// prevent default storeless sort logic as long as we have a store
-			if(this.store){ this._lastCollection = null; }
-			this.inherited(arguments);
-		},
-		
-		_onNotify: function(object, existingId){
-			// summary:
-			//		Method called when the store's notify method is called.
-			
-			// Call inherited in case anything was mixed in earlier
-			this.inherited(arguments);
-			
-			// For adds/puts, check whether any observers are hooked up;
-			// if not, force a refresh to properly hook one up now that there is data
-			if(object && this._numObservers < 1){
-				this.refresh({ keepScrollPosition: true });
-			}
-		},
-		
-		insertRow: function(object, parent, beforeNode, i, options){
-			var store = this.store,
-				dirty = this.dirty,
-				id = store && store.getIdentity(object),
-				dirtyObj;
-			
-			if(id in dirty && !(id in this._updating)){ dirtyObj = dirty[id]; }
-			if(dirtyObj){
-				// restore dirty object as delegate on top of original object,
-				// to provide protection for subsequent changes as well
-				object = lang.delegate(object, dirtyObj);
-			}
-			return this.inherited(arguments);
-		},
-		
-		updateDirty: function(id, field, value){
-			// summary:
-			//		Updates dirty data of a field for the item with the specified ID.
-			var dirty = this.dirty,
-				dirtyObj = dirty[id];
-			
-			if(!dirtyObj){
-				dirtyObj = dirty[id] = {};
-			}
-			dirtyObj[field] = value;
-		},
-		setDirty: function(id, field, value){
-			kernel.deprecated("setDirty(...)", "use updateDirty() instead", "dgrid 0.4");
-			this.updateDirty(id, field, value);
-		},
-		
-		save: function() {
-			// Keep track of the store and puts
-			var self = this,
-				store = this.store,
-				dirty = this.dirty,
-				dfd = new Deferred(), promise = dfd.promise,
-				getFunc = function(id){
-					// returns a function to pass as a step in the promise chain,
-					// with the id variable closured
-					var data;
-					return (self.getBeforePut || !(data = self.row(id).data)) ?
-						function(){ return store.get(id); } :
-						function(){ return data; };
-				};
-			
-			// function called within loop to generate a function for putting an item
-			function putter(id, dirtyObj) {
-				// Return a function handler
-				return function(object) {
-					var colsWithSet = self._columnsWithSet,
-						updating = self._updating,
-						key, data;
-
-					if (typeof object.set === "function") {
-						object.set(dirtyObj);
-					} else {
-						// Copy dirty props to the original, applying setters if applicable
-						for(key in dirtyObj){
-							object[key] = dirtyObj[key];
-						}
-					}
-
-					// Apply any set methods in column definitions.
-					// Note that while in the most common cases column.set is intended
-					// to return transformed data for the key in question, it is also
-					// possible to directly modify the object to be saved.
-					for(key in colsWithSet){
-						data = colsWithSet[key].set(object);
-						if(data !== undefined){ object[key] = data; }
-					}
-					
-					updating[id] = true;
-					// Put it in the store, returning the result/promise
-					return Deferred.when(store.put(object), function() {
-						// Clear the item now that it's been confirmed updated
-						delete dirty[id];
-						delete updating[id];
-					});
-				};
-			}
-			
-			// For every dirty item, grab the ID
-			for(var id in dirty) {
-				// Create put function to handle the saving of the the item
-				var put = putter(id, dirty[id]);
-				
-				// Add this item onto the promise chain,
-				// getting the item from the store first if desired.
-				promise = promise.then(getFunc(id)).then(put);
-			}
-			
-			// Kick off and return the promise representing all applicable get/put ops.
-			// If the success callback is fired, all operations succeeded; otherwise,
-			// save will stop at the first error it encounters.
-			dfd.resolve();
-			return promise;
-		},
-		
-		revert: function(){
-			// summary:
-			//		Reverts any changes since the previous save.
-			this.dirty = {};
-			this.refresh();
-		},
-		
-		_trackError: function(func){
-			// summary:
-			//		Utility function to handle emitting of error events.
-			// func: Function|String
-			//		A function which performs some store operation, or a String identifying
-			//		a function to be invoked (sans arguments) hitched against the instance.
-			//		If sync, it can return a value, but may throw an error on failure.
-			//		If async, it should return a promise, which would fire the error
-			//		callback on failure.
-			// tags:
-			//		protected
-			
-			var result;
-			
-			if(typeof func == "string"){ func = lang.hitch(this, func); }
-			
-			try{
-				result = func();
-			}catch(err){
-				// report sync error
-				emitError.call(this, err);
-			}
-			
-			// wrap in when call to handle reporting of potential async error
-			return Deferred.when(result, noop, lang.hitch(this, emitError));
-		},
-		
-		newRow: function(){
-			// Override to remove no data message when a new row appears.
-			// Run inherited logic first to prevent confusion due to noDataNode
-			// no longer being present as a sibling.
-			var row = this.inherited(arguments);
-			if(this.noDataNode){
-				put(this.noDataNode, "!");
-				delete this.noDataNode;
-			}
-			return row;
-		},
-		removeRow: function(rowElement, justCleanup){
-			var row = {element: rowElement};
-			// Check to see if we are now empty...
-			if(!justCleanup && this.noDataMessage &&
-					(this.up(row).element === rowElement) &&
-					(this.down(row).element === rowElement)){
-				// ...we are empty, so show the no data message.
-				this.noDataNode = put(this.contentNode, "div.dgrid-no-data");
-				this.noDataNode.innerHTML = this.noDataMessage;
-			}
-			return this.inherited(arguments);
-		}
-	});
-});

+ 0 - 55
esp/files/dgrid/css/TouchScroll.css

@@ -1,55 +0,0 @@
-/* styles for scrollbars during touch-scroll */
-
-.touchscroll-x, .touchscroll-y {
-	display: none; /* overridden below */
-	overflow: hidden; /* cut off ends of scrollbar during rubber-banding */
-	position: absolute;
-	/* establish base style for scrollbar fade-in/out */
-	opacity: 0.7;
-}
-.touchscroll-fadeout .touchscroll-x, .touchscroll-fadeout .touchscroll-y {
-	opacity: 0;
-	-webkit-transition: opacity 0.3s ease-out 0.1s;
-	-moz-transition: opacity 0.3s ease-out 0.1s;
-	-o-transition: opacity 0.3s ease-out 0.1s;
-	transition: opacity 0.3s ease-out 0.1s;
-}
-
-.touchscroll-bar {
-	background-color: rgba(88,88,88,0.97);
-	border: 1px solid rgba(88,88,88,1);
-	border-radius: 3px;
-	
-	/* the borders aren't anti-aliased on Android, so this smooths it out a bit */
-	-webkit-box-shadow: 0 0 1px rgba(88,88,88,0.4);
-}
-
-.touchscroll-x {
-	left: 1px;
-	right: 3px;
-	bottom: 1px;
-	height: 5px;
-}
-.touchscroll-y {
-	top: 1px;
-	bottom: 3px;
-	right: 1px;
-	width: 5px;
-}
-
-.touchscroll-scrollable-x .touchscroll-x, .touchscroll-scrollable-y .touchscroll-y {
-	display: block; /* display scrollbar when appropriate */
-}
-
-.touchscroll-bar {
-	/* Establish transition property and timing function for scrollbars */
-	-webkit-transition: transform cubic-bezier(0.33, 0.66, 0.66, 1);
-	-moz-transition: transform cubic-bezier(0.33, 0.66, 0.66, 1);
-	-o-transition: transform cubic-bezier(0.33, 0.66, 0.66, 1);
-	transition: transform cubic-bezier(0.33, 0.66, 0.66, 1);
-}
-
-/* indicator of a successful load */
-#dgrid-css-TouchScroll-loaded {
-	display: none;
-}

+ 0 - 40
esp/files/dgrid/css/columnset.css

@@ -1,40 +0,0 @@
-.dgrid-column-set {
-	overflow: hidden;
-	width: 100%;
-	position: relative; /* This is needed because we setting position: relative on cells in the grid for focus in IE7*/
-}
-
-.dgrid-column-set-cell {
-	vertical-align: top;
-}
-.dgrid-column-set-scroller {
-	position: absolute;
-	bottom: 0px;
-	overflow-x: auto;
-	overflow-y: hidden;
-}
-.dgrid-column-set-scroller-content {
-	position: relative;
-	height: 1px;
-}
-
-/* UA-specific hacks*/
-html.has-mozilla .dgrid-column-set *:focus, html.has-safari .dgrid-column-set *:focus {
-	/* firefox and opera's outline gets cropped by the overflow: hidden, so we add a border*/
-	border: 1px dotted black; 
-	outline: 1px dotted black;
-}
-html.has-ie-7 .dgrid-column-set {
-	/* in IE7 (strangely not IE6 or IE8+) this is needed instead of 100% to make it not create a horizontal scroll bar*/
-	width: auto;
-}
-
-html.has-quirks .dgrid-column-set {
-	/* at it works in quirks even in IE7*/
-	width: 100%;
-}
-
-/* indicator of a successful load */
-#dgrid-css-columnset-loaded {
-	display: none;
-}

+ 0 - 208
esp/files/dgrid/css/dgrid.css

@@ -1,208 +0,0 @@
-/* This stylesheet provides the structural CSS for the dgrid */
-.dgrid {
-	position: relative;
-	overflow: hidden; /* This is needed by IE to prevent crazy scrollbar flashing */
-	border: 1px solid #ddd;
-	height: 30em;
-	display: block;
-}
-
-.dgrid-header {
-	background-color: #eee;
-	position: absolute;
-	right: 17px; /* scrollbar width; revised in List.js if necessary */
-	left: 0;
-}
-
-.dgrid-header-scroll {
-	position: absolute;
-	top: 0;
-	right: 0;
-}
-
-.dgrid-footer {
-	position: absolute;
-	bottom: 0;
-	width: 100%;
-}
-
-.dgrid-header-hidden,
-html.has-quirks .dgrid-header-hidden .dgrid-cell {
-	/*
-		Used to "hide" header, without losing size information for reference.
-		!important is used to supersede theme styles at higher specificity.
-		Left/right box styles are untouched, as they may influence width of
-		.dgrid-content as updated in Grid's resize method.
-		Note: Still not quite perfect in IE Quirks mode (1px left over).
-	*/
-	font-size: 0; /* allow shrinkage in IE Quirks mode for Lists */
-	height: 0 !important;
-	border-top: none !important;
-	border-bottom: none !important;
-	margin-top: 0 !important;
-	margin-bottom: 0 !important;
-	padding-top: 0 !important;
-	padding-bottom: 0 !important;
-}
-
-.dgrid-footer-hidden {
-	/* Hiding footer is much simpler; simply set its display to none. */
-	display: none;
-}
-
-.dgrid-sortable {
-	cursor: pointer;
-}
-.dgrid-header, .dgrid-header-row, .dgrid-footer {
-	overflow: hidden;
-	background-color: #eee;
-}
-
-.dgrid-row-table {
-	border-collapse: collapse;
-	border: none;
-	table-layout: fixed;
-	empty-cells: show;
-	width: 100%; /* this becomes 'auto' for IE7 (non-quirks) */
-	height: 100%;
-}
-.dgrid-cell {
-	padding: 0px;
-	text-align: left;
-	overflow: hidden;
-	vertical-align: top;
-	border: 1px solid #ddd;
-	border-top-style: none;
-	
-	box-sizing: border-box;
-	-moz-box-sizing: border-box;
-	-ms-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-}
-.dgrid-cell-padding {
-	padding: 3px;
-}
-
-.dgrid-content {
-	position: relative;
-	height: 99%;
-}
-
-.dgrid-scroller {
-	overflow-x: auto;
-	overflow-y: scroll;
-	position: absolute;
-	top: 0px;
-	margin-top: 25px; /* this will be adjusted programmatically to fit below the header*/
-	bottom: 0px;
-	width: 100%;
-}
-
-.dgrid-preload {
-	/* Force IE6 to honor 0 height */
-	font-size: 0;
-	line-height: 0;
-}
-
-.dgrid-loading {
-	position: relative;
-	height: 100%;
-}
-.dgrid-above {
-	position: absolute;
-	bottom: 0;
-}
-
-.ui-icon {
-	width: 16px;
-	height: 16px;
-	background-image: url('images/ui-icons_222222_256x240.png');
-}
-
-.ui-icon-triangle-1-e {
-	background-position: -32px -16px;
-}
-.ui-icon-triangle-1-se {
-	background-position: -48px -16px;
-}
-
-.dgrid-expando-icon {
-	width: 16px;
-	height: 16px;
-}
-.dgrid-tree-container {
-	-webkit-transition-duration: 0.3s;
-	-moz-transition-duration: 0.3s;
-	-ms-transition-duration: 0.3s;
-	-o-transition-duration: 0.3s;
-	transition-duration: 0.3s;
-	overflow: hidden;
-}
-.dgrid-tree-container.dgrid-tree-resetting {
-	-webkit-transition-duration: 0;
-	-moz-transition-duration: 0;
-	-ms-transition-duration: 0;
-	-o-transition-duration: 0;
-	transition-duration: 0;
-}
-
-/* Single Sort */
-.dgrid-sort-arrow {
-	background-position: -64px -16px;
-	display: block;
-	float: right;
-	margin: 0 4px 0 5px;
-	height: 12px;
-}
-.dgrid-sort-up .dgrid-sort-arrow {
-	background-position: 0px -16px;
-}
-
-/* selection*/
-.dgrid-selected {
-	background-color: #bfd6eb;
-}
-
-.dgrid-input {
-	width: 99%;
-}
-
-/* UA-specific hacks*/
-html.has-mozilla .dgrid *:focus, html.has-opera .dgrid *:focus {
-	/* firefox's focus doesn't work by default for divs prior to actually tabbing into it. This fixes that
-	(we don't do any other browsers because we are trying to stay as close to native as possible) */ 
-	outline: 1px dotted;
-}
-html.has-ie-6-7.has-no-quirks .dgrid-row-table {
-	/* in IE7 this is needed instead of 100% to make it not create a horizontal scroll bar*/
-	width: auto;
-}
-html.has-quirks .dgrid-row-table, html.has-ie-6 .dgrid-row-table {
-	/* similar story, height looks too high */
-	height: auto; 
-}
-
-html.has-quirks .dgrid-header-scroll,
-html.has-ie-6 .dgrid-header-scroll {
-	/* ensure that header scroll node can shrink to 0 height in IE6 & quirks */
-	font-size: 0;
-}
-
-html.has-mozilla .dgrid-focus {
-	/* fix row focus outline (prevents horizontal scroll in FF 3.6) */
-	outline-offset: -1px;
-}
-
-/* will be used to calculate the width of the scrollbar */
-.dgrid-scrollbar-measure {
-	width: 100px;
-	height: 100px;
-	overflow: scroll;
-	position: absolute;
-	top: -9999px;
-}
-
-/* indicator of a successful load */
-#dgrid-css-dgrid-loaded {
-	display: none;
-}

+ 0 - 50
esp/files/dgrid/css/dgrid_rtl.css

@@ -1,50 +0,0 @@
-/* rtl support 
-
-	IMPORTANT:
-	WebKit places the scrollbars on the RIGHT, even when in RTL mode :(
-	.dgrid-rtl is added to the domNode if the grid's isRTL is true
-	.dgrid-rtl-nonwebkit is also added to the domNode if
-		the grid's isRTL is true AND the client isn't WebKit
-*/
-.dgrid-rtl-nonwebkit .dgrid-header {
-	right: 0;
-	left: 17px;
-}
-
-.dgrid-rtl-nonwebkit .dgrid-header-scroll {
-	left: 0px;
-	right: auto;
-}
-
-.dgrid-rtl .dgrid-cell {
-	text-align: right;
-}
-
-/* Reverse position of sort arrow */
-.dgrid-rtl .dgrid-sort-arrow {
-	float: left;
-	margin: 0 5px 0 4px;
-}
-
-/* Reverse arrows for tree expando states */
-.dgrid-rtl .ui-icon-triangle-1-e {
-	background-position: -96px -16px;
-}
-.dgrid-rtl .ui-icon-triangle-1-se {
-	background-position: -80px -16px;
-}
-
-/* Reverse Pagination */
-
-.dgrid-rtl .dgrid-pagination .dgrid-status {
-	float: right;
-}
-
-.dgrid-rtl .dgrid-pagination .dgrid-page-size {
-	float: right;
-}
-.dgrid-rtl .dgrid-pagination .dgrid-navigation {
-	float: left;
-}
-
-#dgrid-css-dgrid_rtl-loaded { display: none; }

+ 0 - 48
esp/files/dgrid/css/extensions/ColumnHider.css

@@ -1,48 +0,0 @@
-.dgrid-hider-toggle {
-	background-position: 0 -192px;
-	background-color: transparent;
-	border: none;
-	cursor: pointer;
-	position: absolute;
-	right: 0;
-	top: 0;
-}
-
-.dgrid-hider-menu {
-	position: absolute;
-	top: 0;
-	right: 17px;
-	width: 184px;
-	background-color: #fff;
-	border: 1px solid black;
-	z-index: 99999;
-	padding: 4px;
-	overflow-x: hidden;
-	overflow-y: auto;
-}
-
-.dgrid-hider-menu-row {
-	position: relative;
-	padding: 2px;
-}
-.dgrid-hider-menu-check {
-	position: absolute;
-	top: 2px;
-	left: 2px;
-	padding: 0;
-}
-.dgrid-hider-menu-label {
-	display: block;
-	padding-left: 20px;
-}
-
-html.has-quirks .dgrid-hider-menu-check,
-html.has-ie-6-7 .dgrid-hider-menu-check {
-	/* IE < 8 seems to ignore padding: 0, so counteract */
-	top: 0;
-	left: 0;
-}
-
-#dgrid-css-extensions-ColumnHider-loaded {
-	display: none;
-}

+ 0 - 14
esp/files/dgrid/css/extensions/ColumnReorder.css

@@ -1,14 +0,0 @@
-.dgrid-header .dgrid-cell {
-	display: table-cell; /* override any spurious dojoDndItem settings elsewhere */
-}
-
-.dgrid-header .dojoDndItemBefore {
-	border-left: 2px dotted #000 !important;
-}
-.dgrid-header .dojoDndItemAfter {
-	border-right: 2px dotted #000 !important;
-}
-
-#dgrid-css-extensions-ColumnReorder-loaded { /* load indicator for xstyle */
-	display: none;
-}

+ 0 - 58
esp/files/dgrid/css/extensions/ColumnResizer.css

@@ -1,58 +0,0 @@
-.dgrid-column-resizer {
-	position: absolute;
-	width: 2px;
-	background-color: #666;
-	z-index: 1000;
-}
-
-.dgrid-resize-handle {
-	height: 100px;
-	width: 0;
-	position: absolute;
-	right: -4px;
-	top:-4px;
-	cursor: col-resize;
-	z-index: 999;
-	border-left: 5px solid transparent;
-	outline: none;
-}
-html.has-ie-6 .dgrid-resize-handle {
-	border-color: pink;
-	filter: chroma(color=pink);
-}
-.dgrid-resize-header-container {
-	height:100%;
-}
-
-/* make the resize handles larger on touch-capable devices */
-html.has-touch .dgrid-resize-handle {
-	border-left: 20px solid transparent;
-}
-html.has-touch .dgrid-column-resizer {
-	width: 2px;
-}
-
-html.has-no-quirks .dgrid-resize-header-container {
-	/* set to relative so we can do the resizing against this node...
-		except when in quirks mode, where we have to use the th */
-	position: relative;
-}
-html.has-ie-6 .dgrid-resize-header-container {
-	position: static; /* and in IE6 we have to do the th hack */
-} 
-.dgrid-header .dgrid-cell-padding {
-	overflow: hidden;
-}
-html.has-ie-6 .dgrid-header .dgrid-cell-padding {
-	margin-right: 4px; /* for IE6, keep the resizer visible */
-}
-html.has-ie-6 .dgrid-header .dgrid-sort-arrow {
-    margin-right: 0; /* for IE6, zero out the right margin due to the right margin for the container */
-}
-html.has-quirks .dgrid-header .dgrid-cell-padding, html.has-ie-6 .dgrid-header .dgrid-cell {
-	position:relative;
-}
-
-#dgrid-css-extensions-ColumnResizer-loaded {
-	display: none;
-}

+ 0 - 8
esp/files/dgrid/css/extensions/CompoundColumns.css

@@ -1,8 +0,0 @@
-.dgrid-spacer-row th { /* Need to make these cells zero height/invisible, but still force the table layout */
-	padding-top: 0;
-	padding-bottom: 0;
-	border-top: none;
-	border-bottom: none;
-}
-
-#dgrid-css-extensions-CompoundColumns-loaded { display: none; }

+ 0 - 38
esp/files/dgrid/css/extensions/Pagination.css

@@ -1,38 +0,0 @@
-.dgrid-status {
-	padding: 2px;
-}
-
-.dgrid-pagination .dgrid-status {
-	float: left;
-}
-
-.dgrid-pagination .dgrid-navigation, .dgrid-pagination .dgrid-page-size {
-	float: right;
-}
-.dgrid-navigation .dgrid-page-link {
-	cursor: pointer;
-	font-weight: bold;
-	text-decoration: none;
-	color: inherit;
-	padding: 0 4px;
-}
-.dgrid-first, .dgrid-last, .dgrid-next, .dgrid-previous {
-	font-size: 130%;
-}
-.dgrid-pagination .dgrid-page-disabled,
-.has-ie-6-7 .dgrid-navigation .dgrid-page-disabled,
-.has-ie.has-quirks .dgrid-navigation .dgrid-page-disabled {
-	color: #aaa;
-	cursor: default;
-}
-.dgrid-page-input {
-	margin-top: 1px;
-	width: 2em;
-	text-align: center;
-}
-.dgrid-page-size {
-	margin: 1px 4px 0 4px;
-}
-
-/* indicator of a successful load */
-#dgrid-css-extensions-Pagination-loaded { display: none; }

+ 0 - 16
esp/files/dgrid/css/has-transforms3d.css

@@ -1,16 +0,0 @@
-/* these media queries assist in feature detection of 3D transforms */
-
-.has-csstransforms3d {
-	position: absolute;
-	visibility: hidden;
-}
-@media (transform-3d) { .csstransforms3d { left: 9px;	} }
-@media (-ms-transform-3d) { .csstransforms3d { left: 10px; } }
-@media (-o-transform-3d) { .csstransforms3d { left: 11px; } }
-@media (-moz-transform-3d) { .csstransforms3d { left: 12px; } }
-@media (-webkit-transform-3d) { .csstransforms3d { left: 13px; } }
-
-/* indicator of a successful load via xstyle */
-#dgrid-css-has-transforms3d-loaded {
-	display: none;
-}

BIN
esp/files/dgrid/css/images/ui-icons_222222_256x240.png


BIN
esp/files/dgrid/css/images/ui-icons_222222_256x240_white.png


+ 0 - 8
esp/files/dgrid/css/skins/README.md

@@ -1,8 +0,0 @@
-This folder contains skins based on the Dijit themes (claro, tundra, soria, and nihilo),
-as well as a number of other skins (e.g. cactus, sage, slate, squid).
-
-The skins are partially based on generic skin elements from the jquery-ui themeroller CSS
-convention. The dgrid component follows this convention.
-
-Any other stylesheet based on the themeroller convention can ostensibly
-also be used to skin the dgrid.

+ 0 - 108
esp/files/dgrid/css/skins/cactus.css

@@ -1,108 +0,0 @@
-.cactus .ui-widget-content {
-	border: none;
-	background: #faffef;
-	color: #000;
-}
-
-.cactus .dgrid-header-row {
-	border-bottom: none;
-}
-
-.cactus .ui-widget-header,
-.cactus .dgrid-footer {
-	color: #fff;
-	background: #333; /* Old browsers */
-	background: -moz-linear-gradient(top, #4e4e4e 0%, #555555 12%, #636363 25%, #505050 39%, #303030 49%, #000000 50%, #1c1c1c 60%, #292929 76%, #1e1e1e 91%, #141414 100%); /* FF3.6+ */
-	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4e4e4e), color-stop(12%,#555555), color-stop(25%,#636363), color-stop(39%,#505050), color-stop(49%,#303030), color-stop(50%,#000000), color-stop(60%,#1c1c1c), color-stop(76%,#292929), color-stop(91%,#1e1e1e), color-stop(100%,#141414)); /* Chrome,Safari4+ */
-	background: -webkit-linear-gradient(top, #4e4e4e 0%,#555555 12%,#636363 25%,#505050 39%,#303030 49%,#000000 50%,#1c1c1c 60%,#292929 76%,#1e1e1e 91%,#141414 100%); /* Chrome10+,Safari5.1+ */
-	background: -o-linear-gradient(top, #4e4e4e 0%,#555555 12%,#636363 25%,#505050 39%,#303030 49%,#000000 50%,#1c1c1c 60%,#292929 76%,#1e1e1e 91%,#141414 100%); /* Opera 11.10+ */
-	background: -ms-linear-gradient(top, #4e4e4e 0%,#555555 12%,#636363 25%,#505050 39%,#303030 49%,#000000 50%,#1c1c1c 60%,#292929 76%,#1e1e1e 91%,#141414 100%); /* IE10+ */
-	background: linear-gradient(top, #4e4e4e 0%,#555555 12%,#636363 25%,#505050 39%,#303030 49%,#000000 50%,#1c1c1c 60%,#292929 76%,#1e1e1e 91%,#141414 100%); /* W3C */
-	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4e4e4e', endColorstr='#141414',GradientType=0 ); /* IE6-9 */
-}
-
-.cactus .ui-widget-header th {
-	padding: 7px 3px;
-	font-weight: bold;
-	color: #fff;
-	text-shadow: 0 -1px 0 rgba(0,0,0,.9);
-	border-color: #111;
-	text-transform: uppercase;
-}
-
-.cactus .dgrid-cell {
-	border-color: #bbc581;
-	border-top: none;
-	border-right: none;
-	border-left: none;
-}
-
-.cactus .dgrid-row-even {
-	border-top: 1px solid #FFF;
-}
-
-.cactus .dgrid-row-odd {
-	background: #9a6;
-	background-image: -moz-linear-gradient(top, rgba(185,203,127,1) 0%, rgba(143,160,91,1) 100%);
-	background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(185,203,127,1)), color-stop(100%,rgba(143,160,91,1)));
-	background-image: -webkit-linear-gradient(top, rgba(185,203,127,1) 0%,rgba(143,160,91,1) 100%);
-	background-image: -o-linear-gradient(top, rgba(185,203,127,1) 0%,rgba(143,160,91,1) 100%);
-	background-image: -ms-linear-gradient(top, rgba(185,203,127,1) 0%,rgba(143,160,91,1) 100%);
-	background-image: linear-gradient(top, rgba(185,203,127,1) 0%,rgba(143,160,91,1) 100%);
-	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b9cb7f', endColorstr='#8fa05b',GradientType=0 );
-	text-shadow: 0 1px 0 rgba(255,255,255,.9);
-	border-top: 1px solid #ccd595;
-	color: #FFF;
-	text-shadow: 0 -1px 0 rgba(0,0,0,.3);
-}
-
-.cactus .dgrid-row-odd .dgrid-cell {
-	border-top: 1px solid #e9efbd;
-}
-
-.cactus .dgrid-row:hover,
-.cactus .dgrid-row:hover .dgrid-cell {
-	background: #555;
-	color: #fff;
-	text-shadow: 0 -1px 0 rgba(0,0,0,.9);
-	border-color: #555;
-}
-
-.cactus .dgrid-selected,
-.cactus .dgrid-selected .dgrid-cell {
-	background: #333;
-	color: #fff;
-	text-shadow: 0 -1px 0 rgba(0,0,0,.9);
-	border-color: #333;
-}
-
-.cactus .ui-state-active:hover {
-	background: #333;
-	border-color: #333;
-}
-
-.cactus .ui-state-highlight {
-	background: #d6e5a5; /* background-color doesn't override CSS3 gradient */
-	filter: none; /* override gradient in IE */
-	color: #000;
-	text-shadow: none;
-}
-
-/* need to use white-based image for sort arrow */
-.cactus .dgrid-sort-arrow {
-	background-image: url("../images/ui-icons_222222_256x240_white.png");
-}
-
-/* for ColumnReorder */
-.cactus .dgrid-header .dojoDndItemBefore {
-	border-left: 2px dotted #fff !important;
-}
-.cactus .dgrid-header .dojoDndItemAfter {
-	border-right: 2px dotted #fff !important;
-}
-
-/* for pagination in IE < 8 + quirks, need additional rule to override link color */
-.has-ie-6-7 .cactus .dgrid-navigation a,
-.has-ie.has-quirks .cactus .dgrid-navigation a {
-	color: #fff;
-}

+ 0 - 67
esp/files/dgrid/css/skins/claro.css

@@ -1,67 +0,0 @@
-.claro .dgrid {
-	border: 1px solid #aaa;
-	background: #fff;
-	color: #000;
-}
-
-.claro .ui-widget-header {
-	font-weight: bold;
-}
-.claro .ui-widget-header,
-.claro .dgrid-footer { 
-	background: #ebf0f5; /* Old browsers */
-	background: -moz-linear-gradient(top, #ebf0f5 0%, #d5e0ea 100%); /* FF3.6+ */
-	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ebf0f5), color-stop(100%,#d5e0ea)); /* Chrome,Safari4+ */
-	background: -webkit-linear-gradient(top, #ebf0f5 0%,#d5e0ea 100%); /* Chrome10+,Safari5.1+ */
-	background: -o-linear-gradient(top, #ebf0f5 0%,#d5e0ea 100%); /* Opera 11.10+ */
-	background: -ms-linear-gradient(top, #ebf0f5 0%,#d5e0ea 100%); /* IE10+ */
-	background: linear-gradient(top, #ebf0f5 0%,#d5e0ea 100%); /* W3C */
-	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ebf0f5', endColorstr='#d5e0ea',GradientType=0 ); /* IE6-9 */
-}
-.claro .ui-widget-header .dgrid-cell:hover {
-	background: #ebf1f6; /* Old browsers */
-	background: -moz-linear-gradient(top, #ffffff 0%, #d2e0eb 100%); /* FF3.6+ */
-	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#d2e0eb)); /* Chrome,Safari4+ */
-	background: -webkit-linear-gradient(top, #ffffff 0%,#d2e0eb 100%); /* Chrome10+,Safari5.1+ */
-	background: -o-linear-gradient(top, #ffffff 0%,#d2e0eb 100%); /* Opera 11.10+ */
-	background: -ms-linear-gradient(top, #ffffff 0%,#d2e0eb 100%); /* IE10+ */
-	background: linear-gradient(top, #ffffff 0%,#d2e0eb 100%); /* W3C */
-}
-
-.claro .ui-state-default { 
-	-webkit-transition-duration: 0.2s;
-	-moz-transition-duration: 0.2s;
-	-o-transition-duration: 0.2s;
-	transition-duration: 0.2s;
-	-webkit-transition-property: background-color, border-color;
-	-moz-transition-property: background-color, border-color;
-	-o-transition-property: background-color, border-color;
-	transition-property: background-color, border-color;
-	background: url("images/row_back.png") #fff repeat-x;
-}
-.has-ie-6 .claro .ui-state-default {
-	background-image: none;
-}
-.claro .ui-state-default:hover {
-	background-color: #e9f2fe;
-}
-
-.claro .ui-state-active {
-	background-color: #cee6fa;
-}
-
-.claro .ui-state-active:hover {
-	background-color: #9bc6f2;
-}
-
-.claro .ui-state-highlight {
-	background-color: #ff6;
-}
-
-.claro .dgrid-cell {
-	border-color: #edc;
-}
-
-.claro .ui-widget-header .dgrid-cell {
-	border-color: #bbb;
-}

BIN
esp/files/dgrid/css/skins/images/row_back.png


+ 0 - 38
esp/files/dgrid/css/skins/nihilo.css

@@ -1,38 +0,0 @@
-.nihilo .dgrid {
-	border-color: #bba;
-}
-
-.nihilo .ui-widget-content {
-	background: #fff;
-	color: #000;
-}
-.nihilo .ui-widget-header {
-	background: #fff;
-	border-bottom-color: #919191;
-}
-.nihilo .dgrid-footer {
-	background: #fff;
-	border-top: 1px solid #919191;
-}
-.nihilo .dgrid-header .dgrid-cell {
-	border-right-color: #acab99;
-}
-
-.nihilo .ui-state-active {
-	background-color: #aec7e3;
-}
-.nihilo .ui-state-default:hover {
-	background-color: #ffe284;
-}
-
-.nihilo .ui-state-highlight {
-	background-color: #ff6;
-}
-
-.nihilo .dgrid-cell {
-	border-color: #ddc;
-}
-
-.nihilo .ui-widget-header .dgrid-cell {
-	border-color: #bba;
-}

+ 0 - 86
esp/files/dgrid/css/skins/sage.css

@@ -1,86 +0,0 @@
-.sage .ui-widget-content {
-	border: none;
-	background: #fff;
-	color: #000;
-	text-shadow: 0 1px 0 rgba(255,255,255,.9);
-}
-
-.sage .dgrid-header-row {
-	border-bottom: none;
-}
-
-.sage .ui-widget-header, .sage .dgrid-footer {
-	color: #fff;
-	background: #333; /* Old browsers */
-	background: -moz-linear-gradient(top, #4e4e4e 0%, #555555 12%, #636363 25%, #505050 39%, #303030 49%, #000000 50%, #1c1c1c 60%, #292929 76%, #1e1e1e 91%, #141414 100%); /* FF3.6+ */
-	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4e4e4e), color-stop(12%,#555555), color-stop(25%,#636363), color-stop(39%,#505050), color-stop(49%,#303030), color-stop(50%,#000000), color-stop(60%,#1c1c1c), color-stop(76%,#292929), color-stop(91%,#1e1e1e), color-stop(100%,#141414)); /* Chrome,Safari4+ */
-	background: -webkit-linear-gradient(top, #4e4e4e 0%,#555555 12%,#636363 25%,#505050 39%,#303030 49%,#000000 50%,#1c1c1c 60%,#292929 76%,#1e1e1e 91%,#141414 100%); /* Chrome10+,Safari5.1+ */
-	background: -o-linear-gradient(top, #4e4e4e 0%,#555555 12%,#636363 25%,#505050 39%,#303030 49%,#000000 50%,#1c1c1c 60%,#292929 76%,#1e1e1e 91%,#141414 100%); /* Opera 11.10+ */
-	background: -ms-linear-gradient(top, #4e4e4e 0%,#555555 12%,#636363 25%,#505050 39%,#303030 49%,#000000 50%,#1c1c1c 60%,#292929 76%,#1e1e1e 91%,#141414 100%); /* IE10+ */
-	background: linear-gradient(top, #4e4e4e 0%,#555555 12%,#636363 25%,#505050 39%,#303030 49%,#000000 50%,#1c1c1c 60%,#292929 76%,#1e1e1e 91%,#141414 100%); /* W3C */
-	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4e4e4e', endColorstr='#141414',GradientType=0 ); /* IE6-9 */
-}
-
-.sage .ui-widget-header th {
-	padding: 7px 3px;
-	font-weight: bold;
-	color: #fff;
-	text-shadow: 0 -1px 0 rgba(0,0,0,.9);
-	border-color: #111;
-	text-transform: uppercase;
-}
-
-.sage .dgrid-cell {
-	border-color: #bbc581;
-	border-top: none;
-	border-right: none;
-	border-left: none;
-}
-
-.sage .dgrid-row-odd {
-	background: #f2f7e8;
-}
-
-.sage .dgrid-row:hover {
-	background: #c5dca6;
-	color: #333;
-	text-shadow: 0 1px 0 rgba(255,255,255,.5);
-}
-
-.sage .ui-state-default { 
-	-webkit-transition-duration: 0.1s;
-	-moz-transition-duration: 0.1s;
-	transition-duration: 0.1s;
-	-webkit-transition-property: background-color, border-color;
-	-moz-transition-property: background-color, border-color;
-	transition-property: background-color, border-color;
-}
-
-.sage .dgrid-selected,
-.sage .dgrid-selected:hover {
-	background: #b3d18b;
-	text-shadow: 0 1px 0 rgba(255,255,255,.6);
-}
-
-.sage .ui-state-highlight {
-	background-color: #d5e8bd;
-}
-
-/* need to use white-based image for sort arrow */
-.sage .dgrid-sort-arrow {
-	background-image: url("../images/ui-icons_222222_256x240_white.png");
-}
-
-/* for ColumnReorder */
-.sage .dgrid-header .dojoDndItemBefore {
-	border-left: 2px dotted #fff !important;
-}
-.sage .dgrid-header .dojoDndItemAfter {
-	border-right: 2px dotted #fff !important;
-}
-
-/* for pagination in IE < 8 + quirks, need additional rule to override link color */
-.has-ie-6-7 .sage .dgrid-navigation a,
-.has-ie.has-quirks .sage .dgrid-navigation a {
-	color: #fff;
-}

+ 0 - 68
esp/files/dgrid/css/skins/slate.css

@@ -1,68 +0,0 @@
-.slate .ui-widget-content {
-	background: #fff; 
-	color: #000;
-	text-shadow: 0 1px 0 rgba(255,255,255,.9);
-}
-
-.slate .dgrid-header-row {
-	border-bottom: none;
-}
-
-.slate .ui-widget-header, .slate .dgrid-footer {
-	color: #fff;
-	background: #333; /* Old browsers */
-	background: -moz-linear-gradient(top, #4e4e4e 0%, #555555 12%, #636363 25%, #505050 39%, #303030 49%, #000000 50%, #1c1c1c 60%, #292929 76%, #1e1e1e 91%, #141414 100%); /* FF3.6+ */
-	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4e4e4e), color-stop(12%,#555555), color-stop(25%,#636363), color-stop(39%,#505050), color-stop(49%,#303030), color-stop(50%,#000000), color-stop(60%,#1c1c1c), color-stop(76%,#292929), color-stop(91%,#1e1e1e), color-stop(100%,#141414)); /* Chrome,Safari4+ */
-	background: -webkit-linear-gradient(top, #4e4e4e 0%,#555555 12%,#636363 25%,#505050 39%,#303030 49%,#000000 50%,#1c1c1c 60%,#292929 76%,#1e1e1e 91%,#141414 100%); /* Chrome10+,Safari5.1+ */
-	background: -o-linear-gradient(top, #4e4e4e 0%,#555555 12%,#636363 25%,#505050 39%,#303030 49%,#000000 50%,#1c1c1c 60%,#292929 76%,#1e1e1e 91%,#141414 100%); /* Opera 11.10+ */
-	background: -ms-linear-gradient(top, #4e4e4e 0%,#555555 12%,#636363 25%,#505050 39%,#303030 49%,#000000 50%,#1c1c1c 60%,#292929 76%,#1e1e1e 91%,#141414 100%); /* IE10+ */
-	background: linear-gradient(top, #4e4e4e 0%,#555555 12%,#636363 25%,#505050 39%,#303030 49%,#000000 50%,#1c1c1c 60%,#292929 76%,#1e1e1e 91%,#141414 100%); /* W3C */
-	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4e4e4e', endColorstr='#141414',GradientType=0 ); /* IE6-9 */
-}
-
-.slate .ui-widget-header th {
-	padding: 7px 3px;
-	font-weight: bold;
-	color: #FFF;
-	text-shadow: 0 -1px 0 rgba(0,0,0,.9);
-	border-color: #111;
-	text-transform: uppercase;
-}
-
-.slate .dgrid-row-odd { 
-	background-color: #f7f7f7;
-}
-
-.slate .dgrid-row:hover {
-	background-color: #ddd;
-}
-
-.slate .ui-state-active,
-.slate .ui-state-active:hover {
-	background-color: #555;
-	color: #fff;
-	text-shadow: 0 -1px 0 rgba(0,0,0,.5);	
-}
-
-.slate .ui-state-highlight {
-	background-color: #999;
-}
-
-/* need to use white-based image for sort arrow */
-.slate .dgrid-sort-arrow {
-	background-image: url("../images/ui-icons_222222_256x240_white.png");
-}
-
-/* for ColumnReorder */
-.slate .dgrid-header .dojoDndItemBefore {
-	border-left: 2px dotted #fff !important;
-}
-.slate .dgrid-header .dojoDndItemAfter {
-	border-right: 2px dotted #fff !important;
-}
-
-/* for pagination in IE < 8 + quirks, need additional rule to override link color */
-.has-ie-6-7 .slate .dgrid-navigation a,
-.has-ie.has-quirks .slate .dgrid-navigation a {
-	color: #fff;
-}

+ 0 - 46
esp/files/dgrid/css/skins/soria.css

@@ -1,46 +0,0 @@
-.soria .dgrid {
-	border-color: #bba;
-}
-
-.soria .ui-widget-content {
-	background: #fff;
-	color: #000;
-}
-.soria .ui-widget-header, .soria .dgrid-footer {
-	background: #f2f4fe; /* Old browsers */
-	background: -moz-linear-gradient(top, #f2f4fe 0%, #d0dff5 50%, #c6d8f0 51%, #c2d5ef 100%); /* FF3.6+ */
-	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f2f4fe), color-stop(50%,#d0dff5), color-stop(51%,#c6d8f0), color-stop(100%,#c2d5ef)); /* Chrome,Safari4+ */
-	background: -webkit-linear-gradient(top, #f2f4fe 0%,#d0dff5 50%,#c6d8f0 51%,#c2d5ef 100%); /* Chrome10+,Safari5.1+ */
-	background: -o-linear-gradient(top, #f2f4fe 0%,#d0dff5 50%,#c6d8f0 51%,#c2d5ef 100%); /* Opera 11.10+ */
-	background: -ms-linear-gradient(top, #f2f4fe 0%,#d0dff5 50%,#c6d8f0 51%,#c2d5ef 100%); /* IE10+ */
-	background: linear-gradient(top, #f2f4fe 0%,#d0dff5 50%,#c6d8f0 51%,#c2d5ef 100%); /* W3C */
-	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2f4fe', endColorstr='#c2d5ef',GradientType=0 ); /* IE6-9 */
-}
-.soria .ui-widget-header th:hover {
-	background: #d4deec; /* Old browsers */
-	background: -moz-linear-gradient(top, #dae2ed 0%, #b2c7e8 49%, #a8c1eb 50%, #9ebaec 100%); /* FF3.6+ */
-	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#dae2ed), color-stop(49%,#b2c7e8), color-stop(50%,#a8c1eb), color-stop(100%,#9ebaec)); /* Chrome,Safari4+ */
-	background: -webkit-linear-gradient(top, #dae2ed 0%,#b2c7e8 49%,#a8c1eb 50%,#9ebaec 100%); /* Chrome10+,Safari5.1+ */
-	background: -o-linear-gradient(top, #dae2ed 0%,#b2c7e8 49%,#a8c1eb 50%,#9ebaec 100%); /* Opera 11.10+ */
-	background: -ms-linear-gradient(top, #dae2ed 0%,#b2c7e8 49%,#a8c1eb 50%,#9ebaec 100%); /* IE10+ */
-	background: linear-gradient(top, #dae2ed 0%,#b2c7e8 49%,#a8c1eb 50%,#9ebaec 100%); /* W3C */
-}
-
-.soria .ui-state-active {
-	background-color: #aec7e3;
-}
-.soria .ui-state-default:hover {
-	background-color: #60a1ea;
-}
-
-.soria .ui-state-highlight {
-	background-color: #ff6;
-}
-
-.soria .dgrid-cell {
-	border-color: #ddc;
-}
-
-.soria .ui-widget-header .dgrid-cell {
-	border-color: #bba;
-}

+ 0 - 84
esp/files/dgrid/css/skins/squid.css

@@ -1,84 +0,0 @@
-.squid .ui-widget-content {
-	border: 1px solid #555;
-	background: #000;
-	color: #fff;
-	text-shadow: 0 -1px 0 rgba(0,0,0,.7);
-}
-.squid .ui-icon {
-	background-image: url("../images/ui-icons_222222_256x240_white.png");
-}
-
-.squid .dgrid-header {
-	padding: 0 1px; /* add side padding to align with borders on content area */
-}
-
-.squid .ui-widget-header, .squid .dgrid-footer {
-	color: #fff;
-	background: #2d1f14; /* Old browsers */
-	background: -moz-linear-gradient(top, #140e09 0%, #2d1f14 100%); /* FF3.6+ */
-	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#140e09), color-stop(100%,#2d1f14)); /* Chrome,Safari4+ */
-	background: -webkit-linear-gradient(top, #140e09 0%,#2d1f14 100%); /* Chrome10+,Safari5.1+ */
-	background: -o-linear-gradient(top, #140e09 0%,#2d1f14 100%); /* Opera 11.10+ */
-	background: -ms-linear-gradient(top, #140e09 0%,#2d1f14 100%); /* IE10+ */
-	background: linear-gradient(top, #140e09 0%,#2d1f14 100%); /* W3C */
-	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#140e09', endColorstr='#2d1f14',GradientType=0 ); /* IE6-9 */
-	color: #fff;
-	font-weight: bold;
-}
-.squid .ui-widget-header:hover {
-	background: #000; /* Old browsers */
-	background: -moz-linear-gradient(top, #000000 0%, #2d1f14 100%); /* FF3.6+ */
-	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#000000), color-stop(100%,#2d1f14)); /* Chrome,Safari4+ */
-	background: -webkit-linear-gradient(top, #000000 0%,#2d1f14 100%); /* Chrome10+,Safari5.1+ */
-	background: -o-linear-gradient(top, #000000 0%,#2d1f14 100%); /* Opera 11.10+ */
-	background: -ms-linear-gradient(top, #000000 0%,#2d1f14 100%); /* IE10+ */
-	background: linear-gradient(top, #000000 0%,#2d1f14 100%); /* W3C */
-}
-
-.squid .ui-state-default {
-	-webkit-transition-duration: 0.2s;
-	-moz-transition-duration: 0.2s;
-	transition-duration: 0.2s;
-	-webkit-transition-property: background-color, border-color;
-	-moz-transition-property: background-color, border-color;
-	transition-property: background-color, border-color;
-	background: url("images/row_back.png") #000 repeat-x;
-}
-.squid .ui-state-default:hover {
-	background-color: #444;
-}
-
-.has-ie-6 .squid .ui-state-default {
-	background-image: none;
-}
-
-.squid .ui-state-active {
-	background-color: #64390d;
-	text-shadow: 0 -1px 0 rgba(0,0,0,.3);
-}
-
-.squid .ui-state-active:hover {
-	background-color: #8b6b4a;
-}
-
-.squid .ui-state-highlight {
-	background-color: #666;
-}
-
-.squid .dgrid-cell {
-	border-color: #ccc;
-}
-
-/* for ColumnReorder */
-.squid .dgrid-header .dojoDndItemBefore {
-	border-left: 2px dotted #fff !important;
-}
-.squid .dgrid-header .dojoDndItemAfter {
-	border-right: 2px dotted #fff !important;
-}
-
-/* for pagination in IE < 8 + quirks, need additional rule to override link color */
-.has-ie-6-7 .squid .dgrid-navigation a,
-.has-ie.has-quirks .squid .dgrid-navigation a {
-	color: #fff;
-}

+ 0 - 48
esp/files/dgrid/css/skins/tundra.css

@@ -1,48 +0,0 @@
-.tundra .dgrid {
-	border-color: #bba;
-}
-
-.tundra .ui-widget-content {
-	background: #fff;
-	color: #000;
-}
-
-.tundra .ui-widget-header, .tundra .dgrid-footer {
-	background: #e8e8e8; /* Old browsers */
-	background: -moz-linear-gradient(top, #ffffff 0%, #e8e8e8 100%); /* FF3.6+ */
-	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#e8e8e8)); /* Chrome,Safari4+ */
-	background: -webkit-linear-gradient(top, #ffffff 0%,#e8e8e8 100%); /* Chrome10+,Safari5.1+ */
-	background: -o-linear-gradient(top, #ffffff 0%,#e8e8e8 100%); /* Opera 11.10+ */
-	background: -ms-linear-gradient(top, #ffffff 0%,#e8e8e8 100%); /* IE10+ */
-	background: linear-gradient(top, #ffffff 0%,#e8e8e8 100%); /* W3C */
-	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#e8e8e8',GradientType=0 ); /* IE6-9 */
-	font-weight: bold;
-}
-.tundra .ui-widget-header th:hover {
-	background: #f6f6f6; /* Old browsers */
-	background: -moz-linear-gradient(top, #ffffff 0%, #eeeeee 100%); /* FF3.6+ */
-	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#eeeeee)); /* Chrome,Safari4+ */
-	background: -webkit-linear-gradient(top, #ffffff 0%,#eeeeee 100%); /* Chrome10+,Safari5.1+ */
-	background: -o-linear-gradient(top, #ffffff 0%,#eeeeee 100%); /* Opera 11.10+ */
-	background: -ms-linear-gradient(top, #ffffff 0%,#eeeeee 100%); /* IE10+ */
-	background: linear-gradient(top, #ffffff 0%,#eeeeee 100%); /* W3C */
-}
-
-.tundra .ui-state-active {
-	background-color: #aec7e3;
-}
-.tundra .ui-state-default:hover {
-	background-color: #60a1ea;
-}
-
-.tundra .ui-state-highlight {
-	background-color: #ff6;
-}
-
-.tundra .dgrid-cell {
-	border-color: #ddc;
-}
-
-.tundra .ui-widget-header .dgrid-cell {
-	border-color: #bba;
-}

+ 0 - 143
esp/files/dgrid/demos/dTuned/data.js

@@ -1,143 +0,0 @@
-define(["dojo/store/Memory", "dojo/store/Observable"], function(Memory, Observable){
-	//	create some song data, and return a Memory Store from it.
-	var data = {
-		identifier: "Key",
-		label: "Name",
-		items: [
-			{"Key":"1","Name":"Grind","Artist":"Alice In Chains","Album":"Alice In Chains","Genre":"Alternative","Time":"284","TrackNumber":"1","Year":"1995"},
-			{"Key":"2","Name":"Brush Away","Artist":"Alice In Chains","Album":"Alice In Chains","Genre":"Alternative","Time":"202","TrackNumber":"2","Year":"1995"},
-			{"Key":"3","Name":"Sludge Factory","Artist":"Alice In Chains","Album":"Alice In Chains","Genre":"Alternative","Time":"432","TrackNumber":"3","Year":"1995"},
-			{"Key":"4","Name":"Heaven Beside You","Artist":"Alice In Chains","Album":"Alice In Chains","Genre":"Alternative","Time":"327","TrackNumber":"4","Year":"1995"},
-			{"Key":"5","Name":"Head Creeps","Artist":"Alice In Chains","Album":"Alice In Chains","Genre":"Alternative","Time":"388","TrackNumber":"5","Year":"1995"},
-			{"Key":"6","Name":"Again","Artist":"Alice In Chains","Album":"Alice In Chains","Genre":"Alternative","Time":"245","TrackNumber":"6","Year":"1995"},
-			{"Key":"7","Name":"Shame In You","Artist":"Alice In Chains","Album":"Alice In Chains","Genre":"Alternative","Time":"335","TrackNumber":"7","Year":"1995"},
-			{"Key":"8","Name":"God Am","Artist":"Alice In Chains","Album":"Alice In Chains","Genre":"Alternative","Time":"248","TrackNumber":"8","Year":"1995"},
-			{"Key":"9","Name":"So Close","Artist":"Alice In Chains","Album":"Alice In Chains","Genre":"Alternative","Time":"165","TrackNumber":"9","Year":"1995"},
-			{"Key":"10","Name":"Nothin' Song","Artist":"Alice In Chains","Album":"Alice In Chains","Genre":"Alternative","Time":"340","TrackNumber":"10","Year":"1995"},
-			{"Key":"11","Name":"Frogs","Artist":"Alice In Chains","Album":"Alice In Chains","Genre":"Alternative","Time":"498","TrackNumber":"11","Year":"1995"},
-			{"Key":"12","Name":"Over Now","Artist":"Alice In Chains","Album":"Alice In Chains","Genre":"Alternative","Time":"423","TrackNumber":"12","Year":"1995"},
-			{"Key":"13","Name":"Man In the Box","Artist":"Alice In Chains","Album":"Facelift","Genre":"Alternative","Time":"284","TrackNumber":"2","Year":"1990"},
-			{"Key":"14","Name":"Get Born Again","Artist":"Alice In Chains","Album":"Music Bank","Genre":"Alternative","Time":"324","TrackNumber":"1","Year":"1999"},
-			{"Key":"15","Name":"Tempting Time","Artist":"Animals As Leaders","Album":"Animals As Leaders","Genre":"Rock","Time":"323","TrackNumber":"1","Year":"2009"},
-			{"Key":"16","Name":"Soraya","Artist":"Animals As Leaders","Album":"Animals As Leaders","Genre":"Rock","Time":"266","TrackNumber":"2","Year":"2009"},
-			{"Key":"17","Name":"Thoroughly At Home","Artist":"Animals As Leaders","Album":"Animals As Leaders","Genre":"Rock","Time":"241","TrackNumber":"3","Year":"2009"},
-			{"Key":"18","Name":"On Impulse","Artist":"Animals As Leaders","Album":"Animals As Leaders","Genre":"Rock","Time":"369","TrackNumber":"4","Year":"2009"},
-			{"Key":"19","Name":"Tessitura","Artist":"Animals As Leaders","Album":"Animals As Leaders","Genre":"Rock","Time":"66","TrackNumber":"5","Year":"2009"},
-			{"Key":"20","Name":"Behaving Badly","Artist":"Animals As Leaders","Album":"Animals As Leaders","Genre":"Rock","Time":"266","TrackNumber":"6","Year":"2009"},
-			{"Key":"21","Name":"The Price of Everything and the Value of Nothing","Artist":"Animals As Leaders","Album":"Animals As Leaders","Genre":"Rock","Time":"332","TrackNumber":"7","Year":"2009"},
-			{"Key":"22","Name":"CAFO","Artist":"Animals As Leaders","Album":"Animals As Leaders","Genre":"Rock","Time":"401","TrackNumber":"8","Year":"2009"},
-			{"Key":"23","Name":"Inamorata","Artist":"Animals As Leaders","Album":"Animals As Leaders","Genre":"Rock","Time":"368","TrackNumber":"9","Year":"2009"},
-			{"Key":"24","Name":"Point to Point","Artist":"Animals As Leaders","Album":"Animals As Leaders","Genre":"Rock","Time":"104","TrackNumber":"10","Year":"2009"},
-			{"Key":"25","Name":"Modern Meat","Artist":"Animals As Leaders","Album":"Animals As Leaders","Genre":"Rock","Time":"126","TrackNumber":"11","Year":"2009"},
-			{"Key":"26","Name":"Song of Solomon","Artist":"Animals As Leaders","Album":"Animals As Leaders","Genre":"Rock","Time":"256","TrackNumber":"12","Year":"2009"},
-			{"Key":"27","Name":"Hunter","Artist":"Bjork","Album":"Homogenic","Genre":"Electronica","Time":"255","TrackNumber":"1","Year":"1997"},
-			{"Key":"28","Name":"J\u00c3\u00b2ga","Artist":"Bjork","Album":"Homogenic","Genre":"Electronica","Time":"305","TrackNumber":"2","Year":"1997"},
-			{"Key":"29","Name":"Unravel","Artist":"Bjork","Album":"Homogenic","Genre":"Electronica","Time":"201","TrackNumber":"3","Year":"1997"},
-			{"Key":"30","Name":"Bachelorette","Artist":"Bjork","Album":"Homogenic","Genre":"Electronica","Time":"312","TrackNumber":"4","Year":"1997"},
-			{"Key":"31","Name":"All Neon Like","Artist":"Bjork","Album":"Homogenic","Genre":"Electronica","Time":"352","TrackNumber":"5","Year":"1997"},
-			{"Key":"32","Name":"5 Years","Artist":"Bjork","Album":"Homogenic","Genre":"Electronica","Time":"268","TrackNumber":"6","Year":"1997"},
-			{"Key":"33","Name":"Immature","Artist":"Bjork","Album":"Homogenic","Genre":"Electronica","Time":"186","TrackNumber":"7","Year":"1997"},
-			{"Key":"34","Name":"Alarm Call","Artist":"Bjork","Album":"Homogenic","Genre":"Electronica","Time":"259","TrackNumber":"8","Year":"1997"},
-			{"Key":"35","Name":"Pluto","Artist":"Bjork","Album":"Homogenic","Genre":"Electronica","Time":"199","TrackNumber":"9","Year":"1997"},
-			{"Key":"36","Name":"All Is Full of Love","Artist":"Bjork","Album":"Homogenic","Genre":"Electronica","Time":"272","TrackNumber":"10","Year":"1997"},
-			{"Key":"37","Name":"Sunday","Artist":"David Bowie","Album":"Heathen","Genre":"Progressive Rock","Time":"285","TrackNumber":"1","Year":"2002"},
-			{"Key":"38","Name":"Cactus","Artist":"David Bowie","Album":"Heathen","Genre":"Progressive Rock","Time":"174","TrackNumber":"2","Year":"2002"},
-			{"Key":"39","Name":"Slip Away","Artist":"David Bowie","Album":"Heathen","Genre":"Progressive Rock","Time":"364","TrackNumber":"3","Year":"2002"},
-			{"Key":"40","Name":"Slow Burn","Artist":"David Bowie","Album":"Heathen","Genre":"Progressive Rock","Time":"281","TrackNumber":"4","Year":"2002"},
-			{"Key":"41","Name":"Afraid","Artist":"David Bowie","Album":"Heathen","Genre":"Progressive Rock","Time":"208","TrackNumber":"5","Year":"2002"},
-			{"Key":"42","Name":"I've Been Waiting For You","Artist":"David Bowie","Album":"Heathen","Genre":"Progressive Rock","Time":"180","TrackNumber":"6","Year":"2002"},
-			{"Key":"43","Name":"I Would Be Your Slave","Artist":"David Bowie","Album":"Heathen","Genre":"Progressive Rock","Time":"313","TrackNumber":"7","Year":"2002"},
-			{"Key":"44","Name":"I Took A Trip On A Gemini Spaceship","Artist":"David Bowie","Album":"Heathen","Genre":"Progressive Rock","Time":"246","TrackNumber":"8","Year":"2002"},
-			{"Key":"45","Name":"5:15 The Angels Have Gone","Artist":"David Bowie","Album":"Heathen","Genre":"Progressive Rock","Time":"301","TrackNumber":"9","Year":"2002"},
-			{"Key":"46","Name":"Everyone Says 'Hi'","Artist":"David Bowie","Album":"Heathen","Genre":"Progressive Rock","Time":"237","TrackNumber":"10","Year":"2002"},
-			{"Key":"47","Name":"A Better Future","Artist":"David Bowie","Album":"Heathen","Genre":"Progressive Rock","Time":"251","TrackNumber":"11","Year":"2002"},
-			{"Key":"48","Name":"Heathen (The Rays)","Artist":"David Bowie","Album":"Heathen","Genre":"Progressive Rock","Time":"256","TrackNumber":"12","Year":"2002"},
-			{"Key":"49","Name":"The New Bison","Artist":"Happy Apple","Album":"Happy Apple Back On Top","Genre":"Jazz","Time":"290","TrackNumber":"1","Year":"2007"},
-			{"Key":"50","Name":"Very Small Rock","Artist":"Happy Apple","Album":"Happy Apple Back On Top","Genre":"Jazz","Time":"300","TrackNumber":"2","Year":"2007"},
-			{"Key":"51","Name":"1996 A.D.","Artist":"Happy Apple","Album":"Happy Apple Back On Top","Genre":"Jazz","Time":"274","TrackNumber":"3","Year":"2007"},
-			{"Key":"52","Name":"Rise! Marc Anthony","Artist":"Happy Apple","Album":"Happy Apple Back On Top","Genre":"Jazz","Time":"432","TrackNumber":"4","Year":"2007"},
-			{"Key":"53","Name":"Calgon for Hetfield","Artist":"Happy Apple","Album":"Happy Apple Back On Top","Genre":"Jazz","Time":"325","TrackNumber":"5","Year":"2007"},
-			{"Key":"54","Name":"Lefse los Cubanos","Artist":"Happy Apple","Album":"Happy Apple Back On Top","Genre":"Jazz","Time":"337","TrackNumber":"6","Year":"2007"},
-			{"Key":"55","Name":"He's OK","Artist":"Happy Apple","Album":"Happy Apple Back On Top","Genre":"Jazz","Time":"379","TrackNumber":"7","Year":"2007"},
-			{"Key":"56","Name":"Brown Lights","Artist":"Happy Apple","Album":"Happy Apple Back On Top","Genre":"Jazz","Time":"431","TrackNumber":"8","Year":"2007"},
-			{"Key":"57","Name":"Hence the Turtleneck","Artist":"Happy Apple","Album":"Happy Apple Back On Top","Genre":"Jazz","Time":"331","TrackNumber":"9","Year":"2007"},
-			{"Key":"58","Name":"Most Popular to Succeed","Artist":"Happy Apple","Album":"Happy Apple Back On Top","Genre":"Jazz","Time":"545","TrackNumber":"10","Year":"2007"},
-			{"Key":"59","Name":"Density In Dan's Fan City","Artist":"Happy Apple","Album":"Happy Apple Back On Top","Genre":"Jazz","Time":"424","TrackNumber":"11","Year":"2007"},
-			{"Key":"60","Name":"Take Wes Chandler For Instance","Artist":"Happy Apple","Album":"Please Refrain From Fronting","Genre":"Jazz","Time":"329","TrackNumber":"1","Year":"2001"},
-			{"Key":"61","Name":"You & Mattel Vs Me & Coleco","Artist":"Happy Apple","Album":"Please Refrain From Fronting","Genre":"Jazz","Time":"332","TrackNumber":"2","Year":"2001"},
-			{"Key":"62","Name":"Who Is Your Midwest Representation?","Artist":"Happy Apple","Album":"Please Refrain From Fronting","Genre":"Jazz","Time":"179","TrackNumber":"3","Year":"2001"},
-			{"Key":"63","Name":"November","Artist":"Happy Apple","Album":"Please Refrain From Fronting","Genre":"Jazz","Time":"337","TrackNumber":"4","Year":"2001"},
-			{"Key":"64","Name":"The Invasion Has Become","Artist":"Happy Apple","Album":"Please Refrain From Fronting","Genre":"Jazz","Time":"358","TrackNumber":"5","Year":"2001"},
-			{"Key":"65","Name":"A Waltz For The Few Remaining","Artist":"Happy Apple","Album":"Please Refrain From Fronting","Genre":"Jazz","Time":"478","TrackNumber":"6","Year":"2001"},
-			{"Key":"66","Name":"Homage Ritchie Valens","Artist":"Happy Apple","Album":"Please Refrain From Fronting","Genre":"Jazz","Time":"315","TrackNumber":"7","Year":"2001"},
-			{"Key":"67","Name":"Acknowledge The Ascot","Artist":"Happy Apple","Album":"Please Refrain From Fronting","Genre":"Jazz","Time":"540","TrackNumber":"8","Year":"2001"},
-			{"Key":"68","Name":"Koala Bear Wearing A T-Shirt With Your Corporate Logo","Artist":"Happy Apple","Album":"Please Refrain From Fronting","Genre":"Jazz","Time":"245","TrackNumber":"9","Year":"2001"},
-			{"Key":"69","Name":"Buffalo '98","Artist":"Happy Apple","Album":"Please Refrain From Fronting","Genre":"Jazz","Time":"793","TrackNumber":"10","Year":"2001"},
-			{"Key":"70","Name":"Long Live Rock & Roll","Artist":"Happy Apple","Album":"Please Refrain From Fronting","Genre":"Jazz","Time":"170","TrackNumber":"11","Year":"2001"},
-			{"Key":"71","Name":"Take a Bow","Artist":"Muse","Album":"Black Holes and Revelations","Genre":"Alternative","Time":"275","TrackNumber":"1","Year":"2006"},
-			{"Key":"72","Name":"Starlight","Artist":"Muse","Album":"Black Holes and Revelations","Genre":"Alternative","Time":"239","TrackNumber":"2","Year":"2006"},
-			{"Key":"73","Name":"Supermassive Black Hole","Artist":"Muse","Album":"Black Holes and Revelations","Genre":"Alternative","Time":"210","TrackNumber":"3","Year":"2006"},
-			{"Key":"74","Name":"Map of the Problematique","Artist":"Muse","Album":"Black Holes and Revelations","Genre":"Alternative","Time":"258","TrackNumber":"4","Year":"2006"},
-			{"Key":"75","Name":"Soldier's Poem","Artist":"Muse","Album":"Black Holes and Revelations","Genre":"Alternative","Time":"124","TrackNumber":"5","Year":"2006"},
-			{"Key":"76","Name":"Invincible","Artist":"Muse","Album":"Black Holes and Revelations","Genre":"Alternative","Time":"300","TrackNumber":"6","Year":"2006"},
-			{"Key":"77","Name":"Assassin","Artist":"Muse","Album":"Black Holes and Revelations","Genre":"Alternative","Time":"211","TrackNumber":"7","Year":"2006"},
-			{"Key":"78","Name":"Exo-Politics","Artist":"Muse","Album":"Black Holes and Revelations","Genre":"Alternative","Time":"233","TrackNumber":"8","Year":"2006"},
-			{"Key":"79","Name":"City of Delusion","Artist":"Muse","Album":"Black Holes and Revelations","Genre":"Alternative","Time":"288","TrackNumber":"9","Year":"2006"},
-			{"Key":"80","Name":"Hoodoo","Artist":"Muse","Album":"Black Holes and Revelations","Genre":"Alternative","Time":"223","TrackNumber":"10","Year":"2006"},
-			{"Key":"81","Name":"Knights of Cydonia","Artist":"Muse","Album":"Black Holes and Revelations","Genre":"Alternative","Time":"367","TrackNumber":"11","Year":"2006"},
-			{"Key":"82","Name":"Glorious","Artist":"Muse","Album":"Black Holes and Revelations","Genre":"Alternative","Time":"281","TrackNumber":"12","Year":"2006"},
-			{"Key":"83","Name":"Rolling","Artist":"Soul Coughing","Album":"El Oso","Genre":"Indie","Time":"216","TrackNumber":"1","Year":""},
-			{"Key":"84","Name":"Misinformed","Artist":"Soul Coughing","Album":"El Oso","Genre":"Indie","Time":"204","TrackNumber":"2","Year":""},
-			{"Key":"85","Name":"Circles","Artist":"Soul Coughing","Album":"El Oso","Genre":"Indie","Time":"186","TrackNumber":"3","Year":""},
-			{"Key":"86","Name":"Blame","Artist":"Soul Coughing","Album":"El Oso","Genre":"Indie","Time":"300","TrackNumber":"4","Year":""},
-			{"Key":"87","Name":"St. Louise Is Listening","Artist":"Soul Coughing","Album":"El Oso","Genre":"Indie","Time":"268","TrackNumber":"5","Year":""},
-			{"Key":"88","Name":"Maybe I'll Come Down","Artist":"Soul Coughing","Album":"El Oso","Genre":"Indie","Time":"272","TrackNumber":"6","Year":""},
-			{"Key":"89","Name":"Houston","Artist":"Soul Coughing","Album":"El Oso","Genre":"Indie","Time":"243","TrackNumber":"7","Year":""},
-			{"Key":"90","Name":"$300","Artist":"Soul Coughing","Album":"El Oso","Genre":"Indie","Time":"187","TrackNumber":"8","Year":""},
-			{"Key":"91","Name":"Fully Retractable","Artist":"Soul Coughing","Album":"El Oso","Genre":"Indie","Time":"205","TrackNumber":"9","Year":""},
-			{"Key":"92","Name":"Monster Man","Artist":"Soul Coughing","Album":"El Oso","Genre":"Indie","Time":"256","TrackNumber":"10","Year":""},
-			{"Key":"93","Name":"Pensacola","Artist":"Soul Coughing","Album":"El Oso","Genre":"Indie","Time":"255","TrackNumber":"11","Year":""},
-			{"Key":"94","Name":"I Miss the Girl","Artist":"Soul Coughing","Album":"El Oso","Genre":"Indie","Time":"243","TrackNumber":"12","Year":""},
-			{"Key":"95","Name":"So Far I Have Not Found the Sc","Artist":"Soul Coughing","Album":"El Oso","Genre":"Indie","Time":"173","TrackNumber":"13","Year":""},
-			{"Key":"96","Name":"The Incumbent","Artist":"Soul Coughing","Album":"El Oso","Genre":"Indie","Time":"406","TrackNumber":"14","Year":""},
-			{"Key":"97","Name":"Futures","Artist":"Zero 7","Album":"The Garden","Genre":"Trip-Hop","Time":"229","TrackNumber":"1","Year":"2006"},
-			{"Key":"98","Name":"Throw it all away","Artist":"Zero 7","Album":"The Garden","Genre":"Trip-Hop","Time":"320","TrackNumber":"2","Year":"2006"},
-			{"Key":"99","Name":"Seeing things","Artist":"Zero 7","Album":"The Garden","Genre":"Trip-Hop","Time":"309","TrackNumber":"3","Year":"2006"},
-			{"Key":"100","Name":"The pageant of the bizarre","Artist":"Zero 7","Album":"The Garden","Genre":"Trip-Hop","Time":"261","TrackNumber":"4","Year":"2006"},
-			{"Key":"101","Name":"You're my flame","Artist":"Zero 7","Album":"The Garden","Genre":"Trip-Hop","Time":"195","TrackNumber":"5","Year":"2006"},
-			{"Key":"102","Name":"Left behind","Artist":"Zero 7","Album":"The Garden","Genre":"Trip-Hop","Time":"75","TrackNumber":"6","Year":"2006"},
-			{"Key":"103","Name":"Today","Artist":"Zero 7","Album":"The Garden","Genre":"Trip-Hop","Time":"243","TrackNumber":"7","Year":"2006"},
-			{"Key":"104","Name":"This fine social scene","Artist":"Zero 7","Album":"The Garden","Genre":"Trip-Hop","Time":"267","TrackNumber":"8","Year":"2006"},
-			{"Key":"105","Name":"Your place","Artist":"Zero 7","Album":"The Garden","Genre":"Trip-Hop","Time":"361","TrackNumber":"9","Year":"2006"},
-			{"Key":"106","Name":"If I can't have you","Artist":"Zero 7","Album":"The Garden","Genre":"Trip-Hop","Time":"202","TrackNumber":"10","Year":"2006"},
-			{"Key":"107","Name":"Crosses","Artist":"Zero 7","Album":"The Garden","Genre":"Trip-Hop","Time":"399","TrackNumber":"11","Year":"2006"},
-			{"Key":"108","Name":"Waiting to die","Artist":"Zero 7","Album":"The Garden","Genre":"Trip-Hop","Time":"219","TrackNumber":"12","Year":"2006"},
-			{"Key":"109","Name":"I Have Seen","Artist":"Zero 7","Album":"Simple Things","Genre":"Trip-Hop","Time":"307","TrackNumber":"1","Year":"2001"},
-			{"Key":"110","Name":"Polaris","Artist":"Zero 7","Album":"Simple Things","Genre":"Trip-Hop","Time":"288","TrackNumber":"2","Year":"2001"},
-			{"Key":"111","Name":"Destiny","Artist":"Zero 7","Album":"Simple Things","Genre":"Trip-Hop","Time":"337","TrackNumber":"3","Year":"2001"},
-			{"Key":"112","Name":"Give It Away","Artist":"Zero 7","Album":"Simple Things","Genre":"Trip-Hop","Time":"317","TrackNumber":"4","Year":"2001"},
-			{"Key":"113","Name":"Simple Things","Artist":"Zero 7","Album":"Simple Things","Genre":"Trip-Hop","Time":"264","TrackNumber":"5","Year":"2001"},
-			{"Key":"114","Name":"Red Dust","Artist":"Zero 7","Album":"Simple Things","Genre":"Trip-Hop","Time":"340","TrackNumber":"6","Year":"2001"},
-			{"Key":"115","Name":"Distractions","Artist":"Zero 7","Album":"Simple Things","Genre":"Trip-Hop","Time":"316","TrackNumber":"7","Year":"2001"},
-			{"Key":"116","Name":"In The Waiting Line","Artist":"Zero 7","Album":"Simple Things","Genre":"Trip-Hop","Time":"272","TrackNumber":"8","Year":"2001"},
-			{"Key":"117","Name":"Out Of Town","Artist":"Zero 7","Album":"Simple Things","Genre":"Trip-Hop","Time":"287","TrackNumber":"9","Year":"2001"},
-			{"Key":"118","Name":"This World","Artist":"Zero 7","Album":"Simple Things","Genre":"Trip-Hop","Time":"335","TrackNumber":"10","Year":"2001"},
-			{"Key":"119","Name":"Likufanele","Artist":"Zero 7","Album":"Simple Things","Genre":"Trip-Hop","Time":"371","TrackNumber":"11","Year":"2001"},
-			{"Key":"120","Name":"End Theme","Artist":"Zero 7","Album":"Simple Things","Genre":"Trip-Hop","Time":"219","TrackNumber":"12","Year":"2001"},
-			{"Key":"121","Name":"Salt Water Sound","Artist":"Zero 7","Album":"Simple Things","Genre":"Trip-Hop","Time":"330","TrackNumber":"13","Year":"2001"},
-			{"Key":"122","Name":"Spinning","Artist":"Zero 7","Album":"Simple Things","Genre":"Trip-Hop","Time":"363","TrackNumber":"14","Year":"2001"}
-		]
-	};
-
-	//	ugly shortcut, since there's 122 items here and I don't feel like manually editing it.
-	for(var i=0, l=data.items.length; i<l; i++){
-		var item = data.items[i];
-		item.Time = parseInt(item.Time, 10);
-		item.TrackNumber = parseInt(item.TrackNumber, 10);
-		if(item.Year.length){ item.Year = parseInt(item.Year, 10); }
-	}
-
-	// global var "song_store"
-	songStore = Observable(Memory({data: data}));
-	return songStore;
-});

+ 0 - 272
esp/files/dgrid/demos/dTuned/index.html

@@ -1,272 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>dTuned</title>
-		<meta name="viewport" content="width=570">
-		<link rel="stylesheet" href="../../../dojo/resources/dojo.css">
-		<link rel="stylesheet" href="resources/dTuned.css">
-		<style>
-			html, body {
-				width: 100%;
-				height: 100%;
-				overflow: hidden;
-			}
-			body {
-				font-family: "Lucida Grande", sans-serif;
-				font-size: 11px;
-				position: relative;
-			}
-			#header {
-				position: relative;
-				height: 64px;
-				background-image: url(resources/images/header-background.png);
-				background-repeat: repeat-x;
-			}
-			#header-content {
-				position: absolute;
-				top: 10px;
-				left: 50%;
-				width: 431px;
-				height: 45px;
-				margin-left: -215px;
-				font-size: 18px;
-				font-weight: bold;
-				text-align: center;
-				padding-top: 12px;
-				background-image: url(resources/images/header.png);
-				background-repeat: no-repeat;
-			}
-			#list-container {
-				position: absolute;
-				top: 65px;
-				left: 0;
-				right: 0;
-				height: 120px;
-			}
-
-			/* styles for the three lists in the top region */
-			#genres, #artists, #albums {
-				position: absolute;
-				top: 0;
-				bottom: 0;
-				width: 33.3%;
-				height: auto;
-			}
-			#list-container .dgrid-row { /* all rows in all 3 lists */
-				padding: 0.25em;
-				cursor: default;
-			}
-
-			/* IE<7 doesn't support height/width: auto w/ top/bottom / left/right. */
-			.has-ie-6 #genres, .has-ie-6 #artists, .has-ie-6 #albums {
-				height: 120px;
-			}
-			.has-ie-6 #list-container {
-				width: 100%;
-			}
-
-			#artists { left: 33.3%; }
-			#albums { right: 0; }
-
-			#grid {
-				position: absolute;
-				left: 0;
-				right: 0;
-				top: 187px;
-				bottom: 0;
-				height: auto; /* override default height: 30em; in dgrid.css */
-			}
-			
-			.has-ie-6 #grid {
-				width: 100%;
-				/* Give the grid a height.  Not optimal, but we'd need more JS for better. */
-				height: 20em;
-			}
-			
-			#grid .dgrid-cell {
-				border: 0;
-			}
-			#grid .dgrid-header th {
-				border: 0;
-				border-right: 1px solid #a6a6a6;
-			}
-			#grid .dgrid-header th:last-child {
-				border: 0;
-			}
-			#grid .dgrid-row-even {
-				background-color: #f2f6fa;
-			}
-			#grid .dgrid-row-even.dgrid-selected {
-				background-color: #bfd6eb;
-			}
-
-			#grid .field-Time,
-			#grid .field-Year { 
-				text-align: right; 
-			}
-		</style>
-		<script src="../../../dojo/dojo.js" 
-			data-dojo-config="async: true"></script>
-		<script>
-			function unique(arr){
-				//	create a unique list of items from the passed array
-				//	(removing duplicates).  This is quick and dirty.
-
-				//	first, set up a hashtable for unique objects.
-				var obj = {};
-				for(var i=0,l=arr.length; i<l; i++){
-					if(!(arr[i] in obj)){
-						obj[arr[i]] = true;
-					}
-				}
-
-				//	now push the unique objects back into an array, and return it.
-				var ret = [];
-				for(var p in obj){
-					ret.push(p);
-				}
-				ret.sort();
-				return ret;
-			}
-
-			//	our "main" function
-			require([
-					"dgrid/List",
-					"dgrid/OnDemandGrid",
-					"dgrid/Selection",
-					"dgrid/Keyboard",
-					"dgrid/extensions/ColumnHider",
-					"dojo/_base/declare",
-					"dojo/_base/array",
-					"dgrid/demos/dTuned/data",
-					"dojo/domReady!"
-				],
-				function(List, Grid, Selection, Keyboard, Hider, declare, arrayUtil){
-					//	a formatting function for the Duration column.
-					var timeFormatter = function(t){
-						var tmp = parseInt(t, 10), min, sec;
-						if(isNaN(tmp)){ return t; }
-						min = Math.floor(tmp/60);
-						sec = tmp % 60;
-						// don't forget to pad seconds.
-						return "" + min + ":" + (sec < 10 ? "0" : "") + sec;
-					};
-
-					// Create the main grid to appear below the genre/artist/album lists.
-					window.grid = new (declare([Grid, Selection, Keyboard, Hider]))({
-						store: songStore,
-						columns: {
-							Name: "Name",
-							Time: { label: "Duration", formatter: timeFormatter },
-							Year: "Year",
-							Artist: "Artist",
-							Album: "Album",
-							Genre: "Genre"
-						}
-					}, "grid");
-
-					// define a List constructor with the features we want mixed in,
-					// for use by the three lists in the top region
-					var TunesList = declare([List, Selection, Keyboard]);
-
-					//	define our three lists for the top.
-					window.genres = new TunesList({ selectionMode: "single" }, "genres");
-					window.artists = new TunesList({ selectionMode: "single" }, "artists");
-					window.albums = new TunesList({ selectionMode: "single" }, "albums");
-
-					//	create the unique lists and render them
-					var g = unique(arrayUtil.map(songStore.data, function(item){ return item.Genre; })),
-						art = unique(arrayUtil.map(songStore.data, function(item){ return item.Artist; })),
-						alb = unique(arrayUtil.map(songStore.data, function(item){ return item.Album; }));
-					g.unshift("All (" + g.length + " Genre" + (g.length != 1 ? "s" : "") + ")");
-					art.unshift("All (" + art.length + " Artist" + (art.length != 1 ? "s" : "") + ")");
-					alb.unshift("All (" + alb.length + " Album" + (alb.length != 1 ? "s" : "") + ")");
-					genres.renderArray(g);
-					artists.renderArray(art);
-					albums.renderArray(alb);
-
-					var currentGenre; // updated on genre select
-
-					//	start listening for selections on the lists.
-					genres.on("dgrid-select", function(e){
-						//	filter the albums, artists and grid
-						var
-							row = e.rows[0],
-							filter = currentGenre = row.data,
-							art;
-						if(row.id == "0"){
-							//	remove filtering
-							art = unique(arrayUtil.map(songStore.data, function(item){ return item.Artist; }));
-							grid.query = {};
-						} else {
-							//	create filtering
-							art = unique(arrayUtil.map(arrayUtil.filter(songStore.data, function(item){ return item.Genre == filter; }), function(item){ return item.Artist; }));
-							grid.query = { "Genre": filter };
-						}
-						art.unshift("All (" + art.length + " Artist" + (art.length != 1 ? "s" : "") + ")");
-						
-						artists.refresh();	//	clear contents
-						artists.renderArray(art);
-						artists.select(0); //	reselect "all", triggering albums+grid refresh
-					});
-
-					artists.on("dgrid-select", function(e){
-						//	filter the albums, grid
-						var row = e.rows[0],
-							filter = row.data, alb;
-						if(row.id == "0"){
-							if(genres.selection[0]){
-								//	remove filtering entirely
-								alb = unique(arrayUtil.map(songStore.data, function(item){ return item.Album; }));
-							} else {
-								//	filter only by genre
-								alb = unique(arrayUtil.map(arrayUtil.filter(songStore.data, function(item){ return item.Genre == currentGenre; }), function(item){ return item.Album; }));
-							}
-							delete grid.query.Artist;
-						} else {
-							//	create filter based on artist
-							alb = unique(arrayUtil.map(arrayUtil.filter(songStore.data, function(item){ return item.Artist == filter; }), function(item){ return item.Album; }));
-							grid.query.Artist = filter;
-						}
-						alb.unshift("All (" + alb.length + " Album" + (alb.length != 1 ? "s" : "") + ")");
-
-						albums.refresh(); //	clear contents
-						albums.renderArray(alb);
-						albums.select(0); //	reselect "all" item, triggering grid refresh
-					});
-
-					albums.on("dgrid-select", function(e){
-						//	filter the grid
-						var row = e.rows[0],
-							filter = row.data;
-						if(row.id == "0"){
-							// show all albums
-							delete grid.query.Album;
-						} else {
-							grid.query.Album = filter;
-						}
-						grid.refresh();
-					});
-
-					//	set the initial selections on the lists.
-					genres.select(0);
-
-				}	//	end "main" function
-			);	//	end require
-		</script>
-	</head>
-	<body class="dTuned">
-		<div id="header">
-			<div id="header-content">
-				dTuned
-			</div>
-		</div>
-		<div id="list-container">
-			<div id="genres"></div>
-			<div id="artists"></div>
-			<div id="albums"></div>
-		</div>
-		<div id="grid"></div>
-	</body>
-</html>

+ 0 - 46
esp/files/dgrid/demos/dTuned/resources/dTuned.css

@@ -1,46 +0,0 @@
-.dTuned .ui-widget {
-	background: #fff;
-	color: #000;
-}
-.dTuned .ui-widget-header {
-	background-image: url(images/grid-header-bg.png);
-	background-repeat: repeat-x;
-	font-weight: bold;
-}
-.dTuned .ui-widget-header .dgrid-cell:hover,
-.dTuned .ui-widget-header .dgrid-sort-up,
-.dTuned .ui-widget-header .dgrid-sort-down{
-	background-image: url(images/grid-header-sorted.png);
-	background-repeat: repeat-x;
-}
-
-.dTuned .ui-state-default {
-	-webkit-transition-duration: 0.2s;
-	-moz-transition-duration: 0.2s;
-	-o-transition-duration: 0.2s;
-	transition-duration: 0.2s;
-	-webkit-transition-property: background-color, border-color;
-	-moz-transition-property: background-color, border-color;
-	-o-transition-property: background-color, border-color;
-	transition-property: background-color, border-color;
-	background: url("../../../css/skins/images/row_back.png") #fff repeat-x;
-}
-.has-ie-6 .dTuned .ui-state-default {
-	background-image: none;
-}
-
-.dTuned .ui-state-default:hover {
-	background-color: #e9f2fe;
-}
-
-.dTuned .ui-state-active {
-	background-color: #cee6fa;
-}
-
-.dTuned .ui-state-active:hover {
-	background-color: #9bc6f2;
-}
-
-.dTuned .ui-state-highlight {
-	background-color: #ff6;
-}

BIN
esp/files/dgrid/demos/dTuned/resources/images/grid-header-bg.png


BIN
esp/files/dgrid/demos/dTuned/resources/images/grid-header-separator.png


BIN
esp/files/dgrid/demos/dTuned/resources/images/grid-header-sorted-separator.png


BIN
esp/files/dgrid/demos/dTuned/resources/images/grid-header-sorted.png


BIN
esp/files/dgrid/demos/dTuned/resources/images/header-background.png


BIN
esp/files/dgrid/demos/dTuned/resources/images/header.png


+ 0 - 219
esp/files/dgrid/demos/multiview/index.html

@@ -1,219 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>Multi-view dgrid</title>
-		<link rel="stylesheet" href="../../../dojo/resources/dojo.css">
-		<link rel="stylesheet" href="../../css/skins/slate.css">
-		<style>
-#grid {
-	width: 80%;
-	margin: auto;
-	height: 332px; /* tall enough for 2 rows in gallery view */
-}
-
-/* styles for icon node in various views */
-
-.icon {
-	font-size: 0; /*TODO: is this needed?*/
-	background-repeat: no-repeat;
-}
-
-.table .icon {
-	width: 32px;
-	height: 32px;
-}
-
-.details .icon {
-	width: 72px; /* 64px + buffer to separate icon from text */
-	height: 64px;
-}
-
-.gallery .icon {
-	width: 128px;
-	height: 128px;
-	margin: auto;
-}
-
-/* styles for "table" view (using Grid.renderRow) */
-
-.table .field-icon {
-	width: 33px;
-	padding: 0;
-}
-
-.table .field-icon .dgrid-cell-padding { /* old IE */
-	padding: 0;
-}
-
-.table .dgrid-cell {
-	vertical-align: middle;
-}
-
-/* Table view allows expanding/collapsing rows to show summary */
-
-.table .expando {
-	/* style of area containing summary, expanded on click */
-	padding-left: 40px;
-}
-
-.table .collapsed .expando {
-	display: none;
-}
-
-/* styles for details view */
-
-.details .dgrid-row {
-	clear: both;
-	min-height: 64px;
-	padding: 0.5em;
-}
-
-.details .icon {
-	float: left;
-}
-
-.details .name {
-	font-weight: bold;
-	margin-bottom: 1em;
-}
-
-/* styles for gallery view */
-
-.gallery .dgrid-row {
-	width: 25%;
-	float: left;
-	text-align: center;
-	padding: 1em 0;
-}
-		</style>
-	</head>
-	<body class="slate">
-		<p>
-			This page demonstrates presenting several different views within a single
-			Grid instance, by swapping out the <code>renderRow</code> function.
-			The details and gallery views also demonstrate switching the grid header
-			off by calling <code>setShowHeader</code>.
-			(In fact, if only the Details and Gallery views were desired,
-			the <code>List</code> module would be sufficient.)
-		</p>
-		<p>
-			In addition, the "table" view demonstrates hooking up a click callback,
-			in order to display more information when a row is clicked.
-		</p>
-		<p>Switch View:
-			<button id="btnTable">Table</button>
-			<button id="btnDetails">Details</button>
-			<button id="btnGallery">Gallery</button>
-		</p>
-		<div id="grid" class="table"></div>
-		<script src="../../../dojo/dojo.js" data-dojo-config="async:1"></script>
-		<script>
-require(["dgrid/OnDemandGrid", "dgrid/Selection", "dgrid/Keyboard", "dojo/_base/declare", "dojo/on", "dojo/query", "dojo/store/Memory", "dojo/store/Observable", "put-selector/put"],
-function(Grid, Selection, Keyboard, declare, on, query, Memory, Observable, put){
-	var grid, store, origRenderRow, expandoListener, expandedNode,
-		renderers = {
-			gallery: function(obj, options){
-				// function used for renderRow for gallery view (large tiled thumbnails)
-				var div = put("div");
-				div.innerHTML = '<div class="icon" style="background-image:url(resources/' +
-					obj.icon + '-128.png);">&nbsp;</div><div class="name">' + obj.name + '</div>';
-				return div;
-			},
-			details: function(obj, options){
-				// function used for renderRow for details view (items w/ summary)
-				var div = put("div");
-				div.innerHTML = '<div class="icon" style="background-image:url(resources/' +
-					obj.icon + '-64.png);">&nbsp;</div><div class="name">' +
-					obj.name + '</div><div class="summary">' + obj.summary + '</div>';
-				return div;
-			},
-			table: function(obj, options){
-				var div = put("div.collapsed", Grid.prototype.renderRow.apply(this, arguments)),
-					expando = put(div, "div.expando", obj.summary);
-				return div;
-			}
-		};
-	
-	function viewClickHandler(view){
-		return function(){
-			// pause/resume click listener for expando in "table" view
-			expandoListener[view == "table" ? "resume" : "pause"]();
-			// reset expanded node for table view
-			expandedNode = null;
-			// update renderRow function
-			grid.renderRow = renderers[view];
-			// update class on grid domNode
-			put(grid.domNode, "!table!gallery!details." + view);
-			// only show headers if we're in "table" view
-			grid.set("showHeader", view == "table");
-			// force redraw of rows
-			grid.refresh();
-		}
-	}
-	
-	function byId(id) { return document.getElementById(id); }
-	
-	store = new Memory({ data: [
-		{ id: "dojo", name: "Dojo Core", icon: "dojo",
-			summary: "Dojo core is a powerful, lightweight library that makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance."
-		}, {
-			id: "dijit", name: "Dijit", icon: "dojo",
-			summary: "Dijit provides a complete collection of user interface controls based on Dojo, giving you the power to create web applications that are highly optimized for usability, performance, internationalization, accessibility, but above all deliver an incredible user experience."
-		}, {
-			id: "dgrid", name: "dgrid", icon: "df",
-			summary: "A lightweight, mobile-ready, data-driven, modular widget designed for lists and grids."
-		}, {
-			id: "xstyle", name: "xstyle", icon: "df",
-			summary: "CSS framework providing polyfills, extensions, dynamic loading, and selector based DOM manipulation."
-		}, {
-			id: "put-selector", name: "put-selector", icon: "df",
-			summary: "A high-performance, lightweight function for creating and manipulating DOM elements with succinct, elegant, familiar CSS selector-based syntax."
-		}
-	] });
-	
-	grid = new Grid({
-		columns: [
-			{
-				label: " ",
-				field: "icon",
-				sortable: false,
-				formatter: function(icon){
-					return '<div class="icon" style="background-image:url(resources/' +
-						icon + '-32.png);">&nbsp;</div>';
-				}
-			},
-			{ label: "Package", field: "id" },
-			{ label: "Name", field: "name" }
-		],
-		store: store,
-		renderRow: renderers.table
-	}, "grid");
-	
-	// store initially-active renderRow as renderer for table view
-	renderers.table = grid.renderRow;
-	
-	// listen for clicks to trigger expand/collapse in table view mode
-	expandoListener = on.pausable(grid.domNode, ".dgrid-row:click", function(evt){
-		var
-			node = grid.row(evt).element,
-			collapsed = node.className.indexOf("collapsed") >= 0;
-		
-		// toggle state of node which was clicked
-		put(node, (collapsed ? "!" : ".") + "collapsed");
-		
-		// if clicked row wasn't expanded, collapse any previously-expanded row
-		collapsed && expandedNode && put(expandedNode, ".collapsed");
-		
-		// if the row clicked was previously expanded, nothing is expanded now
-		expandedNode = collapsed ? node : null;
-	});
-	
-	// switch views when buttons are clicked
-	byId("btnTable").onclick = viewClickHandler("table");
-	byId("btnDetails").onclick = viewClickHandler("details");
-	byId("btnGallery").onclick = viewClickHandler("gallery");
-});
-		</script>
-	</body>
-</html>

BIN
esp/files/dgrid/demos/multiview/resources/df-128.png


BIN
esp/files/dgrid/demos/multiview/resources/df-32.png


BIN
esp/files/dgrid/demos/multiview/resources/df-64.png


BIN
esp/files/dgrid/demos/multiview/resources/dojo-128.png


BIN
esp/files/dgrid/demos/multiview/resources/dojo-32.png


BIN
esp/files/dgrid/demos/multiview/resources/dojo-64.png


+ 0 - 213
esp/files/dgrid/demos/todo/index.html

@@ -1,213 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>Todo List</title>
-		<link rel="stylesheet" href="../../../dojo/resources/dojo.css">
-		<link rel="stylesheet" href="../../css/skins/slate.css">
-		<!-- some of the DnD styles reside within the Dijit theme -->
-		<link rel="stylesheet" href="../../../dijit/themes/tundra/Common.css">
-		<style>
-#container {
-	width: 500px;
-	margin: auto;
-}
-
-.actionArea {
-	position: absolute;
-	height: 2em;
-}
-.topArea {
-	top: 0;
-}
-.bottomArea {
-	bottom: 0;
-}
-
-#list {
-	position: absolute;
-	top: 2em;
-	bottom: 2em;
-	height: auto;
-	width: 500px;
-}
-
-#list .field-completed {
-	/* column with checkboxes for completing tasks */
-	width: 30px;
-}
-
-#list .completed {
-	/* tasks that are checked off on the list get this class applied */
-	text-decoration: line-through;
-	font-style: italic;
-}
-
-#txtTask {
-	/* text field for adding tasks */
-	width: 400px;
-}
-
-/* IE6 doesn't support top+bottom+height:auto, so do something else */
-.has-ie-6 #list {
-	height: 300px;
-}
-.has-ie-6 .bottomArea {
-	top: 330px;
-}
-		</style>
-	</head>
-	<body class="slate">
-		<div id="container">
-			<form id="itemForm" class="actionArea topArea">
-				<input type="text" id="txtTask" name="task">
-				<button type="submit">Add</button>
-			</form>
-			<div id="list"></div>
-			<div id="removeArea" class="actionArea bottomArea">
-				<button type="button" id="removeSelected">Remove Selected</button>
-				<button type="button" id="removeCompleted">Remove Completed</button>
-			</div>
-		</div>
-		<script src="../../../dojo/dojo.js" data-dojo-config="async:1"></script>
-		<script>
-require(["dgrid/OnDemandGrid", "dgrid/Selection", "dgrid/editor", "dgrid/extensions/DnD", "dojo/_base/declare", "dojo/json", "dojo/store/Memory", "dojo/store/Observable", "put-selector/put"],
-function(Grid, Selection, editor, DnD, declare, json, Memory, Observable, put){
-	function byId(id){
-		return document.getElementById(id);
-	}
-	
-	// function used to support ordered insertion of store items
-	function calculateOrder(store, object, before, orderField){
-		// Calculates proper value of order for an item to be placed before another
-		var afterOrder, beforeOrder = 0;
-		if (!orderField) { orderField = "order"; }
-		
-		if(before){
-			// calculate midpoint between two items' orders to fit this one
-			afterOrder = before[orderField];
-			store.query({}, {}).forEach(function(object){
-				var ord = object[orderField];
-				if(ord > beforeOrder && ord < afterOrder){
-					beforeOrder = ord;
-				}
-			});
-			return (afterOrder + beforeOrder) / 2;
-		}else{
-			// find maximum order and place this one after it
-			afterOrder = 0;
-			store.query({}, {}).forEach(function(object){
-				var ord = object[orderField];
-				if(ord > afterOrder){ afterOrder = ord; }
-			});
-			return afterOrder + 1;
-		}
-	}
-	
-	// Augment Memory store to support ordering, and to
-	// persist to localStorage if the browser supports it.
-	var
-		key = "dgrid_demo_todo_list",
-		OrderedStoreMixin = declare(null, {
-			put: function(object, options){
-				// honor order if present
-				options = options || {};
-				if(options.before !== undefined || !object.order){
-					// if options.before is provided or this item doesn't have any order,
-					// calculate a new one
-					object.order = calculateOrder(this, object, options.before);
-				}
-				return this.inherited(arguments);
-			},
-			query: function(query, options){
-				// sort by order field
-				options = options || {};
-				options.sort = [{attribute:"order"}];
-				return this.inherited(arguments);
-			}
-		}),
-		storeMixins = [Memory, OrderedStoreMixin];
-	
-	if (window.localStorage){
-		// add functionality for saving/recalling from localStorage
-		storeMixins.push(declare(null, {
-			constructor: function(){
-				var jsondata = localStorage[key];
-				jsondata && this.setData(json.parse(jsondata));
-			},
-			put: function(object, options){
-				// persist new/updated item to localStorage
-				var r = this.inherited(arguments);
-				localStorage[key] = json.stringify(this.data);
-				return r;
-			},
-			remove: function(id){
-				// update localStorage to reflect removed item
-				var r = this.inherited(arguments);
-				localStorage[key] = json.stringify(this.data);
-				return r;
-			}
-		}));
-	}
-		Store = declare(storeMixins),
-		store = Observable(new Store({ idProperty: "summary" })),
-		grid = new (declare([Grid, Selection, DnD]))({
-			store: store,
-			columns: {
-				completed: editor({
-					label: " ",
-					autoSave: true,
-					sortable: false
-				}, "checkbox"),
-				summary: {
-					field: "_item", // get whole item for use by formatter
-					label: "TODOs",
-					sortable: false,
-					formatter: function(item){
-						return "<div" + (item.completed ? ' class="completed"' : "") +
-							">" + item.summary + "</div>";
-					}
-				}
-			}
-		}, "list"),
-		taskField = byId("txtTask");
-	
-	grid.sort("order");
-	
-	byId("itemForm").onsubmit = function(){
-		// allow overwrite if already exists (by using put, not add)
-		store.put({
-			completed: false,
-			summary: taskField.value
-		});
-		return false;
-	};
-	byId("removeSelected").onclick = function(){
-		for (var i in grid.selection) {
-			// Each key in the selection map is the id of the item,
-			// so we can pass it directly to store.remove.
-			store.remove(i);
-		}
-	};
-	byId("removeCompleted").onclick = function(){
-		// query for all completed items and remove them
-		store.query({ completed: true }).forEach(function(item){
-			store.remove(item[store.idProperty]);
-		});
-	};
-	
-	if(window.localStorage){
-		// add extra button to clear the localStorage key we're using
-		var button = put(byId("removeArea"), "button[type=button]",
-			"Clear localStorage");
-		button.onclick = function(){
-			localStorage.removeItem(key);
-			// remove all items in grid the quick way (no need to iteratively remove)
-			store.setData([]);
-			grid.refresh();
-		};
-	}
-});
-		</script>
-	</body>
-</html>

+ 0 - 538
esp/files/dgrid/editor.js

@@ -1,538 +0,0 @@
-define([
-	"dojo/_base/kernel",
-	"dojo/_base/lang",
-	"dojo/_base/array",
-	"dojo/_base/Deferred",
-	"dojo/on",
-	"dojo/aspect",
-	"dojo/has",
-	"dojo/query",
-	"./Grid",
-	"put-selector/put",
-	"dojo/_base/sniff"
-], function(kernel, lang, arrayUtil, Deferred, on, aspect, has, query, Grid, put){
-
-// Variables to track info for cell currently being edited
-// (active* variables are for editOn editors only)
-var activeCell, activeValue, activeOptions, focusedCell;
-
-function updateInputValue(input, value){
-	// common code for updating value of a standard input
-	input.value = value;
-	if(input.type == "radio" || input.type == "checkbox"){
-		input.checked = input.defaultChecked = !!value;
-	}
-}
-
-function dataFromValue(value, oldValue){
-	// Default logic for translating values from editors;
-	// tries to preserve type if possible.
-	if(typeof oldValue == "number"){
-		value = isNaN(value) ? value : parseFloat(value);
-	}else if(typeof oldValue == "boolean"){
-		value = value == "true" ? true : value == "false" ? false : value;
-	}else if(oldValue instanceof Date){
-		var asDate = new Date(value);
-		value = isNaN(asDate.getTime()) ? value : asDate;
-	}
-	return value;
-}
-
-// intermediary frontend to dataFromValue for HTML and widget editors
-function dataFromEditor(column, cmp){
-	if(typeof cmp.get == "function"){ // widget
-		return dataFromValue(cmp.get("value"));
-	}else{ // HTML input
-		return dataFromValue(
-			cmp[cmp.type == "checkbox" || cmp.type == "radio"  ? "checked" : "value"]);
-	}
-}
-
-function setProperty(grid, cellElement, oldValue, value, triggerEvent){
-	// Updates dirty hash and fires dgrid-datachange event for a changed value.
-	var cell, row, column, eventObject;
-	// test whether old and new values are inequal, with coercion (e.g. for Dates)
-	if((oldValue && oldValue.valueOf()) != (value && value.valueOf())){
-		cell = grid.cell(cellElement);
-		row = cell.row;
-		column = cell.column;
-		if(column.field && row){
-			// TODO: remove rowId in lieu of cell (or grid.row/grid.cell)
-			// (keeping for the moment for back-compat, but will note in changes)
-			eventObject = {
-				grid: grid,
-				cell: cell,
-				rowId: row.id,
-				oldValue: oldValue,
-				value: value,
-				bubbles: true,
-				cancelable: true
-			};
-			if(triggerEvent && triggerEvent.type){
-				eventObject.parentType = triggerEvent.type;
-			}
-			
-			if(on.emit(cellElement, "dgrid-datachange", eventObject)){
-				if(grid.updateDirty){
-					// for OnDemandGrid: update dirty data, and save if autoSave is true
-					grid.updateDirty(row.id, column.field, value);
-					// perform auto-save (if applicable) in next tick to avoid
-					// unintentional mishaps due to order of handler execution
-					column.autoSave && setTimeout(function(){ grid._trackError("save"); }, 0);
-				}else{
-					// update store-less grid
-					row.data[column.field] = value;
-				}
-			}else{
-				// Otherwise keep the value the same
-				// For the sake of always-on editors, need to manually reset the value
-				var cmp;
-				if(cmp = cellElement.widget){
-					// set _dgridIgnoreChange to prevent an infinite loop in the
-					// onChange handler and prevent dgrid-datachange from firing
-					// a second time
-					cmp._dgridIgnoreChange = true;
-					cmp.set("value", oldValue);
-					setTimeout(function(){ cmp._dgridIgnoreChange = false; }, 0);
-				}else if(cmp = cellElement.input){
-					updateInputValue(cmp, oldValue);
-				}
-				
-				return oldValue;
-			}
-		}
-	}
-	return value;
-}
-
-// intermediary frontend to setProperty for HTML and widget editors
-function setPropertyFromEditor(grid, column, cmp, triggerEvent) {
-	var value, id, editedRow;
-	if(!cmp.isValid || cmp.isValid()){
-		value = setProperty(grid, (cmp.domNode || cmp).parentNode,
-			activeCell ? activeValue : cmp._dgridLastValue,
-			dataFromEditor(column, cmp), triggerEvent);
-		
-		if(activeCell){ // for editors with editOn defined
-			activeValue = value;
-		}else{ // for always-on editors, update _dgridLastValue immediately
-			cmp._dgridLastValue = value;
-		}
-
-		if(cmp.type === "radio" && cmp.name && !column.editOn && column.field){
-			editedRow = grid.row(cmp);
-			
-			// Update all other rendered radio buttons in the group
-			query("input[type=radio][name=" + cmp.name + "]", grid.contentNode).forEach(function(radioBtn){
-				var row = grid.row(radioBtn);
-				// Only update _dgridLastValue and the dirty data if it exists
-				// and is not already false
-				if(radioBtn !== cmp && radioBtn._dgridLastValue){
-					radioBtn._dgridLastValue = false;
-					if(grid.updateDirty){
-						grid.updateDirty(row.id, column.field, false);
-					}else{
-						// update store-less grid
-						row.data[column.field] = false;
-					}
-				}
-			});
-			
-			// Also update dirty data for rows that are not currently rendered
-			for(id in grid.dirty){
-				if(editedRow.id !== id && grid.dirty[id][column.field]){
-					grid.updateDirty(id, column.field, false);
-				}
-			}
-		}
-	}
-}
-
-// editor creation/hookup/placement logic
-
-function createEditor(column){
-	// Creates an editor instance based on column definition properties,
-	// and hooks up events.
-	var editor = column.editor,
-		editOn = column.editOn,
-		grid = column.grid,
-		isWidget = typeof editor != "string", // string == standard HTML input
-		args, cmp, node, putstr, handleChange;
-	
-	args = column.editorArgs || {};
-	if(typeof args == "function"){ args = args.call(grid, column); }
-	
-	if(isWidget){
-		cmp = new editor(args);
-		node = cmp.focusNode || cmp.domNode;
-		
-		// Add dgrid-input to className to make consistent with HTML inputs.
-		node.className += " dgrid-input";
-		
-		// For editOn editors, connect to onBlur rather than onChange, since
-		// the latter is delayed by setTimeouts in Dijit and will fire too late.
-		cmp.connect(cmp, editOn ? "onBlur" : "onChange", function(){
-			if(!cmp._dgridIgnoreChange){
-				setPropertyFromEditor(grid, column, this, {type: "widget"});
-			}
-		});
-	}else{
-		handleChange = function(evt){
-			var target = evt.target;
-			if("_dgridLastValue" in target && target.className.indexOf("dgrid-input") > -1){
-				setPropertyFromEditor(grid, column, target, evt);
-			}
-		};
-
-		// considerations for standard HTML form elements
-		if(!column.grid._hasInputListener){
-			// register one listener at the top level that receives events delegated
-			grid._hasInputListener = true;
-			grid.on("change", function(evt){ handleChange(evt); });
-			// also register a focus listener
-		}
-		
-		putstr = editor == "textarea" ? "textarea" :
-			"input[type=" + editor + "]";
-		cmp = node = put(putstr + ".dgrid-input", lang.mixin({
-			name: column.field,
-			tabIndex: isNaN(column.tabIndex) ? -1 : column.tabIndex
-		}, args));
-		
-		if(has("ie") < 9 || (has("ie") && has("quirks"))){
-			// IE<9 / quirks doesn't fire change events for all the right things,
-			// and it doesn't bubble.
-			if(editor == "radio" || editor == "checkbox"){
-				// listen for clicks since IE doesn't fire change events properly for checks/radios
-				on(cmp, "click", function(evt){ handleChange(evt); });
-			}else{
-				on(cmp, "change", function(evt){ handleChange(evt); });
-			}
-		}
-	}
-	
-	return cmp;
-}
-
-function createSharedEditor(column, originalRenderCell){
-	// Creates an editor instance with additional considerations for
-	// shared usage across an entire column (for columns with editOn specified).
-	
-	var cmp = createEditor(column),
-		grid = column.grid,
-		isWidget = cmp.domNode,
-		node = cmp.domNode || cmp,
-		focusNode = cmp.focusNode || node,
-		reset = isWidget ?
-			function(){ cmp.set("value", cmp._dgridLastValue); } :
-			function(){
-				updateInputValue(cmp, cmp._dgridLastValue);
-				// call setProperty again in case we need to revert a previous change
-				setPropertyFromEditor(column.grid, column, cmp);
-			},
-		keyHandle;
-	
-	function blur(){
-		var element = activeCell;
-		focusNode.blur();
-		
-		if(typeof grid.focus === "function"){
-			// Dijit form widgets don't end up dismissed until the next turn,
-			// so wait before calling focus (otherwise Keyboard will focus the
-			// input again).  IE<9 needs to wait longer, otherwise the cell loses
-			// focus after we've set it.
-			setTimeout(function(){
-				grid.focus(element);
-			}, isWidget && has("ie") < 9 ? 15 : 0);
-		}
-	}
-	
-	function onblur(){
-		var parentNode = node.parentNode,
-			i = parentNode.children.length - 1,
-			options = { alreadyHooked: true },
-			cell = grid.cell(node);
-		
-		// emit an event immediately prior to removing an editOn editor
-		on.emit(cell.element, "dgrid-editor-hide", {
-			grid: grid,
-			cell: cell,
-			column: column,
-			editor: cmp,
-			bubbles: true,
-			cancelable: false
-		});
-		column._editorBlurHandle.pause();
-		// Remove the editor from the cell, to be reused later.
-		parentNode.removeChild(node);
-		
-		put(cell.element, "!dgrid-cell-editing");
-		
-		// Clear out the rest of the cell's contents, then re-render with new value.
-		while(i--){ put(parentNode.firstChild, "!"); }
-		Grid.appendIfNode(parentNode, column.renderCell(
-			column.grid.row(parentNode).data, activeValue, parentNode,
-			activeOptions ? lang.delegate(options, activeOptions) : options));
-		
-		// Reset state now that editor is deactivated;
-		// reset focusedCell as well since some browsers will not trigger the
-		// focusout event handler in this case
-		activeCell = activeValue = activeOptions = focusedCell = null;
-	}
-	
-	function dismissOnKey(evt){
-		// Contains logic for reacting to enter/escape keypresses to save/cancel edits.
-		// Calls `focusNode.blur()` in cases where field should be dismissed.
-		var key = evt.keyCode || evt.which;
-		
-		if(key == 27){ // escape: revert + dismiss
-			reset();
-			activeValue = cmp._dgridLastValue;
-			blur();
-		}else if(key == 13 && column.dismissOnEnter !== false){ // enter: dismiss
-			// FIXME: Opera is "reverting" even in this case
-			blur();
-		}
-	}
-	
-	// hook up enter/esc key handling
-	keyHandle = on(focusNode, "keydown", dismissOnKey);
-	
-	// hook up blur handler, but don't activate until widget is activated
-	(column._editorBlurHandle = on.pausable(cmp, "blur", onblur)).pause();
-	
-	return cmp;
-}
-
-function showEditor(cmp, column, cellElement, value){
-	// Places a shared editor into the newly-active cell in the column.
-	// Also called when rendering an editor in an "always-on" editor column.
-	
-	var isWidget = cmp.domNode,
-		grid = column.grid;
-	
-	// for regular inputs, we can update the value before even showing it
-	if(!isWidget){ updateInputValue(cmp, value); }
-	
-	cellElement.innerHTML = "";
-	put(cellElement, ".dgrid-cell-editing");
-	put(cellElement, cmp.domNode || cmp);
-	
-	if(isWidget){
-		// For widgets, ensure startup is called before setting value,
-		// to maximize compatibility with flaky widgets like dijit/form/Select.
-		if(!cmp._started){ cmp.startup(); }
-		
-		// Set value, but ensure it isn't processed as a user-generated change.
-		// (Clear flag on a timeout to wait for delayed onChange to fire first)
-		cmp._dgridIgnoreChange = true;
-		cmp.set("value", value);
-		setTimeout(function(){ cmp._dgridIgnoreChange = false; }, 0);
-	}
-	// track previous value for short-circuiting or in case we need to revert
-	cmp._dgridLastValue = value;
-	// if this is an editor with editOn, also update activeValue
-	// (activeOptions will have been updated previously)
-	if(activeCell){ 
-		activeValue = value; 
-		// emit an event immediately prior to placing a shared editor
-		on.emit(cellElement, "dgrid-editor-show", {
-			grid: grid,
-			cell: grid.cell(cellElement),
-			column: column,
-			editor: cmp,
-			bubbles: true,
-			cancelable: false
-		});
-	}
-}
-
-function edit(cell) {
-	// summary:
-	//		Method to be mixed into grid instances, which will show/focus the
-	//		editor for a given grid cell.  Also used by renderCell.
-	// cell: Object
-	//		Cell (or something resolvable by grid.cell) to activate editor on.
-	// returns:
-	//		If the cell is editable, returns a promise resolving to the editor
-	//		input/widget when the cell editor is focused.
-	//		If the cell is not editable, returns null.
-	
-	var row, column, cellElement, dirty, field, value, cmp, dfd;
-	
-	if(!cell.column){ cell = this.cell(cell); }
-	if(!cell || !cell.element){ return null; }
-	
-	column = cell.column;
-	field = column.field;
-	cellElement = cell.element.contents || cell.element;
-	
-	if((cmp = column.editorInstance)){ // shared editor (editOn used)
-		if(activeCell != cellElement &&
-				(!column.canEdit || column.canEdit(cell.row.data, value))){
-			activeCell = cellElement;
-			row = cell.row;
-			dirty = this.dirty && this.dirty[row.id];
-			value = (dirty && field in dirty) ? dirty[field] :
-				column.get ? column.get(row.data) : row.data[field];
-			
-			showEditor(column.editorInstance, column, cellElement, value);
-			
-			// focus / blur-handler-resume logic is surrounded in a setTimeout
-			// to play nice with Keyboard's dgrid-cellfocusin as an editOn event
-			dfd = new Deferred();
-			setTimeout(function(){
-				// focus the newly-placed control (supported by form widgets and HTML inputs)
-				if(cmp.focus){ cmp.focus(); }
-				// resume blur handler once editor is focused
-				if(column._editorBlurHandle){ column._editorBlurHandle.resume(); }
-				dfd.resolve(cmp);
-			}, 0);
-			
-			return dfd.promise;
-		}
-	}else if(column.editor){ // editor but not shared; always-on
-		cmp = cellElement.widget || cellElement.input;
-		if(cmp){
-			dfd = new Deferred();
-			if(cmp.focus){ cmp.focus(); }
-			dfd.resolve(cmp);
-			return dfd.promise;
-		}
-	}
-	return null;
-}
-
-// editor column plugin function
-
-return function(column, editor, editOn){
-	// summary:
-	//		Adds editing capability to a column's cells.
-	
-	var originalRenderCell = column.renderCell || Grid.defaultRenderCell,
-		listeners = [],
-		isWidget;
-	
-	function commonInit(column) {
-		// Common initialization logic for both editOn and always-on editors
-		var grid = column.grid,
-			focusoutHandle;
-		if(!grid.edit){
-			// Only perform this logic once on a given grid
-			grid.edit = edit;
-			
-			listeners.push(on(grid.domNode, '.dgrid-input:focusin', function () {
-				focusedCell = grid.cell(this);
-			}));
-			focusoutHandle = grid._editorFocusoutHandle =
-				on.pausable(grid.domNode, '.dgrid-input:focusout', function () {
-					focusedCell = null;
-				});
-			listeners.push(focusoutHandle);
-			
-			listeners.push(aspect.before(grid, 'removeRow', function (row) {
-				row = grid.row(row);
-				if (focusedCell && focusedCell.row.id === row.id) {
-					// Pause the focusout handler until after this row has had
-					// time to re-render, if this removal is part of an update.
-					// A setTimeout is used here instead of resuming in the
-					// insertRow aspect below, since if a row were actually
-					// removed (not updated) while editing, the handler would
-					// not be properly hooked up again for future occurrences.
-					focusoutHandle.pause();
-					setTimeout(function () {
-						focusoutHandle.resume();
-					}, 0);
-				}
-			}));
-			listeners.push(aspect.after(grid, 'insertRow', function (rowElement) {
-				var row = grid.row(rowElement);
-				if (focusedCell && focusedCell.row.id === row.id) {
-					grid.edit(grid.cell(row, focusedCell.column.id));
-				}
-				return rowElement;
-			}));
-		}
-	}
-
-	if(!column){ column = {}; }
-	
-	// accept arguments as parameters to editor function, or from column def,
-	// but normalize to column def.
-	column.editor = editor = editor || column.editor || "text";
-	column.editOn = editOn = editOn || column.editOn;
-	
-	isWidget = typeof editor != "string";
-	
-	// warn for widgetArgs -> editorArgs; TODO: remove @ 0.4
-	if(column.widgetArgs){
-		kernel.deprecated("column.widgetArgs", "use column.editorArgs instead",
-			"dgrid 0.4");
-		column.editorArgs = column.widgetArgs;
-	}
-	
-	aspect.after(column, "init", editOn ? function(){
-		commonInit(column);
-		// Create one shared widget/input to be swapped into the active cell.
-		column.editorInstance = createSharedEditor(column, originalRenderCell);
-	} : function(){
-		var grid = column.grid;
-		commonInit(column);
-		
-		if(isWidget){
-			// add advice for cleaning up widgets in this column
-			listeners.push(aspect.before(grid, "removeRow", function(rowElement){
-				// destroy our widget during the row removal operation,
-				// but don't trip over loading nodes from incomplete requests
-				var cellElement = grid.cell(rowElement, column.id).element,
-					widget = cellElement && (cellElement.contents || cellElement).widget;
-				if(widget){
-					grid._editorFocusoutHandle.pause();
-					widget.destroyRecursive();
-				}
-			}));
-		}
-	});
-	
-	aspect.after(column, "destroy", function(){
-		arrayUtil.forEach(listeners, function(l){ l.remove(); });
-		if(column._editorBlurHandle){ column._editorBlurHandle.remove(); }
-		
-		if(editOn && isWidget){ column.editorInstance.destroyRecursive(); }
-		
-		// Remove the edit function, so that it (and other one-time listeners)
-		// will be re-added if editor columns are re-initialized
-		column.grid.edit = null;
-	});
-	
-	column.renderCell = editOn ? function(object, value, cell, options){
-		// TODO: Consider using event delegation
-		// (Would require using dgrid's focus events for activating on focus,
-		// which we already advocate in README for optimal use)
-		
-		if(!options || !options.alreadyHooked){
-			// in IE<8, cell is the child of the td due to the extra padding node
-			on(cell.tagName == "TD" ? cell : cell.parentNode, editOn, function(){
-				activeOptions = options;
-				column.grid.edit(this);
-			});
-		}
-		
-		// initially render content in non-edit mode
-		return originalRenderCell.call(column, object, value, cell, options);
-		
-	} : function(object, value, cell, options){
-		// always-on: create editor immediately upon rendering each cell
-		if(!column.canEdit || column.canEdit(object, value)){
-			var cmp = createEditor(column);
-			showEditor(cmp, column, cell, value);
-			// Maintain reference for later use.
-			cell[isWidget ? "widget" : "input"] = cmp;
-		}else{
-			return originalRenderCell.call(column, object, value, cell, options);
-		}
-	};
-	
-	return column;
-};
-});

+ 0 - 313
esp/files/dgrid/extensions/ColumnHider.js

@@ -1,313 +0,0 @@
-define(["dojo/_base/declare", "dojo/has", "dojo/on", "../util/misc", "put-selector/put", "dojo/i18n!./nls/columnHider", "xstyle/css!../css/extensions/ColumnHider.css"],
-function(declare, has, listen, miscUtil, put, i18n){
-/*
- *	Column Hider plugin for dgrid
- *	Originally contributed by TRT 2011-09-28
- *
- *	A dGrid plugin that attaches a menu to a dgrid, along with a way of opening it,
- *	that will allow you to show and hide columns.  A few caveats:
- *
- *	1. Menu placement is entirely based on CSS definitions.
- *	2. If you want columns initially hidden, you must add "hidden: true" to your
- *		column definition.
- *	3. This implementation does NOT support ColumnSet, and has not been tested
- *		with multi-subrow records.
- *	4. Column show/hide is controlled via straight up HTML checkboxes.  If you
- *		are looking for something more fancy, you'll probably need to use this
- *		definition as a template to write your own plugin.
- *
- */
-	
-	var activeGrid, // references grid for which the menu is currently open
-		bodyListener, // references pausable event handler for body mousedown
-		// Need to handle old IE specially for checkbox listener and for attribute.
-		hasIE = has("ie"),
-		hasIEQuirks = hasIE && has("quirks"),
-		forAttr = hasIE < 8 || hasIEQuirks ? "htmlFor" : "for";
-	
-	function getColumnIdFromCheckbox(cb, grid){
-		// Given one of the checkboxes from the hider menu,
-		// return the id of the corresponding column.
-		// (e.g. gridIDhere-hider-menu-check-colIDhere -> colIDhere)
-		return cb.id.substr(grid.id.length + 18);
-	}
-	
-	return declare(null, {
-		// hiderMenuNode: DOMNode
-		//		The node for the menu to show/hide columns.
-		hiderMenuNode: null,
-		
-		// hiderToggleNode: DOMNode
-		//		The node for the toggler to open the menu.
-		hiderToggleNode: null,
-		
-		// i18nColumnHider: Object
-		//		This object contains all of the internationalized strings for
-		//		the ColumnHider extension as key/value pairs.
-		i18nColumnHider: i18n,
-		
-		// _hiderMenuOpened: Boolean
-		//		Records the current open/closed state of the menu.
-		_hiderMenuOpened: false,
-		
-		// _columnHiderRules: Object
-		//		Hash containing handles returned from addCssRule.
-		_columnHiderRules: null,
-		
-		// _columnHiderCheckboxes: Object
-		//		Hash containing checkboxes generated for menu items.
-		_columnHiderCheckboxes: null,
-		
-		_renderHiderMenuEntries: function(){
-			// summary:
-			//		Iterates over subRows for the sake of adding items to the
-			//		column hider menu.
-			
-			var subRows = this.subRows,
-				first = true,
-				srLength, cLength, sr, c, checkbox;
-			
-			delete this._columnHiderFirstCheckbox;
-			
-			for(sr = 0, srLength = subRows.length; sr < srLength; sr++){
-				for(c = 0, cLength = subRows[sr].length; c < cLength; c++){
-					this._renderHiderMenuEntry(subRows[sr][c]);
-					if(first){
-						first = false;
-						this._columnHiderFirstCheckbox =
-							this._columnHiderCheckboxes[subRows[sr][c].id];
-					}
-				}
-			}
-		},
-		
-		_renderHiderMenuEntry: function(col){
-			var id = col.id,
-				div, checkId, checkbox;
-			
-			if(col.hidden){
-				// Hidden state is true; hide the column.
-				this._hideColumn(id);
-			}
-			
-			// Allow cols to opt out of the hider (e.g. for selector column).
-			if(col.unhidable){ return; }
-			
-			// Create the checkbox and label for each column selector.
-			div = put("div.dgrid-hider-menu-row");
-			checkId = this.domNode.id + "-hider-menu-check-" + id;
-			
-			this._columnHiderCheckboxes[id] = checkbox = put(div, "input#" + checkId +
-					".dgrid-hider-menu-check.hider-menu-check-" + id + "[type=checkbox]");
-			put(div, "label.dgrid-hider-menu-label.hider-menu-label" + id +
-				"[" + forAttr + "=" + checkId + "]", col.label || col.field || "");
-			
-			put(this.hiderMenuNode, div);
-			
-			if(!col.hidden){
-				// Hidden state is false; checkbox should be initially checked.
-				// (Need to do this after adding to DOM to avoid IE6 clobbering it.)
-				checkbox.checked = true;
-			}
-		},
-		
-		renderHeader: function(){
-			var grid = this,
-				hiderMenuNode = this.hiderMenuNode,
-				hiderToggleNode = this.hiderToggleNode,
-				id;
-			
-			function stopPropagation(event){
-				event.stopPropagation();
-			}
-			
-			this.inherited(arguments);
-			
-			if(!hiderMenuNode){ // first run
-				// Assume that if this plugin is used, then columns are hidable.
-				// Create the toggle node.
-				hiderToggleNode = this.hiderToggleNode =
-					put(this.headerScrollNode, "button.ui-icon.dgrid-hider-toggle[type=button]");
-				
-				this._listeners.push(listen(hiderToggleNode, "click", function(e){
-					grid._toggleColumnHiderMenu(e);
-				}));
-	
-				// Create the column list, with checkboxes.
-				hiderMenuNode = this.hiderMenuNode =
-					put("div#dgrid-hider-menu-" + this.id +
-						".dgrid-hider-menu[role=dialog][aria-label=" + this.i18nColumnHider.popupLabel + "]");
-
-				this._listeners.push(listen(hiderMenuNode, "keyup", function (e) {
-					var charOrCode = e.charCode || e.keyCode;
-					if(charOrCode === /*ESCAPE*/ 27){
-						grid._toggleColumnHiderMenu(e);
-						hiderToggleNode.focus();
-					}
-				}));
-				
-				// Make sure our menu is initially hidden, then attach to the document.
-				hiderMenuNode.style.display = "none";
-				put(this.domNode, hiderMenuNode);
-				
-				// Hook up delegated listener for modifications to checkboxes.
-				this._listeners.push(listen(hiderMenuNode,
-						".dgrid-hider-menu-check:" + (hasIE < 9 || hasIEQuirks ? "click" : "change"),
-					function(e){
-						grid._updateColumnHiddenState(
-							getColumnIdFromCheckbox(e.target, grid), !e.target.checked);
-					}
-				));
-				
-				// Stop click events from propagating from menu or trigger nodes,
-				// so that we can simply track body clicks for hide without
-				// having to drill-up to check.
-				this._listeners.push(
-					listen(hiderMenuNode, "mousedown", stopPropagation),
-					listen(hiderToggleNode, "mousedown", stopPropagation)
-				);
-				
-				// Hook up top-level mousedown listener if it hasn't been yet.
-				if(!bodyListener){
-					bodyListener = listen.pausable(document, "mousedown", function(e){
-						// If an event reaches this listener, the menu is open,
-						// but a click occurred outside, so close the dropdown.
-						activeGrid && activeGrid._toggleColumnHiderMenu(e);
-					});
-					bodyListener.pause(); // pause initially; will resume when menu opens
-				}
-			}else{ // subsequent run
-				// Remove active rules, and clear out the menu (to be repopulated).
-				for(id in this._columnHiderRules){
-					this._columnHiderRules[id].remove();
-				}
-				hiderMenuNode.innerHTML = "";
-			}
-			
-			this._columnHiderCheckboxes = {};
-			this._columnHiderRules = {};
-
-			// Populate menu with checkboxes/labels based on current columns.
-			this._renderHiderMenuEntries();
-		},
-		
-		destroy: function(){
-			this.inherited(arguments);
-			// Remove any remaining rules applied to hidden columns.
-			for(var id in this._columnHiderRules){
-				this._columnHiderRules[id].remove();
-			}
-		},
-		
-		isColumnHidden: function(id){
-			// summary:
-			//		Convenience method to determine current hidden state of a column
-			return !!this._columnHiderRules[id];
-		},
-		
-		_toggleColumnHiderMenu: function(){
-			var hidden = this._hiderMenuOpened, // reflects hidden state after toggle
-				hiderMenuNode = this.hiderMenuNode,
-				domNode = this.domNode,
-				firstCheckbox;
-
-			// Show or hide the hider menu
-			hiderMenuNode.style.display = (hidden ? "none" : "");
-
-			// Adjust height of menu
-			if (hidden) {
-				// Clear the set size
-				hiderMenuNode.style.height = "";
-			} else {
-				// Adjust height of the menu if necessary
-				// Why 12? Based on menu default paddings and border, we need
-				// to adjust to be 12 pixels shorter. Given the infrequency of
-				// this style changing, we're assuming it will remain this
-				// static value of 12 for now, to avoid pulling in any sort of
-				// computed styles.
-				if (hiderMenuNode.offsetHeight > domNode.offsetHeight - 12) {
-					hiderMenuNode.style.height = (domNode.offsetHeight - 12) + "px";
-				}
-				// focus on the first checkbox
-				(firstCheckbox = this._columnHiderFirstCheckbox) && firstCheckbox.focus();
-			}
-
-			// Pause or resume the listener for clicks outside the menu
-			bodyListener[hidden ? "pause" : "resume"]();
-
-			// Update activeGrid appropriately
-			activeGrid = hidden ? null : this;
-
-			// Toggle the instance property
-			this._hiderMenuOpened = !hidden;
-		},
-		
-		_hideColumn: function(id){
-			// summary:
-			//		Hides the column indicated by the given id.
-			
-			// Use miscUtil function directly, since we clean these up ourselves anyway
-			var selectorPrefix = "#" + miscUtil.escapeCssIdentifier(this.domNode.id) + " .dgrid-column-",
-				tableRule; // used in IE8 code path
-
-			if (this._columnHiderRules[id]) {
-				return;
-			}
-
-			this._columnHiderRules[id] =
-				miscUtil.addCssRule(selectorPrefix + id, "display: none;");
-
-			if(has("ie") === 8 && !has("quirks")){
-				tableRule = miscUtil.addCssRule(".dgrid-row-table", "display: inline-table;");
-
-				window.setTimeout(function(){
-					tableRule.remove();
-				}, 0);
-			}
-		},
-		
-		_updateColumnHiddenState: function(id, hidden){
-			// summary:
-			//		Performs internal work for toggleColumnHiddenState; see the public
-			//		method for more information.
-			
-			if(!hidden){
-				this._columnHiderRules[id] && this._columnHiderRules[id].remove();
-				delete this._columnHiderRules[id];
-			}else{
-				this._hideColumn(id);
-			}
-			
-			// Update hidden state in actual column definition,
-			// in case columns are re-rendered.
-			this.columns[id].hidden = hidden;
-			
-			// Emit event to notify of column state change.
-			listen.emit(this.domNode, "dgrid-columnstatechange", {
-				grid: this,
-				column: this.columns[id],
-				hidden: hidden,
-				bubbles: true
-			});
-
-			// Adjust the size of the header.
-			this.resize();
-		},
-		
-		toggleColumnHiddenState: function(id, hidden){
-			// summary:
-			//		Shows or hides the column with the given id.
-			// id: String
-			//		ID of column to show/hide.
-			// hide: Boolean?
-			//		If specified, explicitly sets the hidden state of the specified
-			//		column.  If unspecified, toggles the column from the current state.
-			
-			if(typeof hidden === "undefined"){ hidden = !this._columnHiderRules[id]; }
-			this._updateColumnHiddenState(id, hidden);
-			
-			// Since this can be called directly, re-sync the appropriate checkbox.
-			this._columnHiderCheckboxes[id].checked = !hidden;
-		}
-	});
-});

+ 0 - 193
esp/files/dgrid/extensions/ColumnReorder.js

@@ -1,193 +0,0 @@
-define([
-	"dojo/_base/lang",
-	"dojo/_base/declare",
-	"dojo/_base/array",
-	"dojo/on",
-	"dojo/query",
-	"dojo/dnd/Source",
-	"put-selector/put",
-	"xstyle/css!../css/extensions/ColumnReorder.css"
-], function(lang, declare, arrayUtil, on, query, DndSource, put){
-	var dndTypeRx = /(\d+)(?:-(\d+))?$/; // used to determine subrow from dndType
-	
-	// The following 2 functions are used by onDropInternal logic for
-	// retrieving/modifying a given subRow.  The `match` variable in each is
-	// expected to be the result of executing dndTypeRx on a subRow ID.
-	
-	function getMatchingSubRow(grid, match) {
-		var hasColumnSets = match[2],
-			rowOrSet = grid[hasColumnSets ? "columnSets" : "subRows"][match[1]];
-		
-		return hasColumnSets ? rowOrSet[match[2]] : rowOrSet;
-	}
-	
-	function setMatchingSubRow(grid, match, subRow) {
-		if(match[2]){
-			grid.columnSets[match[1]][match[2]] = subRow;
-		}else{
-			grid.subRows[match[1]] = subRow;
-		}
-	}
-
-	// Builds a prefix for a dndtype value based on a grid id.
-	function makeDndTypePrefix(gridId) {
-		return "dgrid-" + gridId + '-';
-	}
-
-	// Removes the grid id prefix from a dndtype value.  This allows the grid id to contain
-	// a dash-number suffix.  This works only if a column is dropped on the grid from which it
-	// originated.  Otherwise, a dash-number suffix will cause the regex to match on the wrong values.
-	function stripIdPrefix(gridId, dndtype) {
-		return dndtype.slice(makeDndTypePrefix(gridId).length);
-	}
-	
-	var ColumnDndSource = declare(DndSource, {
-		// summary:
-		//		Custom dojo/dnd source extension configured specifically for
-		//		dgrid column reordering.
-		
-		copyState: function(){ return false; }, // never copy
-		
-		checkAcceptance: function(source, nodes){
-			return source == this; // self-accept only
-		},
-		
-		_legalMouseDown: function(evt){
-			// Overridden to prevent blocking ColumnResizer resize handles.
-			return evt.target.className.indexOf("dgrid-resize-handle") > -1 ? false :
-				this.inherited(arguments);
-		},
-		
-		onDropInternal: function(nodes){
-			var grid = this.grid,
-				match = dndTypeRx.exec(stripIdPrefix(grid.id, nodes[0].getAttribute("dndType"))),
-				structureProperty = match[2] ? "columnSets" : "subRows",
-				oldSubRow = getMatchingSubRow(grid, match),
-				columns = grid.columns;
-			
-			// First, allow original DnD logic to place node in new location.
-			this.inherited(arguments);
-			
-			if(!match){ return; }
-			
-			// Then, iterate through the header cells in their new order,
-			// to populate a new row array to assign as a new sub-row to the grid.
-			// (Wait until the next turn to avoid errors in Opera.)
-			setTimeout(function(){
-				var newSubRow = arrayUtil.map(nodes[0].parentNode.childNodes, function(col) {
-						return columns[col.columnId];
-					}),
-					eventObject;
-				
-				setMatchingSubRow(grid, match, newSubRow);
-				
-				eventObject = {
-					grid: grid,
-					subRow: newSubRow,
-					column: columns[nodes[0].columnId],
-					bubbles: true,
-					cancelable: true,
-					// Set parentType to indicate this is the result of user interaction.
-					parentType: "dnd"
-				};
-				// Set columnSets or subRows depending on which the grid is using.
-				eventObject[structureProperty] = grid[structureProperty];
-				
-				// Emit a custom event which passes the new structure.
-				// Allow calling preventDefault() to cancel the reorder operation.
-				if(on.emit(grid.domNode, "dgrid-columnreorder", eventObject)){
-					// Event was not canceled - force processing of modified structure.
-					grid.set(structureProperty, grid[structureProperty]);
-				}else{
-					// Event was canceled - revert the structure and re-render the header
-					// (since the inherited logic invoked above will have shifted cells).
-					setMatchingSubRow(grid, match, oldSubRow);
-					grid.renderHeader();
-					// After re-rendering the header, re-apply the sort arrow if needed.
-					if (this._sort && this._sort.length){
-						this.updateSortArrow(this._sort);
-					}
-				}
-			}, 0);
-		}
-	});
-	
-	var ColumnReorder = declare(null, {
-		// summary:
-		//		Extension allowing reordering of columns in a grid via drag'n'drop.
-		//		Reordering of columns within the same subrow or columnset is also
-		//		supported; between different ones is not.
-		
-		// columnDndConstructor: Function
-		//		Constructor to call for instantiating DnD sources within the grid's
-		//		header.
-		columnDndConstructor: ColumnDndSource,
-		
-		_initSubRowDnd: function(subRow, dndType){
-			// summary:
-			//		Initializes a dojo/dnd source for one subrow of a grid;
-			//		this could be its only subrow, one of several, or a subrow within a
-			//		columnset.
-			
-			var dndParent, c, len, col, th;
-			
-			for(c = 0, len = subRow.length; c < len; c++){
-				col = subRow[c];
-				if(col.reorderable === false){ continue; }
-				
-				th = col.headerNode;
-				if(th.tagName != "TH"){ th = th.parentNode; } // from IE < 8 padding
-				// Add dojoDndItem class, and a dndType unique to this subrow.
-				put(th, ".dojoDndItem[dndType=" + dndType + "]");
-				
-				if(!dndParent){ dndParent = th.parentNode; }
-			}
-			
-			if(dndParent){ // (if dndParent wasn't set, no columns are draggable!)
-				this._columnDndSources.push(new this.columnDndConstructor(dndParent, {
-					horizontal: true,
-					grid: this
-				}));
-			}
-		},
-		
-		renderHeader: function(){
-			var dndTypePrefix = makeDndTypePrefix(this.id),
-				csLength, cs;
-			
-			this.inherited(arguments);
-			
-			// After header is rendered, set up a dnd source on each of its subrows.
-			
-			this._columnDndSources = [];
-			
-			if(this.columnSets){
-				// Iterate columnsets->subrows->columns.
-				for(cs = 0, csLength = this.columnSets.length; cs < csLength; cs++){
-					arrayUtil.forEach(this.columnSets[cs], function(subRow, sr){
-						this._initSubRowDnd(subRow, dndTypePrefix + cs + "-" + sr);
-					}, this);
-				}
-			}else{
-				// Iterate subrows->columns.
-				arrayUtil.forEach(this.subRows, function(subRow, sr){
-					this._initSubRowDnd(subRow, dndTypePrefix + sr);
-				}, this);
-			}
-		},
-		
-		_destroyColumns: function(){
-			if(this._columnDndSources){
-				// Destroy old dnd sources.
-				arrayUtil.forEach(this._columnDndSources, function(source){
-					source.destroy();
-				});
-			}
-			
-			this.inherited(arguments);
-		}
-	});
-	
-	ColumnReorder.ColumnDndSource = ColumnDndSource;
-	return ColumnReorder;
-});

+ 0 - 448
esp/files/dgrid/extensions/ColumnResizer.js

@@ -1,448 +0,0 @@
-define(["dojo/_base/declare", "dojo/on", "dojo/query", "dojo/_base/lang", "dojo/dom", "dojo/dom-geometry", "dojo/has", "../util/misc", "put-selector/put", "dojo/_base/html", "xstyle/css!../css/extensions/ColumnResizer.css"],
-function(declare, listen, query, lang, dom, geom, has, miscUtil, put){
-
-function addRowSpan(table, span, startRow, column, id){
-	// loop through the rows of the table and add this column's id to
-	// the rows' column
-	for(var i=1; i<span; i++){
-		table[startRow+i][column] = id;
-	}
-}
-function subRowAssoc(subRows){
-	// Take a sub-row structure and output an object with key=>value pairs
-	// The keys will be the column id's; the values will be the first-row column
-	// that column's resizer should be associated with.
-
-	var i = subRows.length,
-		l = i,
-		numCols = subRows[0].length,
-		table = new Array(i);
-
-	// create table-like structure in an array so it can be populated
-	// with row-spans and col-spans
-	while(i--){
-		table[i] = new Array(numCols);
-	}
-
-	var associations = {};
-
-	for(i=0; i<l; i++){
-		var row = table[i],
-			subRow = subRows[i];
-
-		// j: counter for table columns
-		// js: counter for subrow structure columns
-		for(var j=0, js=0; j<numCols; j++){
-			var cell = subRow[js], k;
-
-			// if something already exists in the table (row-span), skip this
-			// spot and go to the next
-			if(typeof row[j] != "undefined"){
-				continue;
-			}
-			row[j] = cell.id;
-
-			if(cell.rowSpan && cell.rowSpan > 1){
-				addRowSpan(table, cell.rowSpan, i, j, cell.id);
-			}
-
-			// colSpans are only applicable in the second or greater rows
-			// and only if the colSpan is greater than 1
-			if(i>0 && cell.colSpan && cell.colSpan > 1){
-				for(k=1; k<cell.colSpan; k++){
-					// increment j and assign the id since this is a span
-					row[++j] = cell.id;
-					if(cell.rowSpan && cell.rowSpan > 1){
-						addRowSpan(table, cell.rowSpan, i, j, cell.id);
-					}
-				}
-			}
-			associations[cell.id] = subRows[0][j].id;
-			js++;
-		}
-	}
-
-	return associations;
-}
-
-function resizeColumnWidth(grid, colId, width, parentType){
-	// don't react to widths <= 0, e.g. for hidden columns
-	if(width <= 0){ return; }
-
-	var column = grid.columns[colId],
-		event = {
-			grid: grid,
-			columnId: colId,
-			width: width,
-			bubbles: true,
-			cancelable: true
-		},
-		rule;
-	
-	if(parentType){
-		event.parentType = parentType;
-	}
-	
-	if(!grid._resizedColumns || listen.emit(grid.headerNode, "dgrid-columnresize", event)){
-		// Update width on column object, then convert value for CSS
-		if(width === "auto"){
-			delete column.width;
-		}else{
-			column.width = width;
-			width += "px";
-		}
-		
-		rule = grid._columnSizes[colId];
-		
-		if(rule){
-			// Modify existing, rather than deleting + adding
-			rule.set("width", width);
-		}else{
-			// Use miscUtil function directly, since we clean these up ourselves anyway
-			rule = miscUtil.addCssRule(
-				"#" + miscUtil.escapeCssIdentifier(grid.domNode.id) + " .dgrid-column-" + colId, "width: " + width + ";");
-		}
-
-		// keep a reference for future removal
-		grid._columnSizes[colId] = rule;
-		grid.resize();
-		return true;
-	}
-}
-
-// Functions for shared resizer node
-
-var resizerNode, // DOM node for resize indicator, reused between instances
-	resizableCount = 0; // Number of ColumnResizer-enabled grid instances
-var resizer = {
-	// This object contains functions for manipulating the shared resizerNode
-	create: function(){
-		resizerNode = put("div.dgrid-column-resizer");
-	},
-	destroy: function(){
-		put(resizerNode, "!");
-		resizerNode = null;
-	},
-	show: function(grid){
-		var pos = geom.position(grid.domNode, true);
-		resizerNode.style.top = pos.y + "px";
-		resizerNode.style.height = pos.h + "px";
-		put(document.body, resizerNode);
-	},
-	move: function(x){
-		resizerNode.style.left = x + "px";
-	},
-	hide: function(){
-		resizerNode.parentNode.removeChild(resizerNode);
-	}
-};
-
-return declare(null, {
-	resizeNode: null,
-	
-	// minWidth: Number
-	//		Minimum column width, in px.
-	minWidth: 40,
-	
-	// adjustLastColumn: Boolean
-	//		If true, adjusts the last column's width to "auto" at times where the
-	//		browser would otherwise stretch all columns to span the grid.
-	adjustLastColumn: true,
-	
-	_resizedColumns: false, // flag indicating if resizer has converted column widths to px
-	
-	buildRendering: function(){
-		this.inherited(arguments);
-		
-		// Create resizerNode when first grid w/ ColumnResizer is created
-		if(!resizableCount++){
-			resizer.create();
-		}
-	},
-	
-	destroy: function(){
-		this.inherited(arguments);
-		
-		// Remove any applied column size styles since we're tracking them directly
-		for(var name in this._columnSizes){
-			this._columnSizes[name].remove();
-		}
-		
-		// If this is the last grid on the page with ColumnResizer, destroy the
-		// shared resizerNode
-		if(!--resizableCount){
-			resizer.destroy();
-		}
-	},
-	
-	resizeColumnWidth: function(colId, width){
-		// Summary:
-		//      calls grid's styleColumn function to add a style for the column
-		// colId: String
-		//      column id
-		// width: Integer
-		//      new width of the column
-		return resizeColumnWidth(this, colId, width);
-	},
-	
-	configStructure: function(){
-		var oldSizes = this._oldColumnSizes = lang.mixin({}, this._columnSizes), // shallow clone
-			k;
-		
-		this._resizedColumns = false;
-		this._columnSizes = {};
-		
-		this.inherited(arguments);
-		
-		// Remove old column styles that are no longer relevant; this is specifically
-		// done *after* calling inherited so that _columnSizes will contain keys
-		// for all columns in the new structure that were assigned widths.
-		for(k in oldSizes){
-			if(!(k in this._columnSizes)){
-				oldSizes[k].remove();
-			}
-		}
-		delete this._oldColumnSizes;
-	},
-	
-	_configColumn: function(column){
-		this.inherited(arguments);
-		
-		var colId = column.id,
-			rule;
-		
-		if("width" in column){
-			// Update or add a style rule for the specified width
-			if((rule = this._oldColumnSizes[colId])){
-				rule.set("width", column.width + "px");
-			}else{
-				rule = miscUtil.addCssRule(
-					"#" + this.domNode.id + " .dgrid-column-" + colId, "width: " + column.width + "px;");
-			}
-			this._columnSizes[colId] = rule;
-		}
-	},
-	
-	renderHeader: function(){
-		this.inherited(arguments);
-		
-		var grid = this;
-		
-		var assoc;
-		if(this.columnSets && this.columnSets.length){
-			var csi = this.columnSets.length;
-			while(csi--){
-				assoc = lang.mixin(assoc||{}, subRowAssoc(this.columnSets[csi]));
-			}
-		}else if(this.subRows && this.subRows.length > 1){
-			assoc = subRowAssoc(this.subRows);
-		}
-
-		var colNodes = query(".dgrid-cell", grid.headerNode),
-			i = colNodes.length;
-		while(i--){
-			var colNode = colNodes[i],
-				id = colNode.columnId,
-				col = grid.columns[id],
-				childNodes = colNode.childNodes;
-
-			if(!col || col.resizable === false){ continue; }
-
-			var headerTextNode = put("div.dgrid-resize-header-container");
-			colNode.contents = headerTextNode;
-
-			// move all the children to the header text node
-			while(childNodes.length > 0){
-				put(headerTextNode, childNodes[0]);
-			}
-
-			put(colNode, headerTextNode, "div.dgrid-resize-handle.resizeNode-"+id).columnId = 
-				assoc ? assoc[id] : id;
-		}
-
-		if(!grid.mouseMoveListen){
-			// establish listeners for initiating, dragging, and finishing resize
-			listen(grid.headerNode,
-				".dgrid-resize-handle:mousedown" +
-					(has("touch") ? ",.dgrid-resize-handle:touchstart" : ""),
-				function(e){
-					grid._resizeMouseDown(e, this);
-					grid.mouseMoveListen.resume();
-					grid.mouseUpListen.resume();
-				}
-			);
-			grid._listeners.push(grid.mouseMoveListen = listen.pausable(document,
-				"mousemove" + (has("touch") ? ",touchmove" : ""),
-				miscUtil.throttleDelayed(function(e){ grid._updateResizerPosition(e); })
-			));
-			grid._listeners.push(grid.mouseUpListen = listen.pausable(document,
-				"mouseup" + (has("touch") ? ",touchend" : ""),
-				function(e){
-					grid._resizeMouseUp(e);
-					grid.mouseMoveListen.pause();
-					grid.mouseUpListen.pause();
-				}
-			));
-			// initially pause the move/up listeners until a drag happens
-			grid.mouseMoveListen.pause();
-			grid.mouseUpListen.pause();
-		}
-	}, // end renderHeader
-
-	_resizeMouseDown: function(e, target){
-		// Summary:
-		//      called when mouse button is pressed on the header
-		// e: Object
-		//      mousedown event object
-		
-		// preventDefault actually seems to be enough to prevent browser selection
-		// in all but IE < 9.  setSelectable works for those.
-		e.preventDefault();
-		dom.setSelectable(this.domNode, false);
-		this._startX = this._getResizeMouseLocation(e); //position of the target
-		
-		this._targetCell = query(".dgrid-column-" + target.columnId, this.headerNode)[0];
-
-		// Show resizerNode after initializing its x position
-		this._updateResizerPosition(e);
-		resizer.show(this);
-	},
-	_resizeMouseUp: function(e){
-		// Summary:
-		//      called when mouse button is released
-		// e: Object
-		//      mouseup event object
-		
-		var columnSizes = this._columnSizes,
-			colNodes, colWidths, gridWidth;
-		
-		if(this.adjustLastColumn){
-			// For some reason, total column width needs to be 1 less than this
-			gridWidth = this.headerNode.clientWidth - 1;
-		}
-		
-		//This is used to set all the column widths to a static size
-		if(!this._resizedColumns){
-			colNodes = query(".dgrid-cell", this.headerNode);
-			
-			if(this.columnSets && this.columnSets.length){
-				colNodes = colNodes.filter(function(node){
-					var idx = node.columnId.split("-");
-					return idx[0] == "0" && !(node.columnId in columnSizes);
-				});
-			}else if(this.subRows && this.subRows.length > 1){
-				colNodes = colNodes.filter(function(node){
-					return node.columnId.charAt(0) == "0" && !(node.columnId in columnSizes);
-				});
-			}
-			
-			// Get a set of sizes before we start mutating, to avoid
-			// weird disproportionate measures if the grid has set
-			// column widths, but no full grid width set
-			colWidths = colNodes.map(function(colNode){
-				return colNode.offsetWidth;
-			});
-			
-			// Set a baseline size for each column based on
-			// its original measure
-			colNodes.forEach(function(colNode, i){
-				this.resizeColumnWidth(colNode.columnId, colWidths[i]);
-			}, this);
-			
-			this._resizedColumns = true;
-		}
-		dom.setSelectable(this.domNode, true);
-		
-		var cell = this._targetCell,
-			delta = this._getResizeMouseLocation(e) - this._startX, //final change in position of resizer
-			newWidth = cell.offsetWidth + delta, //the new width after resize
-			obj = this._getResizedColumnWidths(),//get current total column widths before resize
-			totalWidth = obj.totalWidth,
-			lastCol = obj.lastColId,
-			lastColWidth = query(".dgrid-column-"+lastCol, this.headerNode)[0].offsetWidth;
-		
-		if(newWidth < this.minWidth){
-			//enforce minimum widths
-			newWidth = this.minWidth;
-		}
-		
-		if(resizeColumnWidth(this, cell.columnId, newWidth, e.type)){
-			if(cell.columnId != lastCol && this.adjustLastColumn){
-				if(totalWidth + delta < gridWidth) {
-					//need to set last column's width to auto
-					resizeColumnWidth(this, lastCol, "auto", e.type);
-				}else if(lastColWidth-delta <= this.minWidth) {
-					//change last col width back to px, unless it is the last column itself being resized...
-					resizeColumnWidth(this, lastCol, this.minWidth, e.type);
-				}
-			}
-		}
-		resizer.hide();
-		
-		// Clean up after the resize operation
-		delete this._startX;
-		delete this._targetCell;
-	},
-	
-	_updateResizerPosition: function(e){
-		// Summary:
-		//      updates position of resizer bar as mouse moves
-		// e: Object
-		//      mousemove event object
-
-		if(!this._targetCell){ return; } // Release event was already processed
-		
-		var mousePos = this._getResizeMouseLocation(e),
-			delta = mousePos - this._startX, //change from where user clicked to where they drag
-			width = this._targetCell.offsetWidth,
-			left = mousePos;
-		if(width + delta < this.minWidth){ 
-			left = this._startX - (width - this.minWidth); 
-		}
-		resizer.move(left);
-	},
-
-	_getResizeMouseLocation: function(e){
-		//Summary:
-		//      returns position of mouse relative to the left edge
-		// e: event object
-		//      mouse move event object
-		var posX = 0;
-		if(e.pageX){
-			posX = e.pageX;
-		}else if(e.clientX){
-			posX = e.clientX + document.body.scrollLeft +
-				document.documentElement.scrollLeft;
-		}
-		return posX;
-	},
-	_getResizedColumnWidths: function (){
-		//Summary:
-		//      returns object containing new column width and column id
-		var totalWidth = 0,
-			colNodes = query(".dgrid-cell", this.headerNode);
-
-		// For ColumnSets and subRows, only the top row of columns matters
-		if(this.columnSets && this.columnSets.length){
-			colNodes = colNodes.filter(function(node){
-				var idx = node.columnId.split("-");
-				return idx[1] == "0";
-			});
-		}else if(this.subRows && this.subRows.length > 1){
-			colNodes = colNodes.filter(function(node){
-				return node.columnId.charAt(0) == "0";
-			});
-		}
-
-		var i = colNodes.length;
-		if(!i){ return {}; }
-
-		var lastColId = colNodes[i-1].columnId;
-
-		while(i--){
-			totalWidth += colNodes[i].offsetWidth;
-		}
-		return {totalWidth: totalWidth, lastColId: lastColId};
-	}
-});
-});

+ 0 - 90
esp/files/dgrid/extensions/CompoundColumns.js

@@ -1,90 +0,0 @@
-define([
-	"dojo/_base/lang",
-	"dojo/_base/declare",
-	"dgrid/util/misc",
-	"xstyle/css!../css/extensions/CompoundColumns.css"
-], function(lang, declare, miscUtil){
-	return declare(null, {
-		// summary:
-		//		Extension allowing for specification of columns with additional
-		//		header rows spanning multiple columns for strictly display purposes.
-		//		Only works on `columns` arrays, not `columns` objects or `subRows`
-		//		(nor ColumnSets).
-		// description:
-		//		CompoundColumns allows nested header cell configurations, wherein the
-		//		higher-level headers may span multiple columns and are for
-		//		display purposes only.
-		//		These nested header cells are configured using a special recursive
-		//		`children` property in the column definition, where only the deepest
-		//		children are ultimately rendered in the grid as actual columns.
-		//		In addition, the deepest child columns may be rendered without
-		//		individual headers by specifying `showChildHeaders: false` on the parent.
-		
-		configStructure: function(){
-			// create a set of sub rows for the header row so we can do compound columns
-			// the first row is a special spacer row
-			var columns = (this.subRows && this.subRows[0]) || this.columns,
-				headerRows = [[]],
-				contentColumns = [];
-			// This first row is spacer row that will be made invisible (zero height)
-			// with CSS, but it must be rendered as the first row since that is what
-			// the table layout is driven by.
-			headerRows[0].className = "dgrid-spacer-row";
-			
-			function processColumns(columns, level, hasLabel){
-				var numColumns = 0,
-					noop = function(){},
-					column, children, hasChildLabels;
-				
-				function processColumn(column, i){
-					children = column.children;
-					hasChildLabels = column.children && (column.showChildHeaders !== false);
-					if(children){
-						// it has children, recursively process the children
-						numColumns += (column.colSpan = processColumns(children, level + 1, hasChildLabels));
-					}else{
-						// it has no children, it is a normal header, add it to the content columns
-						contentColumns.push(column);
-						// add each one to the first spacer header row for proper layout of the header cells
-						headerRows[0].push(lang.delegate(column, {renderHeaderCell: noop}));
-						numColumns++;
-					}
-					if(!hasChildLabels){
-						// create a header version of the column where we can define a specific rowSpan
-						// we define the rowSpan as a negative, the number of levels less than the total number of rows, which we don't know yet
-						column = lang.delegate(column, {rowSpan: -level});
-					}
-					// add the column to the header rows at the appropriate level
-					if(hasLabel){
-						(headerRows[level] || (headerRows[level] = [])).push(column);
-					}
-				}
-				
-				miscUtil.each(columns, processColumn, this);
-				return numColumns;
-			}
-			processColumns(columns, 1, true);
-			
-			var numHeaderRows = headerRows.length,
-				i, j, headerRow, headerColumn;
-			// Now go back through and increase the rowSpans of the headers to be
-			// total rows minus the number of levels they are at.
-			for(i = 0; i < numHeaderRows; i++){
-				headerRow = headerRows[i];
-				for(j = 0; j < headerRow.length; j++){
-					headerColumn = headerRow[j];
-					if(headerColumn.rowSpan < 1){
-						headerColumn.rowSpan += numHeaderRows;
-					}
-				}
-			}
-			// we need to set this to be used for subRows, so we make it a single row
-			contentColumns = [contentColumns];
-			// set our header rows so that the grid will use the alternate header row 
-			// configuration for rendering the headers
-			contentColumns.headerRows = headerRows;  
-			this.subRows = contentColumns;
-			this.inherited(arguments);
-		}
-	});
-});

+ 0 - 83
esp/files/dgrid/extensions/DijitRegistry.js

@@ -1,83 +0,0 @@
-define(["dojo/_base/declare", "dojo/dom-geometry", "dijit/registry"],
-function(declare, domGeometry, registry){
-	return declare(null, {
-		// summary:
-		//		A dgrid extension which will add the grid to the dijit registry,
-		//		so that startup() will be successfully called by dijit layout widgets
-		//		with dgrid children.
-		
-		// Defaults normally imposed on _WidgetBase by container widget modules:
-		minSize: 0, // BorderContainer
-		maxSize: Infinity, // BorderContainer
-		layoutPriority: 0, // BorderContainer
-		showTitle: true, // StackContainer
-		
-		buildRendering: function(){
-			registry.add(this);
-			this.inherited(arguments);
-			// Note: for dojo 2.0 may rename widgetId to dojo._scopeName + "_widgetId"
-			this.domNode.setAttribute("widgetId", this.id);
-		},
-		
-		startup: function(){
-			if(this._started){ return; }
-			this.inherited(arguments);
-			
-			var widget = registry.getEnclosingWidget(this.domNode.parentNode);
-			// If we have a parent layout container widget, it will handle resize,
-			// so remove the window resize listener added by List.
-			if(widget && widget.isLayoutContainer){
-				this._resizeHandle.remove();
-			}
-		},
-
-		destroyRecursive: function() {
-			this.destroy();
-		},
-		
-		destroy: function(){
-			this.inherited(arguments);
-			registry.remove(this.id);
-		},
-		
-		getChildren: function(){
-			// provide hollow implementation for logic which assumes its existence
-			// (e.g. dijit/form/_FormMixin)
-			return [];
-		},
-		
-		isLeftToRight: function(){
-			// Implement method expected by Dijit layout widgets
-			return !this.isRTL;
-		},
-		
-		resize: function(changeSize){
-			// Honor changeSize parameter used by layout widgets, and resize grid
-			if(changeSize){
-				domGeometry.setMarginBox(this.domNode, changeSize);
-			}
-			
-			this.inherited(arguments);
-		},
-		
-		_set: function(prop, value){
-			// summary:
-			//		Simple analogue of _WidgetBase#_set for compatibility with some
-			//		Dijit layout widgets which assume its existence.
-			this[prop] = value;
-		},
-		
-		watch: function(){
-			// summary:
-			//		dgrid doesn't support watch; this is a no-op for compatibility with
-			//		some Dijit layout widgets which assume its existence.
-		},
-		
-		getParent: function(){
-			// summary:
-			//		Analogue of _WidgetBase#getParent for compatibility with for example
-			//		dijit._KeyNavContainer.
-			return registry.getEnclosingWidget(this.domNode.parentNode);
-		}
-	});
-});

+ 0 - 286
esp/files/dgrid/extensions/DnD.js

@@ -1,286 +0,0 @@
-define([
-	"dojo/_base/declare",
-	"dojo/_base/lang",
-	"dojo/_base/array",
-	"dojo/_base/Deferred",
-	"dojo/aspect",
-	"dojo/on",
-	"dojo/topic",
-	"dojo/has",
-	"dojo/dnd/Source",
-	"dojo/dnd/Manager",
-	"dojo/_base/NodeList",
-	"put-selector/put",
-	"../Selection",
-	"dojo/has!touch?../util/touch",
-	"dojo/has!touch?./_DnD-touch-autoscroll",
-	"xstyle/css!dojo/resources/dnd.css"
-], function(declare, lang, arrayUtil, Deferred, aspect, on, topic, has, DnDSource, DnDManager, NodeList, put, Selection, touchUtil){
-	// Requirements
-	// * requires a store (sounds obvious, but not all Lists/Grids have stores...)
-	// * must support options.before in put calls
-	//   (if undefined, put at end)
-	// * should support copy
-	//   (copy should also support options.before as above)
-	
-	// TODOs
-	// * consider sending items rather than nodes to onDropExternal/Internal
-	// * consider emitting store errors via OnDemandList._trackError
-	
-	var GridDnDSource = declare(DnDSource, {
-		grid: null,
-		
-		getObject: function(node){
-			// summary:
-			//		getObject is a method which should be defined on any source intending
-			//		on interfacing with dgrid DnD.
-			
-			var grid = this.grid;
-			// Extract item id from row node id (gridID-row-*).
-			return grid.store.get(node.id.slice(grid.id.length + 5));
-		},
-		_legalMouseDown: function(evt){
-			// Fix _legalMouseDown to only allow starting drag from an item
-			// (not from bodyNode outside contentNode).
-			var legal = this.inherited(arguments);
-			return legal && evt.target != this.grid.bodyNode;
-		},
-
-		// DnD method overrides
-		onDrop: function(sourceSource, nodes, copy){
-			var targetSource = this,
-				targetRow = this._targetAnchor = this.targetAnchor, // save for Internal
-				grid = this.grid,
-				store = grid.store;
-			
-			if(!this.before && targetRow){
-				// target before next node if dropped within bottom half of this node
-				// (unless there's no node to target at all)
-				targetRow = targetRow.nextSibling;
-			}
-			targetRow = targetRow && grid.row(targetRow);
-			
-			Deferred.when(targetRow && store.get(targetRow.id), function(target){
-				// Note: if dropping after the last row, or into an empty grid,
-				// target will be undefined.  Thus, it is important for store to place
-				// item last in order if options.before is undefined.
-				
-				// Delegate to onDropInternal or onDropExternal for rest of logic.
-				// These are passed the target item as an additional argument.
-				if(targetSource != sourceSource){
-					targetSource.onDropExternal(sourceSource, nodes, copy, target);
-				}else{
-					targetSource.onDropInternal(nodes, copy, target);
-				}
-			});
-		},
-		onDropInternal: function(nodes, copy, targetItem){
-			var store = this.grid.store,
-				targetSource = this,
-				grid = this.grid,
-				anchor = targetSource._targetAnchor,
-				targetRow;
-			
-			if(anchor){ // (falsy if drop occurred in empty space after rows)
-				targetRow = this.before ? anchor.previousSibling : anchor.nextSibling;
-			}
-			
-			// Don't bother continuing if the drop is really not moving anything.
-			// (Don't need to worry about edge first/last cases since dropping
-			// directly on self doesn't fire onDrop, but we do have to worry about
-			// dropping last node into empty space beyond rendered rows.)
-			if(!copy && (targetRow === nodes[0] ||
-					(!targetItem && grid.down(grid.row(nodes[0])).element == nodes[0]))){
-				return;
-			}
-			
-			nodes.forEach(function(node){
-				Deferred.when(targetSource.getObject(node), function(object){
-					// For copy DnD operations, copy object, if supported by store;
-					// otherwise settle for put anyway.
-					// (put will relocate an existing item with the same id, i.e. move).
-					store[copy && store.copy ? "copy" : "put"](object, {
-						before: targetItem
-					});
-				});
-			});
-		},
-		onDropExternal: function(sourceSource, nodes, copy, targetItem){
-			// Note: this default implementation expects that two grids do not
-			// share the same store.  There may be more ideal implementations in the
-			// case of two grids using the same store (perhaps differentiated by
-			// query), dragging to each other.
-			var store = this.grid.store,
-				sourceGrid = sourceSource.grid;
-			
-			// TODO: bail out if sourceSource.getObject isn't defined?
-			nodes.forEach(function(node, i){
-				Deferred.when(sourceSource.getObject(node), function(object){
-					if(!copy){
-						if(sourceGrid){
-							// Remove original in the case of inter-grid move.
-							// (Also ensure dnd source is cleaned up properly)
-							Deferred.when(sourceGrid.store.getIdentity(object), function(id){
-								!i && sourceSource.selectNone(); // deselect all, one time
-								sourceSource.delItem(node.id);
-								sourceGrid.store.remove(id);
-							});
-						}else{
-							sourceSource.deleteSelectedNodes();
-						}
-					}
-					// Copy object, if supported by store; otherwise settle for put
-					// (put will relocate an existing item with the same id).
-					// Note that we use store.copy if available even for non-copy dnd:
-					// since this coming from another dnd source, always behave as if
-					// it is a new store item if possible, rather than replacing existing.
-					store[store.copy ? "copy" : "put"](object, {
-						before: targetItem
-					});
-				});
-			});
-		},
-		
-		onDndStart: function(source, nodes, copy){
-			// Listen for start events to apply style change to avatar.
-			
-			this.inherited(arguments); // DnDSource.prototype.onDndStart.apply(this, arguments);
-			if(source == this){
-				// If TouchScroll is in use, cancel any pending scroll operation.
-				if(this.grid.cancelTouchScroll){ this.grid.cancelTouchScroll(); }
-				
-				// Set avatar width to half the grid's width.
-				// Kind of a naive default, but prevents ridiculously wide avatars.
-				DnDManager.manager().avatar.node.style.width =
-					this.grid.domNode.offsetWidth / 2 + "px";
-			}
-		},
-		
-		onMouseDown: function(evt){
-			// Cancel the drag operation on presence of more than one contact point.
-			// (This check will evaluate to false under non-touch circumstances.)
-			if(has("touch") && this.isDragging &&
-					touchUtil.countCurrentTouches(evt, this.grid.touchNode) > 1){
-				topic.publish("/dnd/cancel");
-				DnDManager.manager().stopDrag();
-			}else{
-				this.inherited(arguments);
-			}
-		},
-		
-		onMouseMove: function(evt){
-			// If we're handling touchmove, only respond to single-contact events.
-			if(!has("touch") || touchUtil.countCurrentTouches(evt, this.grid.touchNode) === 1){
-				this.inherited(arguments);
-			}
-		},
-		
-		checkAcceptance: function(source, nodes){
-			// Augment checkAcceptance to block drops from sources without getObject.
-			return source.getObject &&
-				DnDSource.prototype.checkAcceptance.apply(this, arguments);
-		},
-		getSelectedNodes: function(){
-			// If dgrid's Selection mixin is in use, synchronize with it, using a
-			// map of node references (updated on dgrid-[de]select events).
-			
-			if(!this.grid.selection){
-				return this.inherited(arguments);
-			}
-			var t = new NodeList(),
-				id;
-			for(id in this.grid.selection){
-				t.push(this._selectedNodes[id]);
-			}
-			return t;	// NodeList
-		}
-		// TODO: could potentially also implement copyState to jive with default
-		// onDrop* implementations (checking whether store.copy is available);
-		// not doing that just yet until we're sure about default impl.
-	});
-	
-	// Mix in Selection for more resilient dnd handling, particularly when part
-	// of the selection is scrolled out of view and unrendered (which we
-	// handle below).
-	var DnD = declare(Selection, {
-		// dndSourceType: String
-		//		Specifies the type which will be set for DnD items in the grid,
-		//		as well as what will be accepted by it by default.
-		dndSourceType: "dgrid-row",
-		
-		// dndParams: Object
-		//		Object containing params to be passed to the DnD Source constructor.
-		dndParams: null,
-		
-		// dndConstructor: Function
-		//		Constructor from which to instantiate the DnD Source.
-		//		Defaults to the GridSource constructor defined/exposed by this module.
-		dndConstructor: GridDnDSource,
-		
-		postMixInProperties: function(){
-			this.inherited(arguments);
-			// ensure dndParams is initialized
-			this.dndParams = lang.mixin({ accept: [this.dndSourceType] }, this.dndParams);
-		},
-		
-		postCreate: function(){
-			this.inherited(arguments);
-			
-			// Make the grid's content a DnD source/target.
-			this.dndSource = new (this.dndConstructor || GridDnDSource)(
-				this.bodyNode,
-				lang.mixin(this.dndParams, {
-					// add cross-reference to grid for potential use in inter-grid drop logic
-					grid: this,
-					dropParent: this.contentNode
-				})
-			);
-			
-			// Set up select/deselect handlers to maintain references, in case selected
-			// rows are scrolled out of view and unrendered, but then dragged.
-			var selectedNodes = this.dndSource._selectedNodes = {};
-			
-			function selectRow(row){
-				selectedNodes[row.id] = row.element;
-			}
-			function deselectRow(row){
-				delete selectedNodes[row.id];
-			}
-			
-			this.on("dgrid-select", function(event){
-				arrayUtil.forEach(event.rows, selectRow);
-			});
-			this.on("dgrid-deselect", function(event){
-				arrayUtil.forEach(event.rows, deselectRow);
-			});
-			
-			aspect.after(this, "destroy", function(){
-				delete this.dndSource._selectedNodes;
-				selectedNodes = null;
-				this.dndSource.destroy();
-			}, true);
-		},
-		
-		insertRow: function(object){
-			// override to add dojoDndItem class to make the rows draggable
-			var row = this.inherited(arguments),
-				type = typeof this.getObjectDndType == "function" ?
-					this.getObjectDndType(object) : [this.dndSourceType];
-			
-			put(row, ".dojoDndItem");
-			this.dndSource.setItem(row.id, {
-				data: object,
-				type: type instanceof Array ? type : [type]
-			});
-			return row;
-		},
-		
-		removeRow: function (rowElement) {
-			this.dndSource.delItem(this.row(rowElement));
-			this.inherited(arguments);
-		}
-	});
-	DnD.GridSource = GridDnDSource;
-	
-	return DnD;
-});

+ 0 - 512
esp/files/dgrid/extensions/Pagination.js

@@ -1,512 +0,0 @@
-define(["../_StoreMixin", "dojo/_base/declare", "dojo/_base/array", "dojo/_base/lang", "dojo/_base/Deferred",
-	"dojo/on", "dojo/query", "dojo/string", "dojo/has", "put-selector/put", "dojo/i18n!./nls/pagination",
-	"dojo/_base/sniff", "xstyle/css!../css/extensions/Pagination.css"],
-function(_StoreMixin, declare, arrayUtil, lang, Deferred, on, query, string, has, put, i18n){
-	function cleanupContent(grid){
-		// Remove any currently-rendered rows, or noDataMessage
-		if(grid.noDataNode){
-			put(grid.noDataNode, "!");
-			delete grid.noDataNode;
-		}else{
-			grid.cleanup();
-		}
-		grid.contentNode.innerHTML = "";
-	}
-	function cleanupLoading(grid){
-		if(grid.loadingNode){
-			put(grid.loadingNode, "!");
-			delete grid.loadingNode;
-		}else if(grid._oldPageNodes){
-			// If cleaning up after a load w/ showLoadingMessage: false,
-			// be careful to only clean up rows from the old page, not the new one
-			for(var id in grid._oldPageNodes){
-				grid.removeRow(grid._oldPageNodes[id]);
-			}
-			delete grid._oldPageNodes;
-			// Also remove the observer from the previous page, if there is one
-			if(grid._oldPageObserver){
-				grid._oldPageObserver.cancel();
-				grid._numObservers--;
-				delete grid._oldPageObserver;
-			}
-		}
-		delete grid._isLoading;
-	}
-	
-	return declare(_StoreMixin, {
-		// summary:
-		//		An extension for adding discrete pagination to a List or Grid.
-		
-		// rowsPerPage: Number
-		//		Number of rows (items) to show on a given page.
-		rowsPerPage: 10,
-		
-		// pagingTextBox: Boolean
-		//		Indicates whether or not to show a textbox for paging.
-		pagingTextBox: false,
-		// previousNextArrows: Boolean
-		//		Indicates whether or not to show the previous and next arrow links.
-		previousNextArrows: true,
-		// firstLastArrows: Boolean
-		//		Indicates whether or not to show the first and last arrow links.
-		firstLastArrows: false,
-		
-		// pagingLinks: Number
-		//		The number of page links to show on each side of the current page
-		//		Set to 0 (or false) to disable page links.
-		pagingLinks: 2,
-		// pageSizeOptions: Array[Number]
-		//		This provides options for different page sizes in a drop-down.
-		//		If it is empty (default), no page size drop-down will be displayed.
-		pageSizeOptions: null,
-		
-		// showLoadingMessage: Boolean
-		//		If true, clears previous data and displays loading node when requesting
-		//		another page; if false, leaves previous data in place until new data
-		//		arrives, then replaces it immediately.
-		showLoadingMessage: true,
-		
-		// i18nPagination: Object
-		//		This object contains all of the internationalized strings as
-		//		key/value pairs.
-		i18nPagination: i18n,
-		
-		showFooter: true,
-		_currentPage: 1,
-		_total: 0,
-		
-		buildRendering: function(){
-			this.inherited(arguments);
-			
-			// add pagination to footer
-			var grid = this,
-				paginationNode = this.paginationNode =
-					put(this.footerNode, "div.dgrid-pagination"),
-				statusNode = this.paginationStatusNode =
-					put(paginationNode, "div.dgrid-status"),
-				i18n = this.i18nPagination,
-				navigationNode,
-				node,
-				i;
-			
-			statusNode.tabIndex = 0;
-			
-			// Initialize UI based on pageSizeOptions and rowsPerPage
-			this._updatePaginationSizeSelect();
-			this._updateRowsPerPageOption();
-			
-			// initialize some content into paginationStatusNode, to ensure
-			// accurate results on initial resize call
-			statusNode.innerHTML = string.substitute(i18n.status,
-				{ start: 1, end: 1, total: 0 });
-			
-			navigationNode = this.paginationNavigationNode =
-				put(paginationNode, "div.dgrid-navigation");
-			
-			if(this.firstLastArrows){
-				// create a first-page link
-				node = this.paginationFirstNode =
-					put(navigationNode,  "span.dgrid-first.dgrid-page-link", "«");
-				node.setAttribute("aria-label", i18n.gotoFirst);
-				node.tabIndex = 0;
-			}
-			if(this.previousNextArrows){
-				// create a previous link
-				node = this.paginationPreviousNode =
-					put(navigationNode,  "span.dgrid-previous.dgrid-page-link", "‹");
-				node.setAttribute("aria-label", i18n.gotoPrev);
-				node.tabIndex = 0;
-			}
-			
-			this.paginationLinksNode = put(navigationNode, "span.dgrid-pagination-links");
-			if(this.previousNextArrows){
-				// create a next link
-				node = this.paginationNextNode =
-					put(navigationNode, "span.dgrid-next.dgrid-page-link", "›");
-				node.setAttribute("aria-label", i18n.gotoNext);
-				node.tabIndex = 0;
-			}
-			if(this.firstLastArrows){
-				// create a last-page link
-				node = this.paginationLastNode =
-					put(navigationNode,  "span.dgrid-last.dgrid-page-link", "»");
-				node.setAttribute("aria-label", i18n.gotoLast);
-				node.tabIndex = 0;
-			}
-			
-			this._listeners.push(on(navigationNode, ".dgrid-page-link:click,.dgrid-page-link:keydown", function(event){
-				// For keyboard events, only respond to enter
-				if(event.type === "keydown" && event.keyCode !== 13){
-					return;
-				}
-				
-				var cls = this.className,
-					curr, max;
-				
-				if(grid._isLoading || cls.indexOf("dgrid-page-disabled") > -1){
-					return;
-				}
-				
-				curr = grid._currentPage;
-				max = Math.ceil(grid._total / grid.rowsPerPage);
-				
-				// determine navigation target based on clicked link's class
-				if(this === grid.paginationPreviousNode){
-					grid.gotoPage(curr - 1);
-				}else if(this === grid.paginationNextNode){
-					grid.gotoPage(curr + 1);
-				}else if(this === grid.paginationFirstNode){
-					grid.gotoPage(1);
-				}else if(this === grid.paginationLastNode){
-					grid.gotoPage(max);
-				}else if(cls === "dgrid-page-link"){
-					grid.gotoPage(+this.innerHTML, true); // the innerHTML has the page number
-				}
-			}));
-		},
-		
-		destroy: function(){
-			this.inherited(arguments);
-			if(this._pagingTextBoxHandle){
-				this._pagingTextBoxHandle.remove();
-			}
-		},
-
-		_updatePaginationSizeSelect: function(){
-			// summary:
-			//		Creates or repopulates the pagination size selector based on
-			//		the values in pageSizeOptions. Called from buildRendering
-			//		and _setPageSizeOptions.
-			
-			var pageSizeOptions = this.pageSizeOptions,
-				paginationSizeSelect = this.paginationSizeSelect,
-				handle;
-			
-			if(pageSizeOptions && pageSizeOptions.length){
-				if(!paginationSizeSelect){
-					// First time setting page options; create the select
-					paginationSizeSelect = this.paginationSizeSelect =
-						put(this.paginationNode, "select.dgrid-page-size");
-					
-					handle = this._paginationSizeChangeHandle =
-						on(paginationSizeSelect, "change", lang.hitch(this, function(){
-							this.set("rowsPerPage", +this.paginationSizeSelect.value);
-						}));
-					this._listeners.push(handle);
-				}
-				
-				// Repopulate options
-				paginationSizeSelect.options.length = 0;
-				for(i = 0; i < pageSizeOptions.length; i++){
-					put(paginationSizeSelect, "option", pageSizeOptions[i], {
-						value: pageSizeOptions[i],
-						selected: this.rowsPerPage === pageSizeOptions[i]
-					});
-				}
-				// Ensure current rowsPerPage value is in options
-				this._updateRowsPerPageOption();
-			}else if(!(pageSizeOptions && pageSizeOptions.length) && paginationSizeSelect){
-				// pageSizeOptions was removed; remove/unhook the drop-down
-				put(paginationSizeSelect, "!");
-				this.paginationSizeSelect = null;
-				this._paginationSizeChangeHandle.remove();
-			}
-		},
-
-		_setPageSizeOptions: function(pageSizeOptions){
-			this.pageSizeOptions = pageSizeOptions && pageSizeOptions.sort(function(a, b){
-				return a - b;
-			});
-			this._updatePaginationSizeSelect();
-		},
-
-		_updateRowsPerPageOption: function(){
-			// summary:
-			//		Ensures that an option for rowsPerPage's value exists in the
-			//		paginationSizeSelect drop-down (if one is rendered).
-			//		Called from buildRendering and _setRowsPerPage.
-			
-			var rowsPerPage = this.rowsPerPage,
-				pageSizeOptions = this.pageSizeOptions,
-				paginationSizeSelect = this.paginationSizeSelect;
-			
-			if(paginationSizeSelect){
-				if(arrayUtil.indexOf(pageSizeOptions, rowsPerPage) < 0){
-					this._setPageSizeOptions(pageSizeOptions.concat([rowsPerPage])); 
-				}else{
-					paginationSizeSelect.value = "" + rowsPerPage;
-				}
-			}
-		},
-		
-		_setRowsPerPage: function(rowsPerPage){
-			this.rowsPerPage = rowsPerPage;
-			this._updateRowsPerPageOption();
-			this.gotoPage(1);
-		},
-
-		_updateNavigation: function(focusLink){
-			// summary:
-			//		Update status and navigation controls based on total count from query
-			
-			var grid = this,
-				i18n = this.i18nPagination,
-				linksNode = this.paginationLinksNode,
-				currentPage = this._currentPage,
-				pagingLinks = this.pagingLinks,
-				paginationNavigationNode = this.paginationNavigationNode,
-				end = Math.ceil(this._total / this.rowsPerPage),
-				pagingTextBoxHandle = this._pagingTextBoxHandle;
-			
-			function pageLink(page, addSpace){
-				var link;
-				if(grid.pagingTextBox && page == currentPage && end > 1){
-					// use a paging text box if enabled instead of just a number
-					link = put(linksNode, 'input.dgrid-page-input[type=text][value=$]', currentPage);
-					link.setAttribute("aria-label", i18n.jumpPage);
-					grid._pagingTextBoxHandle = on(link, "change", function(){
-						var value = +this.value;
-						if(!isNaN(value) && value > 0 && value <= end){
-							grid.gotoPage(+this.value, true);
-						}
-					});
-				}else{
-					// normal link
-					link = put(linksNode,
-						'span' + (page == currentPage ? '.dgrid-page-disabled' : '') + '.dgrid-page-link',
-						page + (addSpace ? " " : ""));
-					link.setAttribute("aria-label", i18n.gotoPage);
-					link.tabIndex = 0;
-				}
-				if(page == currentPage && focusLink){
-					// focus on it if we are supposed to retain the focus
-					link.focus();
-				}
-			}
-			
-			if(pagingTextBoxHandle){ pagingTextBoxHandle.remove(); }
-			linksNode.innerHTML = "";
-			query(".dgrid-first, .dgrid-previous", paginationNavigationNode).forEach(function(link){
-				put(link, (currentPage == 1 ? "." : "!") + "dgrid-page-disabled");
-			});
-			query(".dgrid-last, .dgrid-next", paginationNavigationNode).forEach(function(link){
-				put(link, (currentPage >= end ? "." : "!") + "dgrid-page-disabled");
-			});
-			
-			if(pagingLinks && end > 0){
-				// always include the first page (back to the beginning)
-				pageLink(1, true);
-				var start = currentPage - pagingLinks;
-				if(start > 2) {
-					// visual indication of skipped page links
-					put(linksNode, "span.dgrid-page-skip", "...");
-				}else{
-					start = 2;
-				}
-				// now iterate through all the page links we should show
-				for(var i = start; i < Math.min(currentPage + pagingLinks + 1, end); i++){
-					pageLink(i, true);
-				}
-				if(currentPage + pagingLinks + 1 < end){
-					put(linksNode, "span.dgrid-page-skip", "...");
-				}
-				// last link
-				if(end > 1){
-					pageLink(end);
-				}
-			}else if(grid.pagingTextBox){
-				// The pageLink function is also used to create the paging textbox.
-				pageLink(currentPage);
-			}
-		},
-		
-		refresh: function(){
-			var self = this;
-			
-			this.inherited(arguments);
-			
-			if(!this.store){
-				console.warn("Pagination requires a store to operate.");
-				return;
-			}
-			
-			// Reset to first page and return promise from gotoPage
-			return this.gotoPage(1).then(function(results){
-				// Emit on a separate turn to enable event to be used consistently for
-				// initial render, regardless of whether the backing store is async
-				setTimeout(function() {
-					on.emit(self.domNode, "dgrid-refresh-complete", {
-						bubbles: true,
-						cancelable: false,
-						grid: self,
-						results: results // QueryResults object (may be a wrapped promise)
-					});
-				}, 0);
-				
-				return results;
-			});
-		},
-		
-		_onNotification: function(rows){
-			if(rows.length !== this._rowsOnPage){
-				// Refresh the current page to maintain correct number of rows on page
-				this.gotoPage(this._currentPage);
-			}
-		},
-		
-		renderArray: function(results, beforeNode){
-			var grid = this,
-				rows = this.inherited(arguments);
-			
-			// Make sure _lastCollection is cleared (due to logic in List)
-			this._lastCollection = null;
-			
-			if(!beforeNode){
-				if(this._topLevelRequest){
-					// Cancel previous async request that didn't finish
-					this._topLevelRequest.cancel();
-					delete this._topLevelRequest;
-				}
-				
-				if (typeof results.cancel === "function") {
-					// Store reference to new async request in progress
-					this._topLevelRequest = results;
-				}
-				
-				Deferred.when(results, function(){
-					if(grid._topLevelRequest){
-						// Remove reference to request now that it's finished
-						delete grid._topLevelRequest;
-					}
-				});
-			}
-			
-			return rows;
-		},
-		
-		insertRow: function(){
-			var oldNodes = this._oldPageNodes,
-				row = this.inherited(arguments);
-			
-			if(oldNodes && row === oldNodes[row.id]){
-				// If the previous row was reused, avoid removing it in cleanup
-				delete oldNodes[row.id];
-			}
-			
-			return row;
-		},
-		
-		gotoPage: function(page, focusLink){
-			// summary:
-			//		Loads the given page.  Note that page numbers start at 1.
-			var grid = this,
-				dfd = new Deferred();
-			
-			var result = this._trackError(function(){
-				var count = grid.rowsPerPage,
-					start = (page - 1) * count,
-					options = lang.mixin(grid.get("queryOptions"), {
-						start: start,
-						count: count
-						// current sort is also included by get("queryOptions")
-					}),
-					results,
-					contentNode = grid.contentNode,
-					loadingNode,
-					oldNodes,
-					children,
-					i,
-					len;
-				
-				if(grid.showLoadingMessage){
-					cleanupContent(grid);
-					loadingNode = grid.loadingNode = put(contentNode, "div.dgrid-loading");
-					loadingNode.innerHTML = grid.loadingMessage;
-				}else{
-					// Reference nodes to be cleared later, rather than now;
-					// iterate manually since IE < 9 doesn't like slicing HTMLCollections
-					grid._oldPageNodes = oldNodes = {};
-					children = contentNode.children;
-					for(i = 0, len = children.length; i < len; i++){
-						oldNodes[children[i].id] = children[i];
-					}
-					// Also reference the current page's observer (if any)
-					grid._oldPageObserver = grid.observers.pop();
-				}
-				
-				// set flag to deactivate pagination event handlers until loaded
-				grid._isLoading = true;
-				
-				// Run new query and pass it into renderArray
-				results = grid.store.query(grid.query, options);
-				
-				Deferred.when(grid.renderArray(results, null, options), function(rows){
-					cleanupLoading(grid);
-					// Reset scroll Y-position now that new page is loaded.
-					grid.scrollTo({ y: 0 });
-					
-					Deferred.when(results.total, function(total){
-						if(!total){
-							if(grid.noDataNode){
-								put(grid.noDataNode, "!");
-								delete grid.noDataNode;
-							}
-							// If there are no results, display the no data message.
-							grid.noDataNode = put(grid.contentNode, "div.dgrid-no-data");
-							grid.noDataNode.innerHTML = grid.noDataMessage;
-						}
-						
-						// Update status text based on now-current page and total.
-						grid.paginationStatusNode.innerHTML = string.substitute(grid.i18nPagination.status, {
-							start: Math.min(start + 1, total),
-							end: Math.min(total, start + count),
-							total: total
-						});
-						grid._total = total;
-						grid._currentPage = page;
-						grid._rowsOnPage = rows.length;
-						
-						// It's especially important that _updateNavigation is called only
-						// after renderArray is resolved as well (to prevent jumping).
-						grid._updateNavigation(focusLink);
-					});
-					
-					if (has("ie") < 7 || (has("ie") && has("quirks"))) {
-						// call resize in old IE in case grid is set to height: auto
-						grid.resize();
-					}
-					
-					dfd.resolve(results);
-				}, function(error){
-					cleanupLoading(grid);
-					dfd.reject(error);
-				});
-				
-				return dfd.promise;
-			});
-			
-			if (!result) {
-				// A synchronous error occurred; reject the promise.
-				dfd.reject();
-			}
-
-			var self = this;
-			dfd.promise.then(function (results) {
-				// Emit on a separate turn to enable event to be used consistently for
-				// initial render, regardless of whether the backing store is async
-				setTimeout(function () {
-					on.emit(self.domNode, "dgrid-page-complete", {
-						bubbles: true,
-						cancelable: false,
-						grid: self,
-						page: page,
-						results: results // QueryResults object (may be a wrapped promise)
-					});
-				}, 0);
-
-				return results;
-			});
-			return dfd.promise;
-		}
-	});
-});

+ 0 - 93
esp/files/dgrid/extensions/_DnD-touch-autoscroll.js

@@ -1,93 +0,0 @@
-define([
-	"dojo/aspect",
-	"dojo/dom-geometry",
-	"dojo/dnd/autoscroll",
-	"../List"
-], function(aspect, domGeometry, autoscroll, List){
-	// summary:
-	//		This module patches the autoScrollNodes function from the
-	//		dojo/dnd/autoscroll module, in order to behave properly for
-	//		dgrid TouchScroll components.
-	
-	var original = autoscroll.autoScrollNodes,
-		instances, findEnclosing;
-	
-	// In order to properly detect autoscroll cases for dgrid+TouchScroll
-	// instances, we need to register instances so that we can look them up based
-	// on child nodes later.
-	
-	instances = {};
-	aspect.after(List.prototype, "postCreate", function(r){
-		var id = this.id;
-		// Since this code is only hooked in some cases, don't throw an error here,
-		// but do warn since duplicate IDs or improper destruction are likely going
-		// to lead to unintended consequences.
-		if(instances[id]){
-			console.warn("dgrid instance registered with duplicate id '" + id + "'");
-		}
-		instances[id] = this;
-		return r;
-	});
-	aspect.after(List.prototype, "destroy", function(r){
-		delete instances[this.id];
-		return r;
-	});
-	findEnclosing = function(node){
-		var id, instance;
-		while(node){
-			if((id = node.id) && (instance = instances[id])){ return instance; }
-			node = node.parentNode;
-		}
-	};
-	
-	autoscroll.autoScrollNodes = function(evt){
-		var node = evt.target,
-			list = findEnclosing(node),
-			pos, nodeX, nodeY, thresholdX, thresholdY, dx, dy, oldScroll, newScroll;
-		
-		if(list){
-			// We're inside a dgrid component with TouchScroll; handle using the
-			// getScrollPosition and scrollTo APIs instead of scrollTop/Left.
-			// All logic here is designed to be functionally equivalent to the
-			// existing logic in the original dojo/dnd/autoscroll function.
-			
-			node = list.touchNode.parentNode;
-			pos = domGeometry.position(node, true);
-			nodeX = evt.pageX - pos.x;
-			nodeY = evt.pageY - pos.y;
-			// Use standard threshold, unless element is too small to warrant it.
-			thresholdX = Math.min(autoscroll.H_TRIGGER_AUTOSCROLL, pos.w / 2);
-			thresholdY = Math.min(autoscroll.V_TRIGGER_AUTOSCROLL, pos.h / 2);
-			
-			// Check whether event occurred beyond threshold in any given direction.
-			// If so, we will scroll by an amount equal to the calculated threshold.
-			if(nodeX < thresholdX){
-				dx = -thresholdX;
-			}else if(nodeX > pos.w - thresholdX){
-				dx = thresholdX;
-			}
-			
-			if(nodeY < thresholdY){
-				dy = -thresholdY;
-			}else if(nodeY > pos.h - thresholdY){
-				dy = thresholdY;
-			}
-			
-			// Perform any warranted scrolling.
-			if(dx || dy){
-				oldScroll = list.getScrollPosition();
-				newScroll = {};
-				if(dx){ newScroll.x = oldScroll.x + dx; }
-				if(dy){ newScroll.y = oldScroll.y + dy; }
-				
-				list.scrollTo(newScroll);
-				return;
-			}
-		}
-		// If we're not inside a dgrid component with TouchScroll, fall back to
-		// the original logic to handle scroll on other elements and the document.
-		original.call(this, evt);
-	};
-	
-	return autoscroll;
-});

+ 0 - 6
esp/files/dgrid/extensions/nls/columnHider.js

@@ -1,6 +0,0 @@
-define({
-	root: {
-		popupLabel: 'Show or hide columns'
-	},
-	es: true
-});

+ 0 - 9
esp/files/dgrid/extensions/nls/de/pagination.js

@@ -1,9 +0,0 @@
-define({
-	status: "${start} - ${end} von ${total} Ergebnissen",
-	gotoFirst: "Gehe zu erster Seite",
-	gotoNext: "Gehe zu nächster Seite",
-	gotoPrev: "Gehe zu vorheriger Seite",
-	gotoLast: "Gehe zu letzter Seite",
-	gotoPage: "Gehe zu Seite",
-	jumpPage: "Springe zu Seite"
-});

+ 0 - 3
esp/files/dgrid/extensions/nls/es/columnHider.js

@@ -1,3 +0,0 @@
-define({
-	popupLabel: "Mostrar o esconder columnas"
-});

+ 0 - 3
esp/files/dgrid/extensions/nls/es/pagination.js

@@ -1,3 +0,0 @@
-define({
-	status: "${start} - ${end} de ${total} resultados"
-});

+ 0 - 9
esp/files/dgrid/extensions/nls/fr/pagination.js

@@ -1,9 +0,0 @@
-define({
-		status: "${start} - ${end} de ${total} résultats",
-		gotoFirst: "Aller à la première page",
-		gotoNext: "Aller à la page suivante",
-		gotoPrev: "Aller à la page précédente",
-		gotoLast: "Aller à la dernière page",
-		gotoPage: "Aller à la page",
-		jumpPage: "Aller à la page"
-});

+ 0 - 3
esp/files/dgrid/extensions/nls/ja/pagination.js

@@ -1,3 +0,0 @@
-define({
-	status: "検索結果${total}件中${start}件から${end}件までを表示。"
-});

+ 0 - 20
esp/files/dgrid/extensions/nls/pagination.js

@@ -1,20 +0,0 @@
-define({
-	root: {
-		status: "${start} - ${end} of ${total} results",
-		gotoFirst: "Go to first page",
-		gotoNext: "Go to next page",
-		gotoPrev: "Go to previous page",
-		gotoLast: "Go to last page",
-		gotoPage: "Go to page",
-		jumpPage: "Jump to page"
-	},
-	de: true,
-	es: true,
-	fr: true,
-	pt: true,
-	ja: true,
-	sk: true,
-	th: true,
-	"zh-cn": true,
-	"zh-hk": true
-});

+ 0 - 9
esp/files/dgrid/extensions/nls/pt/pagination.js

@@ -1,9 +0,0 @@
-define({
-	status: "${start} - ${end} de ${total} resultados",
-	gotoFirst: "Primeira página",
-	gotoNext: "Próxima página",
-	gotoPrev: "Página anterior",
-	gotoLast: "Última página",
-	gotoPage: "Ir para página",
-	jumpPage: "Pular para página"
-});

+ 0 - 9
esp/files/dgrid/extensions/nls/sk/pagination.js

@@ -1,9 +0,0 @@
-define({
-		status: "${start} - ${end} z ${total} výsledkov",
-		gotoFirst: "Prvá stránka",
-		gotoNext: "Nasledovná stránka",
-		gotoPrev: "Predchádzajúca stránka",
-		gotoLast: "Posledná stránka",
-		gotoPage: "Na stránku",
-		jumpPage: "Na stránku"
-});

+ 0 - 9
esp/files/dgrid/extensions/nls/th/pagination.js

@@ -1,9 +0,0 @@
-define({
-	status: "${start} - ${end} ของ ${total} ผลลัพธ์",
-	gotoFirst: "ไปหน้าแรก",
-	gotoNext: "ไปหน้าถัดไป",
-	gotoPrev: "ไปหน้าก่อน",
-	gotoLast: "ไปหน้าสุดท้าย",
-	gotoPage: "ไปหน้า",
-	jumpPage: "กระโดดไปหน้า"
-});

+ 0 - 9
esp/files/dgrid/extensions/nls/zh-cn/pagination.js

@@ -1,9 +0,0 @@
-define({
-  	status: "${start} - ${end} 共 ${total} 条结果",
-		gotoFirst: "首页",
-		gotoNext: "后一页",
-		gotoPrev: "前一页",
-		gotoLast: "末页",
-		gotoPage: "到这页",
-		jumpPage: "跳到页"
-});

+ 0 - 9
esp/files/dgrid/extensions/nls/zh-hk/pagination.js

@@ -1,9 +0,0 @@
-define({
-    status: "${start} - ${end} 共 ${total} 條結果",
-		gotoFirst: "首頁",
-		gotoNext: "上一頁",
-		gotoPrev: "下一頁",
-		gotoLast: "末頁",
-		gotoPage: "到這頁",
-		jumpPage: "跳到頁"
-});

+ 0 - 23
esp/files/dgrid/package.js

@@ -1,23 +0,0 @@
-var miniExcludes = {
-		"dgrid/CHANGES.md": 1,
-		"dgrid/LICENSE": 1,
-		"dgrid/README.md": 1,
-		"dgrid/package": 1
-	},
-	isTestRe = /\/test\//;
-
-var profile = {
-	resourceTags: {
-		test: function(filename, mid){
-			return isTestRe.test(filename);
-		},
-
-		miniExclude: function(filename, mid){
-			return /\/(?:test|demos)\//.test(filename) || mid in miniExcludes;
-		},
-
-		amd: function(filename, mid){
-			return /\.js$/.test(filename);
-		}
-	}
-};

+ 0 - 31
esp/files/dgrid/package.json

@@ -1,31 +0,0 @@
-{
-  "name": "dgrid",
-  "author": "Kris Zyp",
-  "version": "0.3.12",
-  "description": "A lightweight, mobile-ready, data-driven, modular widget designed for lists and grids",
-  "licenses": [
-     {
-         "type": "AFLv2.1",
-         "url": "http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L43"
-     },
-     {
-         "type": "BSD",
-         "url": "http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L13"
-     }
-  ],
-  "repository": {
-    "type":"git",
-    "url":"http://github.com/SitePen/dgrid"
-  },
-  "dependencies": {
-    "dojo": "1.7.2",
-    "put-selector": "0.3.5",
-    "xstyle": "0.1.3"
-  },
-  "directories": {
-    "lib": "."
-  },
-  "main": "./OnDemandGrid",
-  "icon": "http://packages.dojofoundation.org/images/dgrid.png",
-  "dojoBuild": "package.js"
-}

+ 0 - 197
esp/files/dgrid/selector.js

@@ -1,197 +0,0 @@
-define(["dojo/_base/kernel", "dojo/_base/array", "dojo/on", "dojo/aspect", "dojo/_base/sniff", "put-selector/put"],
-function(kernel, arrayUtil, on, aspect, has, put){
-	return function(column, type){
-		
-		var listeners = [],
-			grid, headerCheckbox;
-		
-		if(!column){ column = {}; }
-		
-		if(column.type){
-			column.selectorType = column.type;
-			kernel.deprecated("columndef.type", "use columndef.selectorType instead", "dgrid 0.4");
-		}
-		// accept type as argument to Selector function, or from column def
-		column.selectorType = type = type || column.selectorType || "checkbox";
-		column.sortable = false;
-
-		function disabled(item) {
-			return !grid.allowSelect(grid.row(item));
-		}
-		
-		function changeInput(value){
-			// creates a function that modifies the input on an event
-			return function(event){
-				var rows = event.rows,
-					len = rows.length,
-					state = "false",
-					selection, mixed, i;
-				
-				for(i = 0; i < len; i++){
-					var element = grid.cell(rows[i], column.id).element;
-					if(!element){ continue; } // skip if row has been entirely removed
-					element = (element.contents || element).input;
-					if(element && !element.disabled){
-						// only change the value if it is not disabled
-						element.checked = value;
-						element.setAttribute("aria-checked", value);
-					}
-				}
-				if(headerCheckbox.type == "checkbox"){
-					selection = grid.selection;
-					mixed = false;
-					// see if the header checkbox needs to be indeterminate
-					for(i in selection){
-						// if there is anything in the selection, than it is indeterminate
-						if(selection[i] != grid.allSelected){
-							mixed = true;
-							break;
-						}
-					}
-					headerCheckbox.indeterminate = mixed;
-					headerCheckbox.checked = grid.allSelected;
-					if (mixed) {
-						state = "mixed";
-					} else if (grid.allSelected) {
-						state = "true";
-					}
-					headerCheckbox.setAttribute("aria-checked", state);
-				}
-			};
-		}
-		
-		function onSelect(event){
-			// we would really only care about click, since other input sources, like spacebar
-			// trigger a click, but the click event doesn't provide access to the shift key in firefox, so
-			// listen for keydown's as well to get an event in firefox that we can properly retrieve
-			// the shiftKey property from
-			if(event.type == "click" || event.keyCode == 32 || (!has("opera") && event.keyCode == 13) || event.keyCode === 0){
-				var row = grid.row(event),
-					lastRow = grid._lastSelected && grid.row(grid._lastSelected);
-
-				grid._selectionTriggerEvent = event;
-				
-				if(type == "radio"){
-					if(!lastRow || lastRow.id != row.id){
-						grid.clearSelection();
-						grid.select(row, null, true);
-						grid._lastSelected = row.element;
-					}
-				}else{
-					if(row){
-						if(event.shiftKey){
-							// make sure the last input always ends up checked for shift key 
-							changeInput(true)({rows: [row]});
-						}else{
-							// no shift key, so no range selection
-							lastRow = null;
-						}
-						lastRow = event.shiftKey ? lastRow : null;
-						grid.select(lastRow || row, row, lastRow ? undefined : null);
-						grid._lastSelected = row.element;
-					}else{
-						// No row resolved; must be the select-all checkbox.
-						put(this, (grid.allSelected ? "!" : ".") + "dgrid-select-all");
-						grid[grid.allSelected ? "clearSelection" : "selectAll"]();
-					}
-				}
-				grid._selectionTriggerEvent = null;
-			}
-		}
-		
-		function setupSelectionEvents(){
-			// register one listener at the top level that receives events delegated
-			grid._hasSelectorInputListener = true;
-			listeners.push(grid.on(".dgrid-selector:click,.dgrid-selector:keydown", onSelect));
-			var handleSelect = grid._handleSelect;
-			grid._handleSelect = function(event){
-				// ignore the default select handler for events that originate from the selector column
-				if(this.cell(event).column != column){
-					handleSelect.apply(this, arguments);
-				}
-			};
-			
-			// Set up disabled and grid.allowSelect to match each other's behaviors
-			if(typeof column.disabled == "function"){
-				var originalAllowSelect = grid.allowSelect,
-					originalDisabled = column.disabled;
-
-				// Wrap allowSelect to consult both the original allowSelect and disabled
-				grid.allowSelect = function(row){
-					var allow = originalAllowSelect.call(this, row);
-
-					if (originalDisabled === disabled) {
-						return allow;
-					} else {
-						return allow && !originalDisabled.call(column, row.data);
-					}
-				};
-
-				// Then wrap disabled to simply call the new allowSelect
-				column.disabled = disabled;
-			}else{
-				// If no disabled function was specified, institute a default one
-				// which honors allowSelect
-				column.disabled = disabled;
-			}
-			// register listeners to the select and deselect events to change the input checked value
-			listeners.push(grid.on("dgrid-select", changeInput(true)));
-			listeners.push(grid.on("dgrid-deselect", changeInput(false)));
-		}
-		
-		var renderInput = typeof type == "function" ? type : function(value, cell, object){
-			var parent = cell.parentNode,
-				disabled;
-			
-			if(!grid._hasSelectorInputListener){
-				setupSelectionEvents();
-			}
-			
-			// column.disabled gets initialized or wrapped in setupSelectionEvents
-			disabled = column.disabled;
-
-			// must set the class name on the outer cell in IE for keystrokes to be intercepted
-			put(parent && parent.contents ? parent : cell, ".dgrid-selector");
-			var input = cell.input || (cell.input = put(cell, "input[type="+type + "]", {
-				tabIndex: isNaN(column.tabIndex) ? -1 : column.tabIndex,
-				disabled: disabled && (typeof disabled == "function" ?
-					disabled.call(column, object) : disabled),
-				checked: value
-			}));
-			input.setAttribute("aria-checked", !!value);
-			
-			return input;
-		};
-		
-		aspect.after(column, "init", function(){
-			grid = column.grid;
-		});
-		
-		aspect.after(column, "destroy", function(){
-			arrayUtil.forEach(listeners, function(l){ l.remove(); });
-			grid._hasSelectorInputListener = false;
-		});
-		
-		column.renderCell = function(object, value, cell, options, header){
-			var row = object && grid.row(object);
-			value = row && grid.selection[row.id];
-			renderInput(value, cell, object);
-		};
-		column.renderHeaderCell = function(th){
-			var label = "label" in column ? column.label :
-				column.field || "";
-			
-			if(type == "radio" || !grid.allowSelectAll){
-				th.appendChild(document.createTextNode(label));
-				if(!grid._hasSelectorInputListener){
-					setupSelectionEvents();
-				}
-			}else{
-				renderInput(false, th, {});
-			}
-			headerCheckbox = th.lastChild;
-		};
-		
-		return column;
-	};
-});

+ 0 - 186
esp/files/dgrid/test/GridFromHtml.html

@@ -1,186 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>GridFromHtml Tests</title>
-		<meta name="viewport" content="width=570">
-		<style>
-			@import "../../dojo/resources/dojo.css";
-			@import "../css/skins/claro.css";
-			body {
-				padding: 0 80px; /* side padding to make it easier to scroll doc */
-			}
-			
-			/* tests for renderCell / renderHeaderCell */
-			.renderedCell {
-				font-style: italic;
-			}
-			.renderedHeaderCell {
-				text-decoration: underline;
-			}
-		</style>
-		<script src="../../dojo/dojo.js" 
-			data-dojo-config="async: true"></script>
-		<script>
-			var store; // defined later, Memory store containing data
-			
-			function getOrdinal(num){
-				// returns a String consisting of num + the appropriate ordinal suffix
-				var ord = 'th';
-				switch (num % 10) {
-					case 1:
-						ord = 'st';
-						break;
-					case 2:
-						ord = 'nd';
-						break;
-					case 3:
-						ord = 'rd';
-						break;
-				}
-				return num + ord;
-			}
-
-			function testFormatter(item){
-				return "<h3>Step " + item.order + ": " + item.name + "</h3><p>" +
-					item.description + "</p>";
-			}
-
-			function testGet(item){
-				return getOrdinal(item.order);
-			}
-
-			function testRenderHeaderCell(th){
-				var div = document.createElement("div");
-				div.className = "renderedHeaderCell";
-				div.innerHTML = "Step";
-				return div;
-			}
-
-			function testRenderCell(object, data, td, options){
-				var div = document.createElement("div");
-				div.className = "renderedCell";
-				div.innerHTML = getOrdinal(object.order);
-				return div;
-			}
-
-	
-
-			require(["dgrid/GridFromHtml", "dgrid/OnDemandList",
-				"dojo/store/Memory", "dojo/store/Observable",
-				"dojo/_base/declare", "dojo/parser",
-				"dgrid/test/data/base", "dojo/domReady!"],
-			function(GridFromHtml, OnDemandList, Memory, Observable, declare, parser){
-				
-				window.gridFromHtmlLegacyFormatter = new GridFromHtml({},
-					"gridFromHtmlLegacyFormatter");
-				gridFromHtmlLegacyFormatter.renderArray(testOrderedData);
-				
-				window.gridFromHtmlLegacyGet = new GridFromHtml({},
-					"gridFromHtmlLegacyGet");
-				gridFromHtmlLegacyGet.renderArray(testOrderedData);
-				
-				window.gridFromHtmlNew = new GridFromHtml({},
-					"gridFromHtmlNew");
-				gridFromHtmlNew.renderArray(testOrderedData);
-				
-				window.gridFromHtmlTestProps = new GridFromHtml({},
-					"gridFromHtmlTestProps");
-				gridFromHtmlTestProps.renderArray(testOrderedData);
-				
-				// Need to expose GridFromHtml as a global for parser to find.
-				// Mix in OnDemandList and create a store, since otherwise there's not
-				// much of a way to add data.
-				window.dgrid = { GridFromHtml: declare([GridFromHtml, OnDemandList]) };
-				store = Observable(new Memory({data: testOrderedData}));
-				parser.parse();
-			});
-			
-		</script>
-	</head>
-	<body class="claro">
-
-		<p>Compare the outcome of the first group of tests with the first group in
-			<a href="test_legacy.html">test_legacy.html</a>.</p>
-		<!-- GridFromHtml should look for TRs with THs anywhere.
-			Testing here with one thead, one tbody, and one implicit. -->
-		<h2>1a: GridFromHtml with single column with formatter for _item field</h2>
-		<table id="gridFromHtmlLegacyFormatter">
-			<thead>
-				<tr>
-					<th data-dgrid-column="{field:'_item', sortable:false, formatter:testFormatter}">Step</th>
-				</tr>
-			</thead>
-		</table>
-		<h2>1b: GridFromHtml with single column with get for order field, and blank label for 3rd column</h2>
-		<table id="gridFromHtmlLegacyGet">
-			<tbody>
-				<tr>
-					<th data-dgrid-column="{field:'order', get:testGet}">Step</th>
-					<th>name</th>
-					<th data-dgrid-column="{label:'', field:'description', sortable:false}">what to do</th>
-				</tr>
-			</tbody>
-		</table>
-		<h2>1c: GridFromHtml with single column with renderCell function</h2>
-		<p>(should look same as previous but with underlined first header cell
-			and italicized first column values)</p>
-		<table id="gridFromHtmlNew">
-			<tr>
-				<th data-dgrid-column="{field:'order',
-					renderCell:testRenderCell, renderHeaderCell:testRenderHeaderCell}">Step</th>
-				<th>name</th>
-				<th data-dgrid-column="{field:'description', sortable:false}">what to do</th>
-			</tr>
-		</table>
-		
-		<hr>
-		
-		<h2>2a: same as 1a, parsed from declarative markup (using a store)</h2>
-		<table id="gridDeclarativeLegacyFormatter" data-dojo-id="gridDeclarativeLegacyFormatter"
-			data-dojo-type="dgrid.GridFromHtml" data-dojo-props="store: store">
-			<thead>
-				<tr>
-					<th data-dgrid-column="{field:'_item', sortable:false, formatter:testFormatter}">Step</th>
-				</tr>
-			</thead>
-		</table>
-		<h2>2b: same as 1b, parsed from declarative markup (using a store)</h2>
-		<table id="gridDeclarativeLegacyGet" data-dojo-id="gridDeclarativeLegacyGet"
-			data-dojo-type="dgrid.GridFromHtml" data-dojo-props="store: store">
-			<tbody>
-				<tr>
-					<th data-dgrid-column="{field:'order', get:testGet}">Step</th>
-					<th>name</th>
-					<th data-dgrid-column="{field:'description', sortable:false}">what to do</th>
-				</tr>
-			</tbody>
-		</table>
-		<h2>2c: same as 1c, parsed from declarative markup (using a store)</h2>
-		<table id="gridDeclarativeNew" data-dojo-id="gridDeclarativeNew"
-			data-dojo-type="dgrid.GridFromHtml" data-dojo-props="store: store">
-			<tr>
-				<th data-dgrid-column="{field:'order',
-					renderCell:testRenderCell, renderHeaderCell:testRenderHeaderCell}">Step</th>
-				<th>name</th>
-				<th data-dgrid-column="{field:'description', sortable:false}">what to do</th>
-			</tr>
-		</table>
-		
-		<hr>
-		
-		<h2>3a: Testing boolean property (un)specification in GridFromHtml</h2>
-		<table id="gridFromHtmlTestProps">
-			<thead>
-				<tr>
-					<th rowspan="2" data-dgrid-column="{field:'name'}">No sortable attr (defaults to true)</th>
-					<th data-dgrid-column="{field:'name', sortable:false}">sortable="false"</th>
-				</tr>
-				<tr>
-					<th data-dgrid-column="{field:'name', sortable:true}">sortable="true"</th>
-				</tr>
-			</thead>
-		</table>
-		
-	</body>
-</html>

+ 0 - 87
esp/files/dgrid/test/GridFromHtml_Editors.html

@@ -1,87 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>Test declarative cell editors </title>
-		<meta name="viewport" content="width=570">
-		<style>
-			@import "../../dojo/resources/dojo.css";
-			@import "../../dijit/themes/claro/claro.css";
-			@import "../css/skins/claro.css";
-			body {
-				padding: 0 80px; /* side padding to make it easier to scroll doc */
-			}
-			
-			/* tests for renderCell / renderHeaderCell */
-			.renderedCell {
-				font-style: italic;
-			}
-			.renderedHeaderCell {
-				text-decoration: underline;
-			}
-		</style>
-		<script src="../../dojo/dojo.js" 
-			data-dojo-config="async: true"></script>
-		<script>
-			require(["dgrid/GridFromHtml", "dgrid/OnDemandList", "dgrid/Keyboard",
-				"dojo/store/Memory", "dojo/store/Observable",
-				"dojo/_base/declare", "dojo/parser", "dojo/query",
-				"dijit/form/Select", "dgrid/editor", "dijit/form/DateTextBox",
-				"dijit/form/HorizontalSlider", "dijit/form/NumberSpinner",
-				"dojo/data/ObjectStore", "dgrid/test/data/base", "dojo/domReady!"],
-			function(GridFromHtml, OnDemandList, Keyboard, Memory, Observable, declare, parser, query, Select, editor, DateTextBox, Slider, NumberSpinner, ObjectStore){
-
-				window.dgrid = {
-					GridFromHtml: declare([GridFromHtml, OnDemandList]),
-					editor: editor
-				};
-				window.stateStore = new ObjectStore({
-						objectStore:testStateStore,
-						labelProperty: "name"
-					});
-				// GridFromHtml tests
-				window.gridProgrammatic = new dgrid.GridFromHtml({
-					store: testTypesStore
-				}, "gridProgrammatic");
-				parser.parse();
-			});
-			
-		</script>
-	</head>
-	<body class="claro">
-
-		
-		<!-- GridFromHtml should look for TRs with THs anywhere.
-			Testing here with one thead, one tbody, and one implicit. -->
-
-		<h2>1: GridFromHtml instantiated programmatically,
-			with columns using editor plugin</h2>
-		<table id="gridProgrammatic">
-			<thead>
-				<tr>
-					<th data-dgrid-column="dgrid.editor({field:'date'}, dijit.form.DateTextBox)">Date</th>
-					<th data-dgrid-column="dgrid.editor({field: 'text'}, 'text', 'dblclick')">Text editable on dblclick</th>
-					<th data-dgrid-column="dgrid.editor({
-							field: 'state',
-							editorArgs: {store: stateStore, style: 'width:120px;', maxHeight: -1}
-						}, dijit.form.Select)">State</th>
-					<th data-dgrid-column="{field:'text2', sortable:false}">Uneditable</th>
-				</tr>
-			</thead>
-		</table>
-	<h2>2: Fully declarative GridFromHtml,
-		with columns using editor plugin</h2>
-	<table id="gridDeclarative" data-dojo-id="gridDeclarative"
-			data-dojo-type="dgrid.GridFromHtml" data-dojo-props="store: testTypesStore">
-			<tr>
-				<th data-dgrid-column="dgrid.editor({field:'date'}, dijit.form.DateTextBox)">Date</th>
-				<th data-dgrid-column="dgrid.editor({field: 'text'}, 'text', 'dblclick')">Text editable on dblclick</th>
-				<th data-dgrid-column="dgrid.editor({
-						field: 'state',
-						editorArgs: {store: stateStore, style: 'width:120px;', maxHeight: -1}
-					}, dijit.form.Select)">State</th>
-				<th data-dgrid-column="{field:'text2', sortable:false}">Uneditable</th>
-			</tr>
-		</table>
-	</body>
-</html>

+ 0 - 143
esp/files/dgrid/test/Grid_headerless.html

@@ -1,143 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>Test Grid Common Cases with showHeader: false</title>
-		<meta name="viewport" content="width=570">
-		<style>
-			@import "../../dojo/resources/dojo.css";
-			@import "../css/dgrid.css";
-			@import "../css/skins/claro.css";
-			@import "../../dijit/themes/claro/claro.css";
-			
-			h2 {
-				font-weight: bold;
-				padding-bottom: 0.25em;
-				clear: both;
-			}
-			
-			.dgrid {
-				width: 700px;
-			}
-			
-			#grid .field-col1 {
-				width: 100px;
-			}
-			#grid .field-col2 {
-				width: 30%;
-			}
-			#grid .field-col4 {
-				width: 180px;
-			}
-			
-			#scrollgrid .dgrid-cell {
-				width: 100px; /* force all columns to have SOME width */
-			}
-			#scrollgrid .field-col1 {
-				width: 500px;
-			}
-			#scrollgrid .field-col4 {
-				width: 300px;
-			}
-			
-			#tree {
-				height: 200px;
-			}
-			#tree .field-bool {
-				width: 20%;
-			}
-			#tree .field-type {
-				width: 80px;
-			}
-			
-			#editgrid {
-				width: 90%;
-			}
-			#editgrid .field-date, #editgrid .field-date2 {
-				width: 16em;
-			}
-			#editgrid .field-integer {
-				width: 6em;
-			}
-			#editgrid .field-bool {
-				width: 6em;
-			}
-		</style>
-		<script src="../../dojo/dojo.js" 
-			data-dojo-config="async: true"></script>
-		<script>
-			require(["dojo/on", "dgrid/List", "dgrid/OnDemandGrid", "dgrid/tree", "dgrid/editor", "dgrid/Selection", "dgrid/Keyboard", "dojo/_base/declare", "dijit/form/DateTextBox", "dijit/form/HorizontalSlider", "dijit/form/NumberSpinner", "dgrid/test/data/base", "dojo/domReady!"],
-				function(on, List, Grid, tree, editor, Selection, Keyboard, declare, DateTextBox, Slider, NumberSpinner, testStore){
-
-					var StandardGrid = declare([Grid, Selection, Keyboard]);
-
-					window.grid = new StandardGrid({
-						store: testStore,
-						columns: { // you can declare columns as an object hash (key translates to field)
-							col1: editor({label: 'Column 1 column 1 column 1'}, "text", "dblclick"),
-							col2: {label: 'Column 2', sortable: false},
-							col3: editor({label: 'Column 3'}, "text", "dblclick"),
-							col4: 'Column444444444444444444',
-							col5: editor({label: 'Column 5'}, "text", "dblclick")
-						},
-						showHeader: false
-					}, "grid");
-					
-					window.scrollgrid = new StandardGrid({
-						store: testStore,
-						columns: { // same as previous, repeated to keep objects/plugins unique
-							col1: editor({label: 'Column 1 column 1 column 1'}, "text", "dblclick"),
-							col2: {label: 'Column 2', sortable: false},
-							col3: editor({label: 'Column 3'}, "text", "dblclick"),
-							col4: 'Column444444444444444444',
-							col5: editor({label: 'Column 5'}, "text", "dblclick")
-						},
-						showHeader: false
-					}, "scrollgrid");
-					
-					window.tree = new StandardGrid({
-						store: testCountryStore,
-						selectionMode: "single",
-						columns: {
-							name: tree({label:'Name', sortable: false}),
-							bool: editor({label: 'A CheckBox', sortable: false}, "checkbox"),
-							type: {label: 'Type', sortable: false},
-							population: 'Population',
-							timezone: 'Timezone'
-						},
-						showHeader: false
-					}, "tree");
-					
-					window.editGrid = new StandardGrid({
-						store: testTypesStore,
-						columns: [ // columns specified as array, with field in each item
-							editor({label: 'A Date', field: 'date'}, DateTextBox),
-							editor({label: 'Real Number', field: 'floatNum'}, Slider),
-							editor({label: 'Integer', field: 'integer', editorArgs: {style: 'width: 5em;', constraints: {min:9,max:1550,places:0}}}, NumberSpinner),
-							editor({label: 'Text editable if checkbox checked + saved', field: 'text', canEdit: function(object){
-								return object.bool;
-							}}, "text", "dblclick"),
-							{label: 'Non editable text', field: 'text', sortable: false},
-							editor({label: 'Another Date', field: 'date2'}, DateTextBox, "focus"),
-							editor({label: 'CheckBox', field: 'bool'}, "checkbox")
-						],
-						selectionMode: "single",
-						showHeader: false
-					}, "editgrid");
-				});
-		</script>
-	</head>
-	<body class="claro">
-		<h1>Headerless Grid Tests</h1>
-		<h2>A basic grid</h2>
-		<div id="grid"></div>
-		<h2>A grid with a tree column</h2>
-		<div tabIndex="2" id="tree"></div>
-		<div tabIndex="1" id="list"></div>
-		<h2>Same as basic grid, but with column widths exceeding grid width</h2>
-		<p>(for testing that nodes occupy correct widths - pay attention to hover/selection style)</p>
-		<div id="scrollgrid"></div>
-		<h2>Editor Grid</h2>
-		<div id="editgrid"></div><br>
-	</body>
-</html>

+ 0 - 103
esp/files/dgrid/test/Grid_mouseevents.html

@@ -1,103 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>Test delegated mouse events</title>
-		<meta name="viewport" content="width=570">
-		<style>
-			@import "../../dojo/resources/dojo.css";
-			@import "../css/skins/claro.css";
-			.heading {
-				font-weight: bold;
-				padding-bottom: 0.25em;
-			}
-			.dgrid {
-				height: 20em;
-				margin: 10px;
-			}
-			
-			/* add styles to size this grid appropriately */
-			#grid .field-order {
-				width: 7%;
-			}
-			#grid .field-name {
-				width: 18%;
-			}
-		</style>
-		<script src="../../dojo/dojo.js" 
-			data-dojo-config="async: true"></script>
-		<script>
-			var columns = {
-				order: "step", // give column a custom name
-				name: {},
-				description: {label: "what to do", sortable: false}
-			};
-			require(["dgrid/Grid", "dgrid/OnDemandGrid", "dgrid/tree", "dgrid/util/mouse", "dojo/on",
-				"dgrid/test/data/base", "dojo/query", "dojo/domReady!"],
-			function(Grid, OnDemandGrid, tree, mouseUtil, on){
-				var data = [
-					{order: 1, name:"preheat", description:"Preheat your oven to 350F"},
-					{order: 2, name:"mix dry", description:"In a medium bowl, combine flour, salt, and baking soda"},
-					{order: 3, name:"mix butter", description:"In a large bowl, beat butter, then add the brown sugar and white sugar then mix"},
-					{order: 4, name:"mix together", description:"Slowly add the dry ingredients from the medium bowl to the wet ingredients in the large bowl, mixing until the dry ingredients are totally combined"},
-					{order: 5, name:"chocolate chips", description:"Add chocolate chips"},
-					{order: 6, name:"make balls", description:"Scoop up a golf ball size amount of dough with a spoon and drop in onto a cookie sheet"},
-					{order: 7, name:"bake", description:"Put the cookies in the oven and bake for about 10-14 minutes"},
-					{order: 8, name:"remove", description:"Using a spatula, lift cookies off onto wax paper or a cooling rack"},
-					{order: 9, name:"eat", description:"Eat and enjoy!"}
-				];
-				
-				var grid = window.grid = new Grid({
-					columns: columns
-				}, "grid");
-				grid.renderArray(data);
-				
-				function makeHandler(grid, type, dir){
-					return function(evt){
-						var obj = grid[type](evt),
-							str = obj.column ? obj.row.id + " " + obj.column.id : obj.id;
-						console.log(grid.id + " " + type + " " + dir + ": " + str);
-					};
-				}
-				function makeHeaderCellHandler(grid, dir){
-					return function(evt){
-						console.log(grid.id + " header cell " + dir + ": " +
-							grid.cell(evt).column.id);
-					};
-				}
-				
-				grid.on(mouseUtil.enterRow, makeHandler(grid, "row", "entered"));
-				grid.on(mouseUtil.leaveRow, makeHandler(grid, "row", "left"));
-				grid.on(mouseUtil.enterCell, makeHandler(grid, "cell", "entered"));
-				grid.on(mouseUtil.leaveCell, makeHandler(grid, "cell", "left"));
-				grid.on(mouseUtil.enterHeaderCell, makeHeaderCellHandler(grid, "entered"));
-				grid.on(mouseUtil.leaveHeaderCell, makeHeaderCellHandler(grid, "left"));
-				
-				var treegrid = window.treegrid = new OnDemandGrid({
-					store: testCountryStore,
-					columns: [
-						tree({label: "Name", field:"name", sortable: false}),
-						{label:"Type", field:"type", sortable: false},
-						{label:"Population", field:"population"},
-						{label:"Timezone", field:"timezone"}
-					]
-				}, "treegrid");
-				
-				treegrid.on(mouseUtil.enterRow, makeHandler(treegrid, "row", "entered"));
-				treegrid.on(mouseUtil.leaveRow, makeHandler(treegrid, "row", "left"));
-				treegrid.on(mouseUtil.enterCell, makeHandler(treegrid, "cell", "entered"));
-				treegrid.on(mouseUtil.leaveCell, makeHandler(treegrid, "cell", "left"));
-				// specifically only hooking up leaveHeaderCell, to ensure that leave events
-				// work independently (in earlier dev, this wasn't the case)
-				treegrid.on(mouseUtil.leaveHeaderCell, makeHeaderCellHandler(treegrid, "left"));
-			});
-				
-		</script>
-	</head>
-	<body class="claro">
-		<h2>A basic grid rendered from an array, with simulated mouseover events</h2>
-		<div id="grid"></div>
-		<h2>A grid with a tree column</h2>
-		<div id="treegrid"></div>
-	</body>
-</html>

+ 0 - 205
esp/files/dgrid/test/Grid_rendering.html

@@ -1,205 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>Test get, formatter, and renderCell</title>
-		<meta name="viewport" content="width=570">
-		<style>
-			@import "../../dojo/resources/dojo.css";
-			@import "../css/skins/claro.css";
-			body {
-				padding: 0 80px; /* side padding to make it easier to scroll doc */
-			}
-			
-			/* tests for renderCell / renderHeaderCell */
-			.renderedCell {
-				font-style: italic;
-			}
-			.renderedHeaderCell {
-				text-decoration: underline;
-			}
-		</style>
-		<script src="../../dojo/dojo.js" 
-			data-dojo-config="async: true"></script>
-		<script>
-			var store; // defined later, Memory store containing data
-			
-			function getOrdinal(num){
-				// returns a String consisting of num + the appropriate ordinal suffix
-				var ord = 'th';
-				switch (num % 10) {
-					case 1:
-						ord = 'st';
-						break;
-					case 2:
-						ord = 'nd';
-						break;
-					case 3:
-						ord = 'rd';
-						break;
-				}
-				return num + ord;
-			}
-			
-			function testFormatter(item){
-				return "<h3>Step " + item.order + ": " + item.name + "</h3><p>" +
-					item.description + "</p>";
-			}
-			
-			function testGet(item){
-				return getOrdinal(item.order);
-			}
-			
-			function testRenderHeaderCell(th){
-				var div = document.createElement("div");
-				div.className = "renderedHeaderCell";
-				div.innerHTML = "Step";
-				return div;
-			}
-			
-			function testRenderCell(object, data, td, options){
-				var div = document.createElement("div");
-				div.className = "renderedCell";
-				div.innerHTML = getOrdinal(object.order);
-				return div;
-			}
-			
-			var testFormatterScope = {
-				foo: function(item){
-					return "<h3>" + this.word + " " + item.order + ": " + item.name + "</h3><p>" +
-						item.description + "</p>";
-				},
-				word: "Step" // for testing proper execution context
-			};
-			
-			var columnsLegacyFormatter = [
-				{
-					label: "Step",
-					field: "_item",
-					formatter: testFormatter
-				}
-			];
-			
-			var columnsLegacyFormatterScope = [
-				{
-					label: "Step",
-					field: "_item",
-					formatter: "foo"
-				}
-			];
-			
-			var columnsLegacyGet = {
-				order: {
-					label: "Step",
-					get: testGet
-				},
-				name: {},
-				description: {label: "what to do", sortable: false}
-			};
-			var columnsNew = {
-				order: {
-					label: "Step",
-					renderHeaderCell: testRenderHeaderCell,
-					renderCell: testRenderCell
-				},
-				name: {},
-				description: {label: "", sortable: false} // Test blank label
-			};
-			require(["dgrid/Grid", "dgrid/OnDemandGrid", "dojo/store/Memory", "dojo/store/Observable", "dojo/_base/declare", "dojo/_base/lang", "dojo/parser", "dojo/query", "dgrid/test/data/base", "dojo/domReady!"],
-			function(Grid, OnDemandGrid, Memory, Observable, declare, lang, parser, query){
-				
-				// fully-programmatic tests
-				
-				window.gridLegacyFormatter = new Grid({
-					columns: columnsLegacyFormatter
-				}, "gridLegacyFormatter");
-				gridLegacyFormatter.renderArray(testOrderedData);
-				
-				window.gridLegacyFormatterScope = new Grid({
-					columns: columnsLegacyFormatterScope,
-					formatterScope: testFormatterScope
-				}, "gridLegacyFormatterScope");
-				gridLegacyFormatterScope.renderArray(testOrderedData);
-				
-				
-				window.gridLegacyGet = new Grid({
-					columns: columnsLegacyGet
-				}, "gridLegacyGet");
-				gridLegacyGet.renderArray(testOrderedData);
-				
-				window.gridNew = new Grid({
-					columns: lang.clone(columnsNew)
-				}, "gridNew");
-				gridNew.renderArray(testOrderedData);
-
-				
-				// also, need a store, since there's currently no way to effectively
-				// invoke renderArray from HTML.
-				store = Observable(Memory({data: testOrderedData}));
-				parser.parse();
-				
-				// Test 2x: testing dgrid w/o srcNodeRef, or w/ srcNodeRef w/o id
-				// Purposely testing with store to see how init is handled.
-				// (works fine if you renderArray after node placement)
-				
-				// Test 2a: srcNodeRef + no id, specify id to dgrid
-				window.grid2a = new OnDemandGrid({
-					store: store,
-					columns: lang.clone(columnsNew),
-					id: "test2a"
-				}, query(".test2a")[0]);
-				
-				// Test 2b: srcNodeRef + no id - should end up with id=dgrid_0
-				window.grid2b = new OnDemandGrid({
-					store: store,
-					columns: lang.clone(columnsNew)
-				}, query(".test2b")[0]);
-				
-				// Test 2c: no srcNodeRef, specify id to dgrid
-				window.grid2c = new OnDemandGrid({
-					store: store,
-					columns: lang.clone(columnsNew),
-					id: "test2c"
-				});
-				query(".test2c")[0].appendChild(grid2c.domNode);
-				// need to call startup after node is placed manually
-				grid2c.startup();
-				
-				// Test 2d: no srcNodeRef, no id - should end up with id=dgrid_1
-				window.grid2d = new OnDemandGrid({
-					store: store,
-					columns: lang.clone(columnsNew)
-				});
-				query(".test2d")[0].appendChild(grid2d.domNode);
-				// need to call startup after node is placed manually
-				grid2d.startup();
-			});
-			
-		</script>
-	</head>
-	<body class="claro">
-		<p>This page tests various responsibilities of renderRow in Grid.js,
-			particularly those sensitive to dojox-grid-friendly properties.</p>
-		<h2>1a: Grid with single column with formatter for _item field (legacy grid behavior)</h2>
-		<div id="gridLegacyFormatter"></div>
-		<h2>1b: Grid with single column with formatter for _item field, using formatterScope (legacy grid behavior)</h2>
-		<div id="gridLegacyFormatterScope"></div>
-		<h2>1c: Grid with single column with get for order field (legacy grid behavior)</h2>
-		<div id="gridLegacyGet"></div>
-		<h2>1d: Grid with single column with renderCell function</h2>
-		<p>(dgrid behavior; should look same as previous but with underlined first header cell
-			and italicized first column values)</p>
-		<div id="gridNew"></div>
-		
-		<hr>
-		
-		<h2>2a: Grid on domnode with no initial id, id specified as param (will become DOM node id)</h2>
-		<div class="test2a"></div>
-		<h2>2b: Grid on domnode with no initial id, dgrid / DOM node id autogenerated</h2>
-		<div class="test2b"></div>
-		<h2>2c: Grid with no srcNodeRef (placed inside another domNode), id specified as param (will become DOM node id)</h2>
-		<div class="test2c"></div>
-		<h2>2d: Grid with no srcNodeRef (placed inside another domNode), dgrid / DOM node id autogenerated</h2>
-		<div class="test2d"></div>
-	</body>
-</html>

+ 0 - 68
esp/files/dgrid/test/JsonRest.html

@@ -1,68 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>Test JsonRest store</title>
-		<meta name="viewport" content="width=570">
-		<style>
-			@import "../../dojo/resources/dojo.css";
-			@import "../css/skins/claro.css";
-			h2 {
-				margin: 12px;
-			}
-			.heading {
-				font-weight: bold;
-				padding-bottom: 0.25em;
-			}
-			.ui-widget{
-				margin: 10px;
-			}
-		</style>
-		<script src="../../dojo/dojo.js" 
-			data-dojo-config="async: true"></script>
-		<script>
-			require(["dgrid/List", "dgrid/OnDemandGrid","dgrid/Selection", "dgrid/editor", "dgrid/Keyboard", "dgrid/tree", "dojo/_base/declare", "dojo/store/JsonRest", "dojo/store/Observable", "dojo/store/Cache", "dojo/store/Memory", "dojo/domReady!"], 
-				function(List, Grid, Selection, editor, Keyboard, tree, declare, JsonRest, Observable, Cache, Memory){
-					var testStore = Observable(Cache(JsonRest({
-						target:"./data/rest.php?", 
-						idProperty: "id",
-						query: function(query, options){
-							// have to manually adjust the query to get rid of the double ?? that trips php up
-							if(query.parent){
-								query = "parent=" + query.parent;
-							}
-							return JsonRest.prototype.query.call(this, query, options);
-						}
-					}), Memory()));
-					testStore.getChildren = function(parent, options){
-						return testStore.query({parent: parent.id}, options);
-					};
-					var columns = [
-						tree({label:'Name', field:'name', sortable: false}),
-						{label:'Id', field:'id', sortable: false},
-						editor({label:'Comment', field:'comment', sortable: false}, "text"),
-						editor({label:'Boolean', field:'boo', sortable: false, autoSave: true}, "checkbox")
-					];
-
-					window.grid = new (declare([Grid, Selection, Keyboard]))({
-						store: testStore,
-						getBeforePut: false,
-						columns: columns
-					}, "grid");
-					deleteSelected = function(){
-						for(var i in grid.selection){
-							testStore.remove(i);
-						}
-					}
-				});
-				
-		</script>
-	</head>
-	<body class="claro">
-		<h2>A basic grid with JsonRest store</h2>
-		<div id="grid"></div>
-		<button onclick='deleteSelected()'>Delete Page</div>
-		<button onclick='grid.save();'>Save</div>
-		<button onclick='grid.revert();'>Revert</div>
-	</body>
-</html>

+ 0 - 72
esp/files/dgrid/test/JsonRest_duplicates.html

@@ -1,72 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>Test JsonRest Tree with objects repeated in different places in hierarchy</title>
-		<meta name="viewport" content="width=570">
-		<style>
-			@import "../../dojo/resources/dojo.css";
-			@import "../css/skins/claro.css";
-			h2 {
-				margin: 12px;
-			}
-			.dgrid {
-				margin: 10px;
-			}
-		</style>
-		<script src="../../dojo/dojo.js"
-			data-dojo-config="async: true"></script>
-		<script>
-			function deleteSelected(){
-				for(var i in grid.selection){
-					testStore.remove(i);
-				}
-			}
-			function newPage(){
-				testStore.add({
-					name: "new",
-					comment:"New"
-				});
-			}
-			
-			require(["dgrid/OnDemandGrid", "dgrid/Selection", "dgrid/Keyboard",
-				"dgrid/editor", "dgrid/tree", "dojo/_base/declare",
-				"dojo/store/JsonRest", "dojo/store/Observable", "dojo/store/Cache", "dojo/store/Memory",
-				"dojo/store/util/SimpleQueryEngine", "dojo/domReady!"], 
-			function(Grid, Selection, Keyboard, editor, tree, declare, JsonRest, Observable, Cache, Memory, SimpleQueryEngine){
-				var testStore = window.testStore = Observable(Cache(JsonRest({
-					target:"./data/rest.php?", 
-					idProperty: "id",
-					queryEngine: SimpleQueryEngine,
-					query: function(query, options){
-						query = "";
-						return JsonRest.prototype.query.call(this, query, options);
-					}
-				}), Memory()));
-				testStore.getChildren = function(parent, options){
-					return testStore.query({parent: parent.id}, options);
-				};
-				var columns = [
-					tree({label:'Name', field:'name', sortable: false, allowDuplicates: true}),
-					{label:'Id', field:'id', sortable: true},
-					editor({label:'Comment', field:'comment', sortable: false, autoSave: true}, "text"),
-					editor({label:'Boolean', field:'boo', sortable: false, autoSave: true}, "checkbox")
-				];
-
-				var grid = window.grid = new (declare([Grid, Selection, Keyboard]))({
-					store: testStore,
-					getBeforePut: false,
-					columns: columns
-				}, "grid");
-			});
-		</script>
-	</head>
-	<body class="claro">
-		<h2>Test JsonRest Tree with objects repeated in different places in hierarchy</h2>
-		<div id="grid"></div>
-		<button onclick='deleteSelected();'>Delete Page</div>
-		<button onclick='grid.save();'>Save</div>
-		<button onclick='grid.revert();'>Revert</div>
-		<button onclick='newPage();'>New Page</div>
-	</body>
-</html>

+ 0 - 100
esp/files/dgrid/test/Keyboard.html

@@ -1,100 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>Test Keyboard Mixin</title>
-		<meta name="viewport" content="width=570">
-		<style>
-			@import "../../dojo/resources/dojo.css";
-			@import "../css/skins/claro.css";
-			/* add styles to size this grid appropriately */
-			.dgrid {
-				height: 15em;
-				float: left;
-				width: 40%;
-				margin: 1em 0.5%;
-			}
-			.field-order {
-				width: 3em;
-			}
-			.field-name {
-				width: 8em;
-			}
-			#list {
-				width: 15%;
-			}
-			
-			.clear {
-				clear: both;
-			}
-		</style>
-		<script src="../../dojo/dojo.js" 
-			data-dojo-config="async: true"></script>
-		<script>
-			var getFirstTarget; // function, defined within require callback
-			
-			require(["dgrid/OnDemandList", "dgrid/OnDemandGrid", "dgrid/Keyboard", "dojo/_base/declare", "dojo/on", "dojo/query", "put-selector/put", "dgrid/test/data/base", "dojo/domReady!"],
-			function(OnDemandList, OnDemandGrid, Keyboard, declare, on, query, put){
-				var columns = {
-						col1: "Column 1",
-						col3: "Column 3",
-						col5: "Column 5"
-					},
-					KeyboardList = declare([OnDemandList, Keyboard]),
-					KeyboardGrid = declare([OnDemandGrid, Keyboard]),
-					list = window.list = new KeyboardList({
-						store: testStore,
-						renderRow: function(item){ return put("div", item.col5); }
-					}, "list"),
-					grid = window.grid = new KeyboardGrid({
-						store: testStore,
-						columns: columns
-					}, "grid"),
-					rowGrid = window.rowGrid = new KeyboardGrid({
-						store: testStore,
-						columns: columns,
-						cellNavigation: false
-					}, "rowGrid");
-				
-				getFirstTarget = function(grid){
-					return query(".dgrid-content .dgrid-cell", grid.domNode)[0] ||
-						query(".dgrid-content .dgrid-row", grid.domNode)[0];
-				};
-				
-				on(document.body, "dgrid-cellfocusin,dgrid-cellfocusout",
-					function(event){
-						var msg = "focus " + (event.type == "dgrid-cellfocusin" ? "gained" : "lost");
-						console.log(event.grid.id + ": " + msg +
-							(event.parentType ? " (via " + event.parentType + "): " : ": "),
-							event.cell || event.row
-						);
-					}
-				);
-			});
-		</script>
-	</head>
-	<body class="claro">
-		<h2>Keyboard/focus-enabled List and Grids</h2>
-		<div id="list"></div>
-		<div id="grid"></div>
-		<div id="rowGrid"></div>
-		<div class="clear">
-			<h3>Buttons to test programmatic focus</h3>
-			<div>Focus, no argument:
-				<button onclick="list.focus();">List</button>
-				<button onclick="grid.focus();">Cell-navigation Grid</button>
-				<button onclick="rowGrid.focus();">Row-navigation Grid</button>
-			</div>
-			<div>Focus first row/cell:
-				<button onclick="list.focus(getFirstTarget(list));">List</button>
-				<button onclick="grid.focus(getFirstTarget(grid));">Cell-navigation Grid</button>
-				<button onclick="rowGrid.focus(getFirstTarget(rowGrid));">Row-navigation Grid</button>
-			</div>
-			<div>Focus header (no argument):
-				<button onclick="grid.focusHeader();">Cell-navigation Grid</button>
-				<button onclick="grid.set('columns', grid.columns); grid.focusHeader();">
-					Reset columns, then focus</button>
-			</div>
-		</div>
-	</body>
-</html>

+ 0 - 378
esp/files/dgrid/test/OnDemand.html

@@ -1,378 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>Test Grid Store Observation</title>
-		<meta name="viewport" content="width=570">
-		<style>
-			@import "../../dojo/resources/dojo.css";
-			@import "../../dijit/themes/claro/claro.css";
-			@import "../css/skins/claro.css";
-			
-			.ui-widget {
-				margin: 10px;
-			}
-			
-			.dgrid-grid {
-				width: 700px;
-			}
-			.dgrid-list {
-				width: 200px;
-			}
-			
-			#grid2 {
-				width: 500px;
-				float: left;
-			}
-			#grid3 {
-				width: 500px;
-				float: right;
-			}
-			
-			.dgrid .field-bool {
-				width: 6em;
-			}
-			.dgrid .field-type {
-				width: 80px;
-			}
-			
-			#grid2 .field-date, #grid2 .field-date2 {
-				width: 16em;
-			}
-			#grid2 .field-integer {
-				width: 6em;
-			}
-			#grid2 .field-bool { /* checkbox */
-				width: 4em;
-			}
-			
-			#gridAddDel, #listAddDel {
-				float: left;
-			}
-		</style>
-		<script>
-			var start= new Date().getTime();
-		</script>
-		<script src="../../dojo/dojo.js" 
-			data-dojo-config="async: true"></script>
-		<script>
-			require([
-				"dojo/on",
-				"dgrid/OnDemandList",
-				"dgrid/OnDemandGrid",
-				"dgrid/Keyboard",
-				"dgrid/Selection",
-				"dgrid/editor",
-				"dijit/form/DateTextBox",
-				"dijit/form/HorizontalSlider",
-				"dijit/form/NumberSpinner",
-				"dojo/_base/lang",
-				"dojo/_base/declare",
-				"dojo/_base/array",
-				"dojo/Stateful",
-				"dojo/store/Memory",
-				"put-selector/put",
-				"dgrid/test/data/errorStores",
-				"dgrid/test/data/base",
-				"dojo/domReady!"
-			], function(on, List, Grid, Keyboard, Selection, editor, DateTextBox, Slider, NumberSpinner,
-					lang, declare, arrayUtil, Stateful, Memory, put, errorStores){
-				
-				function createStatefulStore() {
-					var data = [],
-						states = testStateStore.data,
-						state,
-						statefulState,
-						i,
-						total = states.length;
-					
-					function watcher(name, oldValue, value) {
-						console.log(name, " updating from ", oldValue, " to ", value);
-					}
-					
-					for (i = 0; i < total; i++) {
-						state = states[i];
-						statefulState = new Stateful({
-							abbreviation: state.abbreviation,
-							name: state.name
-						});
-						statefulState.watch(watcher);
-						data.push(statefulState);
-					}
-
-					return new Memory({
-						data: data,
-						idProperty: "abbreviation"
-					});
-				}
-				
-				var columns = {
-					col1: 'Column 1',
-					col2: {label: 'Column 2'},
-					col3: 'Column 3',
-					col4: 'Column 4',
-					col5: 'Column 5',
-					col6: 'Column 6',
-					col7: 'Column 7'
-				};
-
-				var columns2 = [
-					editor({label: 'Real Number', field: 'floatNum'}, Slider),
-					editor({label: 'Integer', field: 'integer', editorArgs: {style: 'width: 5em;'}}, NumberSpinner),
-					editor({label: 'Text editable if checkbox checked', field: 'text', canEdit: function(object){
-						return object.bool;
-					}}, "text", "dblclick"),
-					editor({label: 'Another Date (autoSave)', field: 'date2', autoSave:true}, DateTextBox, "focus"),
-					editor({label: 'Check', field: 'bool'}, "checkbox")
-				];
-
-				var columns3 = {
-					floatNum: 'Real Number',
-					integer: 'Integer',
-					text: 'Text',
-					date2: 'Date',
-					bool: 'Check'
-				};
-				var columns4 = {
-					col1: 'Color',
-					col2: 'A Goat',
-					col3: 'Position',
-					col4: 'Description',
-					col5: 'R',
-					col6: 'G',
-					col7: 'B'
-				};
-				var StandardGrid = declare([Grid, Selection, Keyboard]);
-				var grid = window.grid = new StandardGrid({
-					store: testStore,
-					columns: columns,
-					sort: "col3", // initially sort by col3 ascending
-					noDataMessage: "Nobody here but us chickens!",
-					loadingMessage: "Loading..."
-				}, "grid");
-
-				var grid2 = window.grid2 = new StandardGrid({
-					store: testTypesStore,
-					columns: columns2,
-					selectionMode: "single"
-				},"grid2");
-
-				var grid3 = window.grid3 = new StandardGrid({
-					store: testTypesStore,
-					columns: columns3
-				}, "grid3");
-
-				var gridAddDel = window.gridAddDel = new StandardGrid({
-					store: smallColorStore,
-					columns: lang.clone(columns4)
-				}, "gridAddDel");
-				
-				// also throw in a List connected to the same store
-				// (so additions/deletions should show up in both)
-				window.listAddDel = new (declare([List, Keyboard, Selection]))({
-					store: smallColorStore,
-					columns: lang.clone(columns4),
-					renderRow: function(object, options){
-						// need to define renderRow to accommodate store items
-						return put("div", object.col1);
-					}
-				}, "listAddDel");
-				
-				window.statefulGrid = new StandardGrid({
-					store: createStatefulStore(),
-					columns: [
-						editor({
-							label: "Abbreviation",
-							field: "abbreviation",
-							editor: "text",
-							editOn: "dblclick"
-						}),
-						editor({
-							label: "Name",
-							field: "name",
-							editor: "text",
-							editOn: "dblclick"
-						})
-					]
-				}, "statefulGrid");
-				
-				// buttons / listeners for 1st grid
-				
-				grid.on("dgrid-error", function(evt) {
-					console.warn("error on grid: ", evt.error);
-				});
-				
-				on(document.getElementById("setstore"), "click", function(){
-					console.log("setting store to colorStore: ", colorStore);
-					window.grid.set("store", colorStore);//no query
-				});
-				on(document.getElementById("restore"), "click", function(){
-					console.log("setting store to testStore");
-					grid.set("store", testStore);//no query
-				});
-				on(document.getElementById("colorQuery"), "click", function(){
-					console.log("setting store to colorStore and setting query to show only primary colors");
-					grid.set("store", colorStore, {col3: "Primary"});//query set to only show primary colors
-				});
-				on(document.getElementById("resetQuery"), "click", function(){
-					console.log("reset query to show all");
-					grid.set("query", {});
-				});
-				
-				var sortDescending = true;
-				
-				on(document.getElementById("setQueryWithOptions"), "click", function(){
-					// set sort for the col1 field
-					sortDescending = !sortDescending;
-					
-					// get existing sort order
-					var sortByCol1 = arrayUtil.filter(
-							grid.get("sort") || [], 
-							function(sortBy){
-								return sortBy.attribute == "col1";
-							}
-					).shift();
-					if(sortByCol1){
-						console.log("modifying existing sort direction for col1: ", sortByCol1);
-					} else {
-						sortByCol1 = { attribute: "col1" };
-					}
-					sortByCol1.descending = sortDescending;
-					grid.set("query", grid.query, { sort: [sortByCol1] });
-					
-					console.log("sort after setting query + queryOptions w/ sort: ",
-						grid.get("sort"), grid.queryOptions);
-				});
-				on(document.getElementById("sort"), "click", function(){
-					sortDescending = !sortDescending;
-					grid.set("sort", "col1", sortDescending);
-					
-					console.log("sort after setting sort: ", grid.get("sort"));
-				});
-
-
-				on(document.getElementById("empty"), "click", function(){
-					grid.set("store", emptyStore, {});
-				});
-				on(document.getElementById("emptyAsync"), "click", function(){
-					grid.set("store", emptyAsyncStore, {});
-				});
-				on(document.getElementById("error"), "click", function(){
-					grid.set("store", errorStores.query, {});
-				});
-				
-				on(document.getElementById("error2"), "click", function(){
-					grid.set("store", errorStores.asyncQuery, {});
-				});
-				
-				// buttons / listeners for 2nd grid
-				
-				function updateDirty(){
-					setTimeout(function(){
-						var dirtyDiv = document.getElementById("dirty");
-						// clear "dirty items" list after change has been processed
-						dirtyDiv.innerHTML = "";
-						for(var rowId in grid2.dirty){
-							put(dirtyDiv, "div", "rowId: "+rowId);
-						}
-					}, 0);
-				}
-				
-				grid2.on("dgrid-error", function(evt) {
-					console.warn("error on grid2: ", evt.error);
-				});
-				
-				on(document.getElementById("save"), "click", function(){
-					console.log("save to store");
-					grid2.save();
-					updateDirty();
-				});
-				
-				on(document.getElementById("setorigeditstore"), "click", function(){
-					grid2.set("store", testTypesStore, {});
-					updateDirty();
-				});
-				
-				on(document.getElementById("seterrorputstore"), "click", function(){
-					grid2.set("store", errorStores.put, {});
-					updateDirty();
-				});
-				
-				on(document.getElementById("setdeferrorputstore"), "click", function(){
-					grid2.set("store", errorStores.asyncPut, {});
-					updateDirty();
-				});
-				
-				grid2.on("dgrid-datachange", updateDirty);
-				
-				// buttons for 3rd grid
-				
-				on(document.getElementById("add"), "click", function(){
-					var id = smallColorStore.data.length+Math.floor(Math.random()*1001);
-					console.log("id: ", id);
-					smallColorStore.put({id: id, col1: "Grey", col2: false, col3: "Hue", col4:'A hue' , col5: 192, col6: 192, col7: 192 });
-				});
-				on(document.getElementById("delete"), "click", function(){
-					for(var id in gridAddDel.selection){
-						smallColorStore.remove(id);
-					}
-				});
-				
-				// hook up a listener for error events on the document to test bubbling
-				// (currently error events don't seem to bubble,
-				// but perhaps we want them to?)
-				on(document, "dgrid-error", function(evt){
-					evt.preventDefault(); // Suppress console.error
-					console.log("document received error: " + evt.error);
-				});
-			});
-		</script>
-	</head>
-	<body class="claro">
-		<h2>Simple test to show setting a new store and query to dgrid</h2>
-		<div id="grid"></div>
-		<button id="colorQuery">Set color store and query</button>
-		<button id="resetQuery">Reset query</button>
-		<button id="setQueryWithOptions">Set query with queryOptions</button>
-		<button id="sort">sort</button>
-		<br>
-		<button id="setstore">Set Color Store</button>
-		<button id="restore">Set Original Store</button>
-		<button id="empty">Set to empty store</button>
-		<button id="emptyAsync">Set to empty store (async)</button>
-		<button id="error">Set to error store</button>
-		<button id="error2">Set to error store (async)</button>
-
-		<br><br>
-		<h2>Simple test to show editor effect on store data</h2>
-		<div id="container" style="width:1200px;">
-		<div id="grid2"></div>
-		<div style="float:left;margin-left:20px;"><div><h3>Dirty Items</h3></div><div id="dirty"></div></div>
-		<div id="grid3"></div>
-		</div>
-		<div style="clear:both"><button id="save">Save Changes</button></div>
-		<p>The following buttons switch between stores in the left grid above,
-			to test handling of errors on put operations.</p>
-		<p>Note that clicking Save will NOT emit an error event on the grid,
-			as direct invocations of save are expected to handle the returned promise
-			as they see fit.  However, modifying an editor field with autoSave enabled
-			will cause an error event to be emitted, since in this case it is
-			the grid which initiated the operation.</p>
-		<div>
-			<button id="setorigeditstore">Set to original store</button>
-			<button id="seterrorputstore">Set to store which causes error on put</button>
-			<button id="setdeferrorputstore">Set to store which rejects Deferred on put</button>
-		</div>
-		<h2>Simple test to show adding/deleting items</h2>
-		<p>(With an OnDemandList alongside, also observing the changes)</p>
-		<div id="gridAddDel"></div>
-		<div id="listAddDel"></div>
-		<div style="clear:both">
-			<button id="add">Add Color</button>
-			<button id="delete">Delete Selected</button>
-		</div>
-		<h2>OnDemandGrid using store with Stateful objects</h2>
-		<div id="statefulGrid"></div>
-		<button type="button" onclick="statefulGrid.save()">Save</button>
-	</body>
-</html>

+ 0 - 71
esp/files/dgrid/test/OnDemand_promises.html

@@ -1,71 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>Test OnDemandGrids with promise-based stores</title>
-		<link rel="stylesheet" href="../../dojo/resources/dojo.css">
-		<link rel="stylesheet" href="../css/skins/claro.css">
-		<style>
-#grid, #grid2 {
-	height: 300px;
-}
-		</style>
-	</head>
-	<body class="claro">
-		<p>This test page tests two types of stores that return promises from their
-		query methods: the dojo/store/DataStore wrapper for dojo/data stores,
-		and an instance of dojo/store/Memory with a promise returned from query.</p>
-		<h2>Grid w/ ItemFileWriteStore via DataStore</h2>
-		<div>
-			<button onclick="grid.set('query', { name: 'foo' })">Show only items named 'foo'</button>
-			<button onclick="grid.set('query', {})">Reset query</button>
-		</div>
-		<div id="grid"></div>
-		<h2>Grid w/ dojo/store w/ async query results</h2>
-		<div id="grid2"></div>
-		<script src="../../dojo/dojo.js" data-dojo-config="async:true"></script>
-		<script>
-require(["dgrid/OnDemandGrid", "dojo/store/Memory", "dojo/store/Observable", "dojo/store/util/QueryResults", "dojo/data/ItemFileWriteStore", "dojo/store/DataStore", "dojo/_base/Deferred", "dojo/_base/lang"],
-function(Grid, Memory, Observable, QueryResults, ItemFileWriteStore, DataStore, Deferred, lang){
-	var items = [], ifws, datastore, asyncstore, grid, grid2, i,
-		names = ["sasquatch", "foo", "bar", "zaphod", "beeblebrox"];
-	
-	// generate data
-	for(i = 1; i <= 200; i++){
-		items.push({
-			id: i,
-			name: names[i%5]
-		});
-	}
-	
-	ifws = new ItemFileWriteStore({ data: { identifier: "id", items: lang.clone(items) } });
-	datastore = window.datastore = Observable(new DataStore({store: ifws}));
-	
-	var grid = window.grid = new Grid({
-		columns: { id: "id", name: "name" },
-		store: datastore
-	}, "grid");
-	
-	var asyncstore = window.asyncstore = Observable(new Memory({
-		data: items,
-		query: function(query, options){
-			var results, def, promisedResults;
-			results = Memory.prototype.query.apply(this, arguments);
-			def = new Deferred();
-			setTimeout(function(){
-				def.resolve(results);
-			}, 200);
-			promisedResults = QueryResults(def.promise);
-			promisedResults.total = results.total;
-			return promisedResults;
-		}
-	}));
-	
-	var grid2 = window.grid2 = new Grid({
-		columns: { id: "id", name: "name" },
-		store: asyncstore
-	}, "grid2");
-});
-		</script>
-	</body>
-</html>

+ 0 - 76
esp/files/dgrid/test/OnDemand_tile.html

@@ -1,76 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>Test Tile Layout in OnDemandList</title>
-		<style>
-			@import "../../dojo/resources/dojo.css";
-			@import "../css/dgrid.css";
-			@import "../css/skins/claro.css";
-			.dgrid {
-				margin: 10px;
-				width: 430px;
-				height: 400px;
-				float: left;
-			}
-			
-			#list .dgrid-row {
-				display: inline-block;
-				width: 100px;
-				height: 100px;
-			}
-			
-			#imglist .dgrid-row {
-				width: 64px;
-				height: 64px;
-			}
-			
-			.clear {
-				clear: both;
-			}
-		</style>
-		<script src="../../dojo/dojo.js" 
-			data-dojo-config="async: true"></script>
-		<script>
-			var logRendered; // Function defined in require factory
-			require(["dgrid/OnDemandList", "dojo/query", "dojo/store/Memory", "put-selector/put", "dojo/domReady!"],
-			function(OnDemandList, query, Memory, put){
-				// Create dummy array to make list show a number of entries.
-				var data = [], i, store;
-				for(i = 0; i < 500; i++){ data[i] = { id: i }; }
-				store = new Memory({ data: data });
-				
-				logRendered = function(){
-					console.log("list: " + query("#list .dgrid-row").length);
-					console.log("imglist: " + query("#imglist .dgrid-row").length);
-				};
-				document.getElementById("logRendered").onclick = logRendered;
-				
-				window.list = new OnDemandList({
-					store: store,
-					farOffRemoval: 500,
-					renderRow: function(object){
-						return put("span", object.id);
-					}
-				}, "list");
-				
-				window.imglist = new OnDemandList({
-					store: store,
-					farOffRemoval: 500,
-					renderRow: function(object){
-						return put("img[src=../demos/multiview/resources/dojo-64.png]");
-					}
-				}, "imglist");
-			});
-				
-		</script>
-	</head>
-	<body class="claro">
-		<h2>OnDemandLists with a tiled layout, for testing virtual paging</h2>
-		<div id="list"></div>
-		<div id="imglist"></div>
-		<div class="clear">
-			<button id="logRendered">Log number of rendered items</button>
-		</div>
-	</body>
-</html>

+ 0 - 133
esp/files/dgrid/test/Selection.html

@@ -1,133 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>Test Selection</title>
-		<meta name="viewport" content="width=570">
-		<style>
-			@import "../../dojo/resources/dojo.css";
-			@import "../css/skins/nihilo.css";
-			.heading {
-				font-weight: bold;
-				padding-bottom: 0.25em;
-			}
-			.dgrid { 
-				width: 70%;
-			}
-			.ui-widget {
-				margin: 10px;
-			}
-		</style>
-		<script src="../../dojo/dojo.js" 
-			data-dojo-config="async: true"></script>
-		<script>
-			require(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/json", "dojo/on",
-					"dgrid/OnDemandGrid", "dgrid/editor","dgrid/Selection", "dgrid/CellSelection", "dgrid/Keyboard",
-					"dgrid/test/data/base", "dojo/domReady!"],
-				function(lang, declare, arrayUtil, json, on, Grid, editor, Selection, CellSelection, Keyboard, testStore){
-					on(document.body, "dgrid-select,dgrid-deselect",
-						function(event){
-							var msg = (event.type == "dgrid-deselect" ? "de" : "") + "selected";
-							console.log(event.grid.id + ": " + msg +
-								(event.parentType ? " (via " + event.parentType + "): " : ": "),
-								(event.cells ?
-									arrayUtil.map(event.cells, function(cell){
-										return cell.row.id + ":" + cell.column.id;
-									}).join(", ") :
-									arrayUtil.map(event.rows, function(row){ return row.id; }).join(", "))
-							);
-							console.log("selection: " + json.stringify(event.grid.selection, null, "  "));
-						}
-					);
-					var SelectionGrid = declare([Grid, Selection, Keyboard]);
-					var CellSelectionGrid = declare([Grid, CellSelection, Keyboard]);
-
-					gridRowNavigation = new SelectionGrid({
-						store: testStore,
-						cellNavigation: false,
-						columns: {
-							col1: 'Column 1',
-							col2: {label: 'Column 2', sortable: false},
-							col3: 'Column 3',
-							col4: editor({label: 'Editable'}, "text")
-						},
-						allowSelectAll: true
-					}, "grid-row-navigation");
-					
-					var columns2 = {
-						col1: 'Column 1',
-						col2: {label: 'Column 2', sortable: false},
-						col3: 'Column 3',
-						col4: 'Column 4'
-					};
-					gridCellNavigation = new CellSelectionGrid({
-						store: testStore,
-						columns: lang.clone(columns2)
-					}, "grid-cell-navigation");
-					gridCellNavigationSingle = new CellSelectionGrid({
-						store: testStore,
-						columns: lang.clone(columns2),
-						selectionMode: "single"
-					}, "grid-cell-navigation-single");
-					gridCellNavigationMultiple = new CellSelectionGrid({
-						store: testStore,
-						columns: lang.clone(columns2),
-						selectionMode: "multiple"
-					}, "grid-cell-navigation-multiple");
-					gridCellNavigationNone = new CellSelectionGrid({
-						store: testStore,
-						columns: lang.clone(columns2),
-						selectionMode: "none",
-						allowSelectAll: true
-					}, "grid-cell-navigation-none");
-					
-					// cell navigation + row selection
-					gridMixed = new SelectionGrid({
-						store: testStore,
-						columns: { // same as columns in very first grid
-							col1: 'Column 1',
-							col2: {label: 'Column 2', sortable: false},
-							col3: 'Column 3',
-							col4: editor({label: 'Editable'}, "text")
-						}
-					}, "grid-mixed");
-				});
-		</script>
-	</head>
-	<body class="nihilo">
-		<h2>A grid with row-level selection (and row-level navigation)</h2>
-		<h3>Use Ctrl/Cmd+A to test keyboard select-all with different selectionModes</h3>
-		<div>Set selectionMode:
-			<button type="button" onclick="gridRowNavigation.set('selectionMode', 'none');">None</button>
-			<button type="button" onclick="gridRowNavigation.set('selectionMode', 'single');">Single</button>
-			<button type="button" onclick="gridRowNavigation.set('selectionMode', 'multiple');">Multiple</button>
-			<button type="button" onclick="gridRowNavigation.set('selectionMode', 'extended');">Extended</button>
-			<button type="button" onclick="gridRowNavigation.set('selectionMode', 'toggle');">Toggle</button>
-		</div>
-		<div>Set allowTextSelection:
-			<button type="button" onclick="gridRowNavigation.set('allowTextSelection', true);">Always allow</button>
-			<button type="button" onclick="gridRowNavigation.set('allowTextSelection', false);">Always prevent</button>
-			<button type="button" onclick="gridRowNavigation.set('allowTextSelection', undefined);">Default</button>
-			(default = allowed only when selectionMode == none)
-		</div>
-		<div id="grid-row-navigation"></div>
-		<h2>A grid with cell-level selection (default selection mode of "extended")</h2>
-		<div id="grid-cell-navigation"></div>
-		<h2>A grid with cell-level selection and selection mode of "single"</h2>
-		<div id="grid-cell-navigation-single"></div>
-		<h2>A grid with cell-level selection and selection mode of "multiple"</h2>
-		<div id="grid-cell-navigation-multiple"></div>
-		<h2>A grid with cell-level selection and selection mode of "none" initially</h2>
-		<h3>Use Ctrl/Cmd+A to test keyboard select-all with different selectionModes</h3>
-		<div>Set selectionMode:
-			<button type="button" onclick="gridCellNavigationNone.set('selectionMode', 'none');">None</button>
-			<button type="button" onclick="gridCellNavigationNone.set('selectionMode', 'single');">Single</button>
-			<button type="button" onclick="gridCellNavigationNone.set('selectionMode', 'multiple');">Multiple</button>
-			<button type="button" onclick="gridCellNavigationNone.set('selectionMode', 'extended');">Extended</button>
-			<button type="button" onclick="gridCellNavigationNone.set('selectionMode', 'toggle');">Toggle</button>
-		</div>
-		<div id="grid-cell-navigation-none"></div>
-		<h2>A grid with row-level selection and cell-level navigation</h2>
-		<div id="grid-mixed"></div>
-	</body>
-</html>

+ 0 - 59
esp/files/dgrid/test/autoheight.html

@@ -1,59 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>Test height:auto</title>
-		<meta name="viewport" content="width=570">
-		<style>
-			@import "../../dojo/resources/dojo.css";
-			@import "../css/dgrid.css";
-			@import "../css/skins/claro.css";
-			.heading {
-				font-weight: bold;
-				padding-bottom: 0.25em;
-			}
-			#grid {
-				width: 400px;
-			}
-			
-			/* styles for autoheight */
-			#grid {
-				height: auto;
-			}
-			#grid .dgrid-scroller {
-				position: relative;
-				overflow-y: hidden;
-			}
-			.has-ie-6 #grid .dgrid-scroller {
-				/* IE6 doesn't react properly to hidden on this page for some reason */
-				overflow-y: visible;
-			}
-			#grid .dgrid-header-scroll {
-				display: none;
-			}
-			#grid .dgrid-header {
-				right: 0;
-			}
-		</style>
-		<script src="../../dojo/dojo.js" 
-			data-dojo-config="async: true"></script>
-		<script>
-			require(["dgrid/List", "dgrid/OnDemandGrid","dgrid/Selection", "dgrid/Keyboard", "dojo/_base/declare", "dgrid/test/data/base", "dojo/domReady!"], 
-				function(List, Grid, Selection, Keyboard, declare){
-					window.grid = new (declare([Grid, Selection, Keyboard]))({
-						store: testCountryStore,
-						columns: {
-							name: "Name",
-							type: "Type"
-						}
-					}, "grid");
-				});
-				
-		</script>
-	</head>
-	<body class="claro">
-		<h2>A basic grid with height:auto</h2>
-		<div id="grid"></div>
-		<a href="https://github.com/SitePen/dgrid">dgrid</a>
-	</body>
-</html>

+ 0 - 127
esp/files/dgrid/test/common_cases.html

@@ -1,127 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>Test Grid Common Cases</title>
-		<meta name="viewport" content="width=570">
-		<style>
-			@import "../../dojo/resources/dojo.css";
-			@import "../css/dgrid.css";
-			@import "../css/skins/claro.css";
-			h2 {
-				font-weight: bold;
-				padding-bottom: 0.25em;
-				clear: both;
-			}
-			#grid { 
-				width: 70%;
-			}
-			#grid .field-col1 {
-				width: 100px;
-			}
-			#grid .field-col2 {
-				width: 30%;
-			}
-			#grid .field-col4 {
-				width: 180px;
-			}
-			
-			#scrollgrid {
-				width: 50%;
-			}
-			#scrollgrid .dgrid-cell {
-				width: 100px; /* force all columns to have SOME width */
-			}
-			#scrollgrid .field-col1 {
-				width: 500px;
-			}
-			#scrollgrid .field-col4 {
-				width: 300px;
-			}
-			
-			#tree {
-				width: 700px;
-				height: 200px;
-				float:left;
-			}
-			#tree .field-bool {
-				width: 20%;
-			}
-			#tree .field-type {
-				width: 80px;
-			}
-			#list{
-				width: 300px;
-				float: left;
-			}
-			.dgrid {
-				margin: 10px;
-			}
-		</style>
-		<script>
-			var start= new Date().getTime();
-		</script>
-		<script src="../../dojo/dojo.js" 
-			data-dojo-config="async: true"></script>
-		<script>
-			require(["dojo/on", "dgrid/List", "dgrid/OnDemandGrid", "dgrid/tree", "dgrid/editor", "dgrid/Selection", "dgrid/Keyboard", "dgrid/test/data/base", "dojo/_base/declare", "dojo/_base/array", "dojo/domReady!"], 
-				function(on, List, Grid, tree, editor, Selection, Keyboard, testStore, declare, arrayUtil){
-					console.log("loaded in " + (new Date().getTime() - start));
-
-					var StandardGrid = declare([Grid, Selection, Keyboard]);
-					
-					function getColumns(){
-						return { // you can declare columns as an object hash (key translates to field)
-							col1: editor({label: 'Column 1 column 1 column 1'}, "text", "dblclick"),
-							col2: {label: 'Column 2', sortable: false},
-							col3: editor({label: 'Column 3'}, "text", "dblclick"),
-							col4: 'Column444444444444444444',
-							col5: editor({label: 'Column 5'}, "text", "dblclick")
-						};
-					}
-					window.grid = new StandardGrid({
-						store: testStore,
-						columns: getColumns()
-					}, "grid");
-					
-					window.scrollgrid = new StandardGrid({
-						store: testStore,
-						columns: getColumns()
-					}, "scrollgrid");
-					
-					window.tree = new StandardGrid({
-						tabIndex: 2,
-						store: testCountryStore,
-						selectionMode: "single",
-						columns: {
-							name: tree({label:'Name', sortable: false}),
-							bool: editor({label: 'A CheckBox', sortable: false}, "checkbox"),
-							type: {label: 'Type', sortable: false},
-							population: 'Population',
-							timezone: 'Timezone'
-						}
-					}, "tree");
-					window.list = new (declare([List, Selection, Keyboard]))({
-						tabIndex: 1
-					}, "list");
-					list.renderArray(arrayUtil.map(testCountryStore.data, function(country){
-						return country.name;
-					}));
-					on(document.getElementById("save"), "click", function(){
-						grid.save();
-					});
-				});
-		</script>
-	</head>
-	<body class="claro">
-		<h2>A basic grid (70% of page width)</h2>
-		<div id="grid"></div>
-		<button id="save">Save</button>
-		<h2>A grid with tree column and then a simple list (floated left)</h2>
-		<div id="tree"></div>
-		<div id="list"></div>
-		<h2>Same as basic grid, but with column widths exceeding grid width</h2>
-		<p>(for testing that nodes occupy correct widths - pay attention to hover/selection style)</p>
-		<div id="scrollgrid"></div>
-	</body>
-</html>

+ 0 - 264
esp/files/dgrid/test/complex_column.html

@@ -1,264 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>Test Grid Complex Columns</title>
-		<meta name="viewport" content="width=570">
-		<style>
-			@import "../../dojo/resources/dojo.css";
-			@import "../css/skins/claro.css";
-			@import "../css/dgrid.css"; /* this ensures that are rules come after dgrid.css */
-			.heading {
-				font-weight: bold;
-				padding-bottom: 0.25em;
-			}
-			.grid { 
-				width: 700px;
-			}
-			.grid .dgrid-column-set-0 { 
-				width: 50%;
-			}
-			.grid .field-col1 {
-				width: 200px;
-			}
-			.grid .field-col2 {
-				width: 100px;
-			}
-			.grid .field-col4 {
-				width: 500px;
-			}
-			.ui-widget{
-				margin: 10px;
-			}
-			.dgrid-sort-arrow {
-				float: left;
-			}
-		</style>
-
-		<script src="../../dojo/dojo.js" 
-			data-dojo-config="async: true"></script>
-		<script>
-			require(["dgrid/OnDemandGrid", "dgrid/GridWithColumnSetsFromHtml", "dgrid/ColumnSet", "dgrid/Selection", "dgrid/Keyboard", "dojo/_base/declare", "dojo/on", "dojo/parser", "dgrid/test/data/base", "dgrid/test/data/DeferredWrapper", "dojo/domReady!"],
-				function(OnDemandGrid, GridFromHtml, ColumnSet, Selection, Keyboard, declare, on, parser, testStore, DeferredWrapper){
-					var columnSets1 = [
-							[
-								[{label: 'Column 1', field: 'col1'},
-										{label: 'Column 2', field: 'col2', sortable: false}],
-									[{label: 'Column 3', field: 'col3', colSpan: 2}]],
-							[
-								[{label: 'Column 1', field: 'col1', rowSpan: 2},
-									{label: 'Column 4', field: 'col4'}],
-									[{label: 'Column 5', field: 'col5'}]
-							]],
-						columnSets2 = [
-							[
-								[{label: 'Column 1', field: 'col1'},
-									{label: 'Column 3', field: 'col3', rowSpan: 2}],
-								[{label: 'Column 2', field: 'col2', sortable: false}]],
-							[
-								[{label: 'Column 1', field: 'col1', colSpan: 2}],
-								[{label: 'Column 4', field: 'col4'},
-									{label: 'Column 5', field: 'col5'}]
-							]],
-						columnSets3 = [
-							[
-								[{label: 'Column 1', field: 'col1'},
-										{label: 'Column 2', field: 'col2', sortable: false}],
-									[{label: 'Column 3', field: 'col3', colSpan: 2}]],
-							[[{label: 'Column 1', field: 'col1', rowSpan: 2}]],
-							[
-								[{label: 'Column 4', field: 'col4'}],
-									[{label: 'Column 5', field: 'col5'}]
-							]],
-						// same structures as above, without being split into ColumnSets
-						subRows1 = [
-							[
-								{label: 'Column 1', field: 'col1'},
-								{label: 'Column 2', field: 'col2', sortable: false},
-								{label: 'Column 1', field: 'col1', rowSpan: 2},
-								{label: 'Column 4', field: 'col4'}
-							], [
-								{label: 'Column 3', field: 'col3', colSpan: 2},
-								{label: 'Column 5', field: 'col5'}
-							]],
-						subRows2 = [
-							[
-								{label: 'Column 1', field: 'col1'},
-								{label: 'Column 3', field: 'col3', rowSpan: 2},
-								{label: 'Column 1', field: 'col1', colSpan: 2}
-							], [
-								{label: 'Column 2', field: 'col2', sortable: false},
-								{label: 'Column 4', field: 'col4'},
-								{label: 'Column 5', field: 'col5'}
-							]],
-						columnSetsSingleRow = [
-							[
-								[
-									{label: 'Column 1', field: 'col1'},
-									{label: 'Column 2', field: 'col2', sortable: false}
-								]
-							], [
-								[
-									{label: 'Column 1', field: 'col1'},
-									{label: 'Column 4', field: 'col4'}
-								]
-							]];
-					
-					function byId(id){ return document.getElementById(id); }
-
-					var ComplexGrid = declare([OnDemandGrid, ColumnSet, Selection, Keyboard]);
-
-					window.gridNoColumnSets = new (declare([OnDemandGrid, Selection, Keyboard]))({
-						store: DeferredWrapper(testStore),
-						subRows: subRows1
-					}, "gridNoColumnSets");
-					
-					window.gridSingleRow = new ComplexGrid({
-						store: DeferredWrapper(testStore),
-						columnSets: columnSetsSingleRow
-					}, "gridSingleRow");
-					
-					window.grid = new ComplexGrid({
-						store: DeferredWrapper(testStore),
-						columnSets: columnSets1
-					}, "grid");
-					
-					// hook up buttons for testing setSubRows / setColumnSets
-					on(byId("btnSubRows1"), "click", function(){
-						gridNoColumnSets.set("subRows", subRows1);
-					});
-					on(byId("btnSubRows2"), "click", function(){
-						gridNoColumnSets.set("subRows", subRows2);
-					});
-					
-					on(byId("btnColumnSets1"), "click", function(){
-						grid.set("columnSets", columnSets1);
-					});
-					on(byId("btnColumnSets2"), "click", function(){
-						grid.set("columnSets", columnSets2);
-					});
-					on(byId("btnColumnSets3"), "click", function(){
-						grid.set("columnSets", columnSets3);
-					});
-
-					var HtmlGrid = declare([OnDemandGrid, GridFromHtml, Selection, Keyboard]);
-
-					window.gridFromHtml = new HtmlGrid({
-						store: DeferredWrapper(testStore)
-					}, "gridFromHtml");
-					window.gridFromHtml2 = new HtmlGrid({
-						store: testStore
-					}, "gridFromHtml2");
-					
-					// test declarative instantiation (need a global for parser)
-					window.dgrid = { GridFromHtml: HtmlGrid };
-					parser.parse();
-				});
-		</script>
-	</head>
-	<body class="claro">
-		<h2>A Grid with subrows (no ColumnSets)</h2>
-		<div id="gridNoColumnSets" class="grid"></div>
-		<p>Buttons to test resetting subRows:
-			<button id="btnSubRows1">set 1</button>
-			<button id="btnSubRows2">set 2</button>
-		</p>
-		<h2>A Grid with locking columns but only one subrow</h2>
-		<div id="gridSingleRow" class="grid"></div>
-		<h2>A Grid with complex columns including locking columns and subrows</h2>
-		<div id="grid" class="grid"></div>
-		<p>Buttons to test resetting columnSets:
-			<button id="btnColumnSets1">set 1</button>
-			<button id="btnColumnSets2">set 2</button>
-			<button id="btnColumnSets3">set 3</button>
-		</p>
-		<p>(set 3 tests 3 columnsets, to test proper cleanup of scrollers when
-			going back to 2)</p>
-		<h2>Same grid, instantiated programmatically from HTML table</h2>
-		<table id="gridFromHtml" class="grid">
-			<colgroup span="2"></colgroup>
-			<colgroup span="2"></colgroup>
-			<thead>
-				<tr>
-					<th data-dgrid-column="{field:'col1'}">Column 1</th>
-					<th data-dgrid-column="{field:'col2', sortable:false}">Column 2</th>
-					<th rowspan="2" data-dgrid-column="{field:'col1'}">Column 1</th>
-					<th data-dgrid-column="{field:'col4'}">Column 4</th>
-				</tr>
-				<tr>
-					<th colspan="2" data-dgrid-column="{field:'col3'}">Column 3</th>
-					<th data-dgrid-column="{field:'col5'}">Column 5</th>
-				</tr>
-			</thead>
-		</table>
-		<h2>Another complex grid instantiated from an HTML table</h2>
-		<table id="gridFromHtml2">
-			<colgroup span="3"></colgroup>
-			<colgroup span="4"></colgroup>
-			<thead>
-				<tr>
-					<th rowspan="3" data-dgrid-column="{field:'col1'}">rowspan=3</th>
-					<th colspan="2" data-dgrid-column="{field:'col2'}">colspan=2</th>
-					<th rowspan="2" data-dgrid-column="{field:'col3'}">rowspan=2</th>
-					<th colspan="2" data-dgrid-column="{field:'col4'}">colspan=2</th>
-					<th rowspan="2" data-dgrid-column="{field:'col5'}">rowspan=2</th>
-				</tr>
-				<tr>
-					<th rowspan="2" data-dgrid-column="{field:'col2'}">rowspan=2</th>
-					<th data-dgrid-column="{field:'col3'}">Column 3</th>
-					<th rowspan="2" data-dgrid-column="{field:'col4'}">rowspan=2</th>
-					<th data-dgrid-column="{field:'col5'}">Column 5</th>
-				</tr>
-				<tr>
-					<th data-dgrid-column="{field:'col2'}">Column 2</th>
-					<th data-dgrid-column="{field:'col3'}">Column 3</th>
-					<th colspan="2" data-dgrid-column="{field:'col5'}">colspan=2</th>
-				</tr>
-			</thead>
-		</table>
-		<hr>
-		<h2>Same as previous two tables, instantiated declaratively</h2>
-		<table id="gridFromHtmlDecl" class="grid" data-dojo-type="dgrid.GridFromHtml"
-			data-dojo-props="store:testStore">
-			<colgroup span="2"></colgroup>
-			<colgroup span="2"></colgroup>
-			<thead>
-				<tr>
-					<th data-dgrid-column="{field:'col1'}">Column 1</th>
-					<th data-dgrid-column="{field:'col2', sortable:false}">Column 2</th>
-					<th rowspan="2" data-dgrid-column="{field:'col1'}">Column 1</th>
-					<th data-dgrid-column="{field:'col4'}">Column 4</th>
-				</tr>
-				<tr>
-					<th colspan="2" data-dgrid-column="{field:'col3'}">Column 3</th>
-					<th data-dgrid-column="{field:'col5'}">Column 5</th>
-				</tr>
-			</thead>
-		</table>
-		<table id="gridFromHtmlDecl2" data-dojo-type="dgrid.GridFromHtml"
-			data-dojo-props="store:testStore">
-			<colgroup span="3"></colgroup>
-			<colgroup span="4"></colgroup>
-			<thead>
-				<tr>
-					<th rowspan="3" data-dgrid-column="{field:'col1'}">rowspan=3</th>
-					<th colspan="2" data-dgrid-column="{field:'col2'}">colspan=2</th>
-					<th rowspan="2" data-dgrid-column="{field:'col3'}">rowspan=2</th>
-					<th data-dgrid-column="{field:'col4', colSpan:2}">colSpan:2</th>
-					<th data-dgrid-column="{field:'col5', rowSpan:2}">rowSpan:2</th>
-				</tr>
-				<tr>
-					<th rowspan="2" data-dgrid-column="{field:'col2'}">rowspan=2</th>
-					<th data-dgrid-column="{field:'col3'}">Column 3</th>
-					<th rowspan="2" data-dgrid-column="{field:'col4'}">rowspan=2</th>
-					<th data-dgrid-column="{field:'col5'}">Column 5</th>
-				</tr>
-				<tr>
-					<th data-dgrid-column="{field:'col2'}">Column 2</th>
-					<th data-dgrid-column="{field:'col3'}">Column 3</th>
-					<th colspan="2" data-dgrid-column="{field:'col5'}">colspan=2</th>
-				</tr>
-			</thead>
-		</table>
-	</body>
-</html>

+ 0 - 35
esp/files/dgrid/test/data/DeferredWrapper.js

@@ -1,35 +0,0 @@
-define(["dojo/_base/lang", "dojo/_base/Deferred", "dojo/store/util/QueryResults"],function(lang, Deferred, QueryResults){
-	// summary:
-	//		Creates a store that wraps the delegate store's query results and total in Deferred
-	//		instances. If delay is set, the Deferreds will be resolved asynchronously after delay +/-50%
-	//		milliseconds to simulate network requests that may come back out of order.
-	return function(store, delay){
-		return lang.delegate(store, {
-			query: function(query, options){
-				var queryResult = store.query(query, options);
-
-				var totalDeferred = new Deferred();
-				var resultsDeferred = new Deferred();
-				resultsDeferred.total = totalDeferred;
-
-				var resolveTotal = function(){
-					totalDeferred.resolve(queryResult.total);
-				};
-				var resolveResults = function(){
-					resultsDeferred.resolve(queryResult);
-				};
-
-				if(delay){
-					setTimeout(resolveTotal, delay * (Math.random() + 0.5));
-					setTimeout(resolveResults, delay * (Math.random() + 0.5));
-				}
-				else{
-					resolveTotal();
-					resolveResults();
-				}
-					
-				return QueryResults(resultsDeferred);
-			}
-		});
-	}
-});

+ 0 - 0
esp/files/dgrid/test/data/base.js


Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff