summaryrefslogtreecommitdiff
path: root/js/dojo-1.6/dojox/grid
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo-1.6/dojox/grid')
-rw-r--r--js/dojo-1.6/dojox/grid/DataGrid.js14
-rw-r--r--js/dojo-1.6/dojox/grid/DataGrid.js.uncompressed.js17283
-rw-r--r--js/dojo-1.6/dojox/grid/DataGrid.xd.js14
-rw-r--r--js/dojo-1.6/dojox/grid/DataGrid.xd.js.uncompressed.js17090
-rw-r--r--js/dojo-1.6/dojox/grid/DataSelection.js76
-rw-r--r--js/dojo-1.6/dojox/grid/DataSelection.xd.js81
-rw-r--r--js/dojo-1.6/dojox/grid/EnhancedGrid.js265
-rw-r--r--js/dojo-1.6/dojox/grid/EnhancedGrid.xd.js274
-rw-r--r--js/dojo-1.6/dojox/grid/LazyTreeGrid.js823
-rw-r--r--js/dojo-1.6/dojox/grid/LazyTreeGrid.xd.js831
-rw-r--r--js/dojo-1.6/dojox/grid/LazyTreeGridStoreModel.js116
-rw-r--r--js/dojo-1.6/dojox/grid/LazyTreeGridStoreModel.xd.js121
-rw-r--r--js/dojo-1.6/dojox/grid/README148
-rw-r--r--js/dojo-1.6/dojox/grid/Selection.js271
-rw-r--r--js/dojo-1.6/dojox/grid/Selection.xd.js275
-rw-r--r--js/dojo-1.6/dojox/grid/TreeGrid.js962
-rw-r--r--js/dojo-1.6/dojox/grid/TreeGrid.xd.js970
-rw-r--r--js/dojo-1.6/dojox/grid/TreeSelection.js219
-rw-r--r--js/dojo-1.6/dojox/grid/TreeSelection.xd.js224
-rw-r--r--js/dojo-1.6/dojox/grid/_Builder.js753
-rw-r--r--js/dojo-1.6/dojox/grid/_Builder.xd.js759
-rw-r--r--js/dojo-1.6/dojox/grid/_CheckBoxSelector.js14
-rw-r--r--js/dojo-1.6/dojox/grid/_CheckBoxSelector.xd.js19
-rw-r--r--js/dojo-1.6/dojox/grid/_EditManager.js250
-rw-r--r--js/dojo-1.6/dojox/grid/_EditManager.xd.js255
-rw-r--r--js/dojo-1.6/dojox/grid/_Events.js503
-rw-r--r--js/dojo-1.6/dojox/grid/_Events.xd.js507
-rw-r--r--js/dojo-1.6/dojox/grid/_FocusManager.js612
-rw-r--r--js/dojo-1.6/dojox/grid/_FocusManager.xd.js617
-rw-r--r--js/dojo-1.6/dojox/grid/_Grid.js1382
-rw-r--r--js/dojo-1.6/dojox/grid/_Grid.xd.js1401
-rw-r--r--js/dojo-1.6/dojox/grid/_Layout.js275
-rw-r--r--js/dojo-1.6/dojox/grid/_Layout.xd.js281
-rw-r--r--js/dojo-1.6/dojox/grid/_RadioSelector.js14
-rw-r--r--js/dojo-1.6/dojox/grid/_RadioSelector.xd.js19
-rw-r--r--js/dojo-1.6/dojox/grid/_RowManager.js71
-rw-r--r--js/dojo-1.6/dojox/grid/_RowManager.xd.js75
-rw-r--r--js/dojo-1.6/dojox/grid/_RowSelector.js66
-rw-r--r--js/dojo-1.6/dojox/grid/_RowSelector.xd.js71
-rw-r--r--js/dojo-1.6/dojox/grid/_Scroller.js515
-rw-r--r--js/dojo-1.6/dojox/grid/_Scroller.xd.js519
-rw-r--r--js/dojo-1.6/dojox/grid/_Selector.js227
-rw-r--r--js/dojo-1.6/dojox/grid/_Selector.xd.js234
-rw-r--r--js/dojo-1.6/dojox/grid/_TreeView.js454
-rw-r--r--js/dojo-1.6/dojox/grid/_TreeView.xd.js461
-rw-r--r--js/dojo-1.6/dojox/grid/_View.js844
-rw-r--r--js/dojo-1.6/dojox/grid/_View.xd.js855
-rw-r--r--js/dojo-1.6/dojox/grid/_ViewManager.js313
-rw-r--r--js/dojo-1.6/dojox/grid/_ViewManager.xd.js317
-rw-r--r--js/dojo-1.6/dojox/grid/cells.js13
-rw-r--r--js/dojo-1.6/dojox/grid/cells.xd.js18
-rw-r--r--js/dojo-1.6/dojox/grid/cells/_base.js464
-rw-r--r--js/dojo-1.6/dojox/grid/cells/_base.xd.js470
-rw-r--r--js/dojo-1.6/dojox/grid/cells/dijit.js249
-rw-r--r--js/dojo-1.6/dojox/grid/cells/dijit.xd.js265
-rw-r--r--js/dojo-1.6/dojox/grid/cells/tree.js78
-rw-r--r--js/dojo-1.6/dojox/grid/cells/tree.xd.js83
-rw-r--r--js/dojo-1.6/dojox/grid/compatGrid.tar.gzbin0 -> 216813 bytes
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/_Events.js223
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/_Events.xd.js227
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/_FocusManager.js784
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/_FocusManager.xd.js788
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/_Plugin.js174
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/_Plugin.xd.js179
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/_PluginManager.js275
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/_PluginManager.xd.js281
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ar/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ar/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ar/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ar/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ar/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ar/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ca/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ca/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ca/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ca/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ca/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ca/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/cs/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/cs/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/cs/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/cs/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/cs/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/cs/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/da/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/da/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/da/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/da/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/da/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/da/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/de/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/de/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/de/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/de/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/de/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/de/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/el/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/el/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/el/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/el/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/el/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/el/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/es/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/es/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/es/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/es/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/es/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/es/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/fi/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/fi/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/fi/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/fi/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/fi/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/fi/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/fr/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/fr/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/fr/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/fr/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/fr/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/fr/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/he/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/he/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/he/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/he/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/he/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/he/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/hu/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/hu/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/hu/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/hu/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/hu/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/hu/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/it/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/it/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/it/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/it/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/it/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/it/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ja/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ja/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ja/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ja/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ja/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ja/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/kk/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/kk/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/kk/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/kk/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/kk/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/kk/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ko/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ko/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ko/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ko/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ko/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ko/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/nb/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/nb/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/nb/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/nb/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/nb/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/nb/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/nl/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/nl/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/nl/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/nl/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/nl/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/nl/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pl/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pl/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pl/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pl/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pl/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pl/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pt/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pt/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pt/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pt/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pt/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/pt/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ro/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ro/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ru/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ru/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ru/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ru/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ru/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/ru/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/sk/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/sk/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/sl/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/sl/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/sl/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/sl/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/sl/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/sl/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/sv/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/sv/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/sv/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/sv/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/sv/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/sv/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/th/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/th/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/th/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/th/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/th/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/th/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/tr/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/tr/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/tr/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/tr/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/tr/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/tr/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/zh/EnhancedGrid.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/zh/EnhancedGrid.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/zh/Filter.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/zh/Filter.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/zh/Pagination.js1
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/nls/zh/Pagination.xd.js5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/AutoScroll.js182
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/AutoScroll.xd.js188
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/CellMerge.js277
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/CellMerge.xd.js282
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Cookie.js356
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Cookie.xd.js364
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Dialog.js45
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Dialog.xd.js51
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/DnD.js1085
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/DnD.xd.js1094
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Exporter.js242
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Exporter.xd.js248
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Filter.js171
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Filter.xd.js183
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/GridSource.js159
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/GridSource.xd.js165
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/IndirectSelection.js616
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/IndirectSelection.xd.js623
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Menu.js131
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Menu.xd.js136
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/NestedSorting.js579
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/NestedSorting.xd.js584
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Pagination.js1235
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Pagination.xd.js1245
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Printer.js269
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Printer.xd.js275
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Rearrange.js492
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Rearrange.xd.js498
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Search.js120
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Search.xd.js126
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Selector.js1456
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/Selector.xd.js1463
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/_RowMapLayer.js215
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/_RowMapLayer.xd.js220
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/_SelectionPreserver.js138
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/_SelectionPreserver.xd.js142
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/_StoreLayer.js394
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/_StoreLayer.xd.js398
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/CSVWriter.js90
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/CSVWriter.xd.js95
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/TableWriter.js156
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/TableWriter.xd.js161
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js278
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/_ExportWriter.xd.js283
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js44
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.xd.js49
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterBar.js380
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterBar.xd.js387
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterBuilder.js89
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterBuilder.xd.js94
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js1236
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterDefDialog.xd.js1260
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterLayer.js415
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterLayer.xd.js421
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js150
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterStatusTip.xd.js160
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js226
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_ConditionExpr.xd.js230
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_DataExprs.js89
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_DataExprs.xd.js95
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_FilterExpr.js239
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_FilterExpr.xd.js245
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/Common.css36
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/Common_rtl.css15
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/DnD.css78
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/DnD_rtl.css12
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/EnhancedGrid.css8
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css6
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/Filter.css292
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/Filter_rtl.css78
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/Pagination.css138
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/Pagination_rtl.css52
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/Sorter.css170
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/Sorter_rtl.css78
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/claro/Common.css99
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/claro/EnhancedGrid.css4
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/claro/Filter.css59
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/images/sprite_icons.pngbin0 -> 2836 bytes
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/tundra/Common.css40
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/tundra/EnhancedGrid.css5
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/tundra/Filter.css38
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/resources/tundra/Sorter.css83
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/templates/ClearFilterConfirmPane.html9
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/templates/CriteriaBox.html20
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/templates/FilterBar.html15
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/templates/FilterBoolValueBox.html11
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/templates/FilterDefPane.html27
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/templates/FilterStatusPane.html9
-rw-r--r--js/dojo-1.6/dojox/grid/enhanced/templates/Pagination.html13
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ROOT.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ROOT.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ar.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ar.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ca.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ca.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_cs.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_cs.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_da.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_da.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_de-de.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_de-de.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_de.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_de.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_el.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_el.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en-gb.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en-gb.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en-us.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en-us.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_es-es.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_es-es.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_es.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_es.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fi-fi.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fi-fi.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fi.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fi.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fr-fr.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fr-fr.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fr.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fr.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_he-il.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_he-il.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_he.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_he.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_hu.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_hu.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_it-it.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_it-it.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_it.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_it.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ja-jp.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ja-jp.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ja.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ja.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ko-kr.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ko-kr.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ko.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ko.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nb.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nb.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nl-nl.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nl-nl.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nl.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nl.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pl.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pl.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt-br.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt-br.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt-pt.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt-pt.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ru.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ru.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sk.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sk.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sl.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sl.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sv.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sv.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_th.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_th.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_tr.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_tr.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_xx.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_xx.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh-cn.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh-cn.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh-tw.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh-tw.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_ROOT.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_ROOT.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_ar.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_ar.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_ca.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_ca.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_cs.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_cs.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_da.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_da.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_de-de.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_de-de.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_de.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_de.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_el.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_el.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_en-gb.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_en-gb.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_en-us.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_en-us.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_en.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_en.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_es-es.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_es-es.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_es.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_es.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_fi-fi.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_fi-fi.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_fi.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_fi.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_fr-fr.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_fr-fr.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_fr.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_fr.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_he-il.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_he-il.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_he.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_he.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_hu.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_hu.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_it-it.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_it-it.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_it.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_it.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_ja-jp.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_ja-jp.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_ja.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_ja.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_ko-kr.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_ko-kr.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_ko.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_ko.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_nb.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_nb.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_nl-nl.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_nl-nl.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_nl.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_nl.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_pl.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_pl.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_pt-br.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_pt-br.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_pt-pt.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_pt-pt.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_pt.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_pt.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_ru.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_ru.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_sk.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_sk.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_sl.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_sl.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_sv.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_sv.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_th.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_th.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_tr.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_tr.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_xx.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_xx.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_zh-cn.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_zh-cn.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_zh-tw.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_zh-tw.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_zh.js1
-rw-r--r--js/dojo-1.6/dojox/grid/nls/DataGrid_zh.xd.js7
-rw-r--r--js/dojo-1.6/dojox/grid/resources/Expando.html5
-rw-r--r--js/dojo-1.6/dojox/grid/resources/Grid.css415
-rw-r--r--js/dojo-1.6/dojox/grid/resources/Grid_rtl.css15
-rw-r--r--js/dojo-1.6/dojox/grid/resources/View.html12
-rw-r--r--js/dojo-1.6/dojox/grid/resources/_Grid.html6
-rw-r--r--js/dojo-1.6/dojox/grid/resources/claroGrid.css283
-rw-r--r--js/dojo-1.6/dojox/grid/resources/images/grid_dx_gradient.gifbin0 -> 267 bytes
-rw-r--r--js/dojo-1.6/dojox/grid/resources/images/grid_sort_down.gifbin0 -> 49 bytes
-rw-r--r--js/dojo-1.6/dojox/grid/resources/images/grid_sort_up.gifbin0 -> 48 bytes
-rw-r--r--js/dojo-1.6/dojox/grid/resources/images/header.pngbin0 -> 3276 bytes
-rw-r--r--js/dojo-1.6/dojox/grid/resources/images/header_shadow.pngbin0 -> 197 bytes
-rw-r--r--js/dojo-1.6/dojox/grid/resources/images/row_back.pngbin0 -> 3077 bytes
-rw-r--r--js/dojo-1.6/dojox/grid/resources/images/tabEnabled_rotated.pngbin0 -> 94 bytes
-rw-r--r--js/dojo-1.6/dojox/grid/resources/images/tabHover_rotated.pngbin0 -> 106 bytes
-rw-r--r--js/dojo-1.6/dojox/grid/resources/images/td_button_down.pngbin0 -> 3105 bytes
-rw-r--r--js/dojo-1.6/dojox/grid/resources/nihiloGrid.css237
-rw-r--r--js/dojo-1.6/dojox/grid/resources/soriaGrid.css245
-rw-r--r--js/dojo-1.6/dojox/grid/resources/tundraGrid.css268
-rw-r--r--js/dojo-1.6/dojox/grid/util.js79
-rw-r--r--js/dojo-1.6/dojox/grid/util.xd.js83
519 files changed, 84877 insertions, 0 deletions
diff --git a/js/dojo-1.6/dojox/grid/DataGrid.js b/js/dojo-1.6/dojox/grid/DataGrid.js
new file mode 100644
index 0000000..74c39cf
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/DataGrid.js
@@ -0,0 +1,14 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+/*
+ This is an optimized version of Dojo, built for deployment and not for
+ development. To get sources and documentation, please visit:
+
+ http://dojotoolkit.org
+*/
+
+if(!dojo._hasResource["dojo.window"]){dojo._hasResource["dojo.window"]=true;dojo.provide("dojo.window");dojo.getObject("window",true,dojo);dojo.window.getBox=function(){var _1=(dojo.doc.compatMode=="BackCompat")?dojo.body():dojo.doc.documentElement;var _2=dojo._docScroll();return {w:_1.clientWidth,h:_1.clientHeight,l:_2.x,t:_2.y};};dojo.window.get=function(_3){if(dojo.isIE&&window!==document.parentWindow){_3.parentWindow.execScript("document._parentWindow = window;","Javascript");var _4=_3._parentWindow;_3._parentWindow=null;return _4;}return _3.parentWindow||_3.defaultView;};dojo.window.scrollIntoView=function(_5,_6){try{_5=dojo.byId(_5);var _7=_5.ownerDocument||dojo.doc,_8=_7.body||dojo.body(),_9=_7.documentElement||_8.parentNode,_a=dojo.isIE,_b=dojo.isWebKit;if((!(dojo.isMoz||_a||_b||dojo.isOpera)||_5==_8||_5==_9)&&(typeof _5.scrollIntoView!="undefined")){_5.scrollIntoView(false);return;}var _c=_7.compatMode=="BackCompat",_d=_c?_8:_9,_e=_b?_8:_d,_f=_d.clientWidth,_10=_d.clientHeight,rtl=!dojo._isBodyLtr(),_11=_6||dojo.position(_5),el=_5.parentNode,_12=function(el){return ((_a<=6||(_a&&_c))?false:(dojo.style(el,"position").toLowerCase()=="fixed"));};if(_12(_5)){return;}while(el){if(el==_8){el=_e;}var _13=dojo.position(el),_14=_12(el);if(el==_e){_13.w=_f;_13.h=_10;if(_e==_9&&_a&&rtl){_13.x+=_e.offsetWidth-_13.w;}if(_13.x<0||!_a){_13.x=0;}if(_13.y<0||!_a){_13.y=0;}}else{var pb=dojo._getPadBorderExtents(el);_13.w-=pb.w;_13.h-=pb.h;_13.x+=pb.l;_13.y+=pb.t;}if(el!=_e){var _15=el.clientWidth,_16=_13.w-_15;if(_15>0&&_16>0){_13.w=_15;if(_a&&rtl){_13.x+=_16;}}_15=el.clientHeight;_16=_13.h-_15;if(_15>0&&_16>0){_13.h=_15;}}if(_14){if(_13.y<0){_13.h+=_13.y;_13.y=0;}if(_13.x<0){_13.w+=_13.x;_13.x=0;}if(_13.y+_13.h>_10){_13.h=_10-_13.y;}if(_13.x+_13.w>_f){_13.w=_f-_13.x;}}var l=_11.x-_13.x,t=_11.y-Math.max(_13.y,0),r=l+_11.w-_13.w,bot=t+_11.h-_13.h;if(r*l>0){var s=Math[l<0?"max":"min"](l,r);_11.x+=el.scrollLeft;el.scrollLeft+=(_a>=8&&!_c&&rtl)?-s:s;_11.x-=el.scrollLeft;}if(bot*t>0){_11.y+=el.scrollTop;el.scrollTop+=Math[t<0?"max":"min"](t,bot);_11.y-=el.scrollTop;}el=(el!=_e)&&!_14&&el.parentNode;}}catch(error){console.error("scrollIntoView: "+error);_5.scrollIntoView(false);}};}if(!dojo._hasResource["dijit._base.manager"]){dojo._hasResource["dijit._base.manager"]=true;dojo.provide("dijit._base.manager");dojo.declare("dijit.WidgetSet",null,{constructor:function(){this._hash={};this.length=0;},add:function(_17){if(this._hash[_17.id]){throw new Error("Tried to register widget with id=="+_17.id+" but that id is already registered");}this._hash[_17.id]=_17;this.length++;},remove:function(id){if(this._hash[id]){delete this._hash[id];this.length--;}},forEach:function(_18,_19){_19=_19||dojo.global;var i=0,id;for(id in this._hash){_18.call(_19,this._hash[id],i++,this._hash);}return this;},filter:function(_1a,_1b){_1b=_1b||dojo.global;var res=new dijit.WidgetSet(),i=0,id;for(id in this._hash){var w=this._hash[id];if(_1a.call(_1b,w,i++,this._hash)){res.add(w);}}return res;},byId:function(id){return this._hash[id];},byClass:function(cls){var res=new dijit.WidgetSet(),id,_1c;for(id in this._hash){_1c=this._hash[id];if(_1c.declaredClass==cls){res.add(_1c);}}return res;},toArray:function(){var ar=[];for(var id in this._hash){ar.push(this._hash[id]);}return ar;},map:function(_1d,_1e){return dojo.map(this.toArray(),_1d,_1e);},every:function(_1f,_20){_20=_20||dojo.global;var x=0,i;for(i in this._hash){if(!_1f.call(_20,this._hash[i],x++,this._hash)){return false;}}return true;},some:function(_21,_22){_22=_22||dojo.global;var x=0,i;for(i in this._hash){if(_21.call(_22,this._hash[i],x++,this._hash)){return true;}}return false;}});(function(){dijit.registry=new dijit.WidgetSet();var _23=dijit.registry._hash,_24=dojo.attr,_25=dojo.hasAttr,_26=dojo.style;dijit.byId=function(id){return typeof id=="string"?_23[id]:id;};var _27={};dijit.getUniqueId=function(_28){var id;do{id=_28+"_"+(_28 in _27?++_27[_28]:_27[_28]=0);}while(_23[id]);return dijit._scopeName=="dijit"?id:dijit._scopeName+"_"+id;};dijit.findWidgets=function(_29){var _2a=[];function _2b(_2c){for(var _2d=_2c.firstChild;_2d;_2d=_2d.nextSibling){if(_2d.nodeType==1){var _2e=_2d.getAttribute("widgetId");if(_2e){var _2f=_23[_2e];if(_2f){_2a.push(_2f);}}else{_2b(_2d);}}}};_2b(_29);return _2a;};dijit._destroyAll=function(){dijit._curFocus=null;dijit._prevFocus=null;dijit._activeStack=[];dojo.forEach(dijit.findWidgets(dojo.body()),function(_30){if(!_30._destroyed){if(_30.destroyRecursive){_30.destroyRecursive();}else{if(_30.destroy){_30.destroy();}}}});};if(dojo.isIE){dojo.addOnWindowUnload(function(){dijit._destroyAll();});}dijit.byNode=function(_31){return _23[_31.getAttribute("widgetId")];};dijit.getEnclosingWidget=function(_32){while(_32){var id=_32.getAttribute&&_32.getAttribute("widgetId");if(id){return _23[id];}_32=_32.parentNode;}return null;};var _33=(dijit._isElementShown=function(_34){var s=_26(_34);return (s.visibility!="hidden")&&(s.visibility!="collapsed")&&(s.display!="none")&&(_24(_34,"type")!="hidden");});dijit.hasDefaultTabStop=function(_35){switch(_35.nodeName.toLowerCase()){case "a":return _25(_35,"href");case "area":case "button":case "input":case "object":case "select":case "textarea":return true;case "iframe":var _36;try{var _37=_35.contentDocument;if("designMode" in _37&&_37.designMode=="on"){return true;}_36=_37.body;}catch(e1){try{_36=_35.contentWindow.document.body;}catch(e2){return false;}}return _36.contentEditable=="true"||(_36.firstChild&&_36.firstChild.contentEditable=="true");default:return _35.contentEditable=="true";}};var _38=(dijit.isTabNavigable=function(_39){if(_24(_39,"disabled")){return false;}else{if(_25(_39,"tabIndex")){return _24(_39,"tabIndex")>=0;}else{return dijit.hasDefaultTabStop(_39);}}});dijit._getTabNavigable=function(_3a){var _3b,_3c,_3d,_3e,_3f,_40,_41={};function _42(_43){return _43&&_43.tagName.toLowerCase()=="input"&&_43.type&&_43.type.toLowerCase()=="radio"&&_43.name&&_43.name.toLowerCase();};var _44=function(_45){dojo.query("> *",_45).forEach(function(_46){if((dojo.isIE&&_46.scopeName!=="HTML")||!_33(_46)){return;}if(_38(_46)){var _47=_24(_46,"tabIndex");if(!_25(_46,"tabIndex")||_47==0){if(!_3b){_3b=_46;}_3c=_46;}else{if(_47>0){if(!_3d||_47<_3e){_3e=_47;_3d=_46;}if(!_3f||_47>=_40){_40=_47;_3f=_46;}}}var rn=_42(_46);if(dojo.attr(_46,"checked")&&rn){_41[rn]=_46;}}if(_46.nodeName.toUpperCase()!="SELECT"){_44(_46);}});};if(_33(_3a)){_44(_3a);}function rs(_48){return _41[_42(_48)]||_48;};return {first:rs(_3b),last:rs(_3c),lowest:rs(_3d),highest:rs(_3f)};};dijit.getFirstInTabbingOrder=function(_49){var _4a=dijit._getTabNavigable(dojo.byId(_49));return _4a.lowest?_4a.lowest:_4a.first;};dijit.getLastInTabbingOrder=function(_4b){var _4c=dijit._getTabNavigable(dojo.byId(_4b));return _4c.last?_4c.last:_4c.highest;};dijit.defaultDuration=dojo.config["defaultDuration"]||200;})();}if(!dojo._hasResource["dijit._base.focus"]){dojo._hasResource["dijit._base.focus"]=true;dojo.provide("dijit._base.focus");dojo.mixin(dijit,{_curFocus:null,_prevFocus:null,isCollapsed:function(){return dijit.getBookmark().isCollapsed;},getBookmark:function(){var bm,rg,tg,sel=dojo.doc.selection,cf=dijit._curFocus;if(dojo.global.getSelection){sel=dojo.global.getSelection();if(sel){if(sel.isCollapsed){tg=cf?cf.tagName:"";if(tg){tg=tg.toLowerCase();if(tg=="textarea"||(tg=="input"&&(!cf.type||cf.type.toLowerCase()=="text"))){sel={start:cf.selectionStart,end:cf.selectionEnd,node:cf,pRange:true};return {isCollapsed:(sel.end<=sel.start),mark:sel};}}bm={isCollapsed:true};}else{rg=sel.getRangeAt(0);bm={isCollapsed:false,mark:rg.cloneRange()};}}}else{if(sel){tg=cf?cf.tagName:"";tg=tg.toLowerCase();if(cf&&tg&&(tg=="button"||tg=="textarea"||tg=="input")){if(sel.type&&sel.type.toLowerCase()=="none"){return {isCollapsed:true,mark:null};}else{rg=sel.createRange();return {isCollapsed:rg.text&&rg.text.length?false:true,mark:{range:rg,pRange:true}};}}bm={};try{rg=sel.createRange();bm.isCollapsed=!(sel.type=="Text"?rg.htmlText.length:rg.length);}catch(e){bm.isCollapsed=true;return bm;}if(sel.type.toUpperCase()=="CONTROL"){if(rg.length){bm.mark=[];var i=0,len=rg.length;while(i<len){bm.mark.push(rg.item(i++));}}else{bm.isCollapsed=true;bm.mark=null;}}else{bm.mark=rg.getBookmark();}}else{console.warn("No idea how to store the current selection for this browser!");}}return bm;},moveToBookmark:function(_4d){var _4e=dojo.doc,_4f=_4d.mark;if(_4f){if(dojo.global.getSelection){var sel=dojo.global.getSelection();if(sel&&sel.removeAllRanges){if(_4f.pRange){var r=_4f;var n=r.node;n.selectionStart=r.start;n.selectionEnd=r.end;}else{sel.removeAllRanges();sel.addRange(_4f);}}else{console.warn("No idea how to restore selection for this browser!");}}else{if(_4e.selection&&_4f){var rg;if(_4f.pRange){rg=_4f.range;}else{if(dojo.isArray(_4f)){rg=_4e.body.createControlRange();dojo.forEach(_4f,function(n){rg.addElement(n);});}else{rg=_4e.body.createTextRange();rg.moveToBookmark(_4f);}}rg.select();}}}},getFocus:function(_50,_51){var _52=!dijit._curFocus||(_50&&dojo.isDescendant(dijit._curFocus,_50.domNode))?dijit._prevFocus:dijit._curFocus;return {node:_52,bookmark:(_52==dijit._curFocus)&&dojo.withGlobal(_51||dojo.global,dijit.getBookmark),openedForWindow:_51};},focus:function(_53){if(!_53){return;}var _54="node" in _53?_53.node:_53,_55=_53.bookmark,_56=_53.openedForWindow,_57=_55?_55.isCollapsed:false;if(_54){var _58=(_54.tagName.toLowerCase()=="iframe")?_54.contentWindow:_54;if(_58&&_58.focus){try{_58.focus();}catch(e){}}dijit._onFocusNode(_54);}if(_55&&dojo.withGlobal(_56||dojo.global,dijit.isCollapsed)&&!_57){if(_56){_56.focus();}try{dojo.withGlobal(_56||dojo.global,dijit.moveToBookmark,null,[_55]);}catch(e2){}}},_activeStack:[],registerIframe:function(_59){return dijit.registerWin(_59.contentWindow,_59);},unregisterIframe:function(_5a){dijit.unregisterWin(_5a);},registerWin:function(_5b,_5c){var _5d=function(evt){dijit._justMouseDowned=true;setTimeout(function(){dijit._justMouseDowned=false;},0);if(dojo.isIE&&evt&&evt.srcElement&&evt.srcElement.parentNode==null){return;}dijit._onTouchNode(_5c||evt.target||evt.srcElement,"mouse");};var doc=dojo.isIE?_5b.document.documentElement:_5b.document;if(doc){if(dojo.isIE){_5b.document.body.attachEvent("onmousedown",_5d);var _5e=function(evt){if(evt.srcElement.tagName.toLowerCase()!="#document"&&dijit.isTabNavigable(evt.srcElement)){dijit._onFocusNode(_5c||evt.srcElement);}else{dijit._onTouchNode(_5c||evt.srcElement);}};doc.attachEvent("onactivate",_5e);var _5f=function(evt){dijit._onBlurNode(_5c||evt.srcElement);};doc.attachEvent("ondeactivate",_5f);return function(){_5b.document.detachEvent("onmousedown",_5d);doc.detachEvent("onactivate",_5e);doc.detachEvent("ondeactivate",_5f);doc=null;};}else{doc.body.addEventListener("mousedown",_5d,true);var _60=function(evt){dijit._onFocusNode(_5c||evt.target);};doc.addEventListener("focus",_60,true);var _61=function(evt){dijit._onBlurNode(_5c||evt.target);};doc.addEventListener("blur",_61,true);return function(){doc.body.removeEventListener("mousedown",_5d,true);doc.removeEventListener("focus",_60,true);doc.removeEventListener("blur",_61,true);doc=null;};}}},unregisterWin:function(_62){_62&&_62();},_onBlurNode:function(_63){dijit._prevFocus=dijit._curFocus;dijit._curFocus=null;if(dijit._justMouseDowned){return;}if(dijit._clearActiveWidgetsTimer){clearTimeout(dijit._clearActiveWidgetsTimer);}dijit._clearActiveWidgetsTimer=setTimeout(function(){delete dijit._clearActiveWidgetsTimer;dijit._setStack([]);dijit._prevFocus=null;},100);},_onTouchNode:function(_64,by){if(dijit._clearActiveWidgetsTimer){clearTimeout(dijit._clearActiveWidgetsTimer);delete dijit._clearActiveWidgetsTimer;}var _65=[];try{while(_64){var _66=dojo.attr(_64,"dijitPopupParent");if(_66){_64=dijit.byId(_66).domNode;}else{if(_64.tagName&&_64.tagName.toLowerCase()=="body"){if(_64===dojo.body()){break;}_64=dojo.window.get(_64.ownerDocument).frameElement;}else{var id=_64.getAttribute&&_64.getAttribute("widgetId"),_67=id&&dijit.byId(id);if(_67&&!(by=="mouse"&&_67.get("disabled"))){_65.unshift(id);}_64=_64.parentNode;}}}}catch(e){}dijit._setStack(_65,by);},_onFocusNode:function(_68){if(!_68){return;}if(_68.nodeType==9){return;}dijit._onTouchNode(_68);if(_68==dijit._curFocus){return;}if(dijit._curFocus){dijit._prevFocus=dijit._curFocus;}dijit._curFocus=_68;dojo.publish("focusNode",[_68]);},_setStack:function(_69,by){var _6a=dijit._activeStack;dijit._activeStack=_69;for(var _6b=0;_6b<Math.min(_6a.length,_69.length);_6b++){if(_6a[_6b]!=_69[_6b]){break;}}var _6c;for(var i=_6a.length-1;i>=_6b;i--){_6c=dijit.byId(_6a[i]);if(_6c){_6c._focused=false;_6c.set("focused",false);_6c._hasBeenBlurred=true;if(_6c._onBlur){_6c._onBlur(by);}dojo.publish("widgetBlur",[_6c,by]);}}for(i=_6b;i<_69.length;i++){_6c=dijit.byId(_69[i]);if(_6c){_6c._focused=true;_6c.set("focused",true);if(_6c._onFocus){_6c._onFocus(by);}dojo.publish("widgetFocus",[_6c,by]);}}}});dojo.addOnLoad(function(){var _6d=dijit.registerWin(window);if(dojo.isIE){dojo.addOnWindowUnload(function(){dijit.unregisterWin(_6d);_6d=null;});}});}if(!dojo._hasResource["dojo.AdapterRegistry"]){dojo._hasResource["dojo.AdapterRegistry"]=true;dojo.provide("dojo.AdapterRegistry");dojo.AdapterRegistry=function(_6e){this.pairs=[];this.returnWrappers=_6e||false;};dojo.extend(dojo.AdapterRegistry,{register:function(_6f,_70,_71,_72,_73){this.pairs[((_73)?"unshift":"push")]([_6f,_70,_71,_72]);},match:function(){for(var i=0;i<this.pairs.length;i++){var _74=this.pairs[i];if(_74[1].apply(this,arguments)){if((_74[3])||(this.returnWrappers)){return _74[2];}else{return _74[2].apply(this,arguments);}}}throw new Error("No match found");},unregister:function(_75){for(var i=0;i<this.pairs.length;i++){var _76=this.pairs[i];if(_76[0]==_75){this.pairs.splice(i,1);return true;}}return false;}});}if(!dojo._hasResource["dijit._base.place"]){dojo._hasResource["dijit._base.place"]=true;dojo.provide("dijit._base.place");dijit.getViewport=function(){return dojo.window.getBox();};dijit.placeOnScreen=function(_77,pos,_78,_79){var _7a=dojo.map(_78,function(_7b){var c={corner:_7b,pos:{x:pos.x,y:pos.y}};if(_79){c.pos.x+=_7b.charAt(1)=="L"?_79.x:-_79.x;c.pos.y+=_7b.charAt(0)=="T"?_79.y:-_79.y;}return c;});return dijit._place(_77,_7a);};dijit._place=function(_7c,_7d,_7e,_7f){var _80=dojo.window.getBox();if(!_7c.parentNode||String(_7c.parentNode.tagName).toLowerCase()!="body"){dojo.body().appendChild(_7c);}var _81=null;dojo.some(_7d,function(_82){var _83=_82.corner;var pos=_82.pos;var _84=0;var _85={w:_83.charAt(1)=="L"?(_80.l+_80.w)-pos.x:pos.x-_80.l,h:_83.charAt(1)=="T"?(_80.t+_80.h)-pos.y:pos.y-_80.t};if(_7e){var res=_7e(_7c,_82.aroundCorner,_83,_85,_7f);_84=typeof res=="undefined"?0:res;}var _86=_7c.style;var _87=_86.display;var _88=_86.visibility;_86.visibility="hidden";_86.display="";var mb=dojo.marginBox(_7c);_86.display=_87;_86.visibility=_88;var _89=Math.max(_80.l,_83.charAt(1)=="L"?pos.x:(pos.x-mb.w)),_8a=Math.max(_80.t,_83.charAt(0)=="T"?pos.y:(pos.y-mb.h)),_8b=Math.min(_80.l+_80.w,_83.charAt(1)=="L"?(_89+mb.w):pos.x),_8c=Math.min(_80.t+_80.h,_83.charAt(0)=="T"?(_8a+mb.h):pos.y),_8d=_8b-_89,_8e=_8c-_8a;_84+=(mb.w-_8d)+(mb.h-_8e);if(_81==null||_84<_81.overflow){_81={corner:_83,aroundCorner:_82.aroundCorner,x:_89,y:_8a,w:_8d,h:_8e,overflow:_84,spaceAvailable:_85};}return !_84;});if(_81.overflow&&_7e){_7e(_7c,_81.aroundCorner,_81.corner,_81.spaceAvailable,_7f);}var l=dojo._isBodyLtr(),s=_7c.style;s.top=_81.y+"px";s[l?"left":"right"]=(l?_81.x:_80.w-_81.x-_81.w)+"px";return _81;};dijit.placeOnScreenAroundNode=function(_8f,_90,_91,_92){_90=dojo.byId(_90);var _93=dojo.position(_90,true);return dijit._placeOnScreenAroundRect(_8f,_93.x,_93.y,_93.w,_93.h,_91,_92);};dijit.placeOnScreenAroundRectangle=function(_94,_95,_96,_97){return dijit._placeOnScreenAroundRect(_94,_95.x,_95.y,_95.width,_95.height,_96,_97);};dijit._placeOnScreenAroundRect=function(_98,x,y,_99,_9a,_9b,_9c){var _9d=[];for(var _9e in _9b){_9d.push({aroundCorner:_9e,corner:_9b[_9e],pos:{x:x+(_9e.charAt(1)=="L"?0:_99),y:y+(_9e.charAt(0)=="T"?0:_9a)}});}return dijit._place(_98,_9d,_9c,{w:_99,h:_9a});};dijit.placementRegistry=new dojo.AdapterRegistry();dijit.placementRegistry.register("node",function(n,x){return typeof x=="object"&&typeof x.offsetWidth!="undefined"&&typeof x.offsetHeight!="undefined";},dijit.placeOnScreenAroundNode);dijit.placementRegistry.register("rect",function(n,x){return typeof x=="object"&&"x" in x&&"y" in x&&"width" in x&&"height" in x;},dijit.placeOnScreenAroundRectangle);dijit.placeOnScreenAroundElement=function(_9f,_a0,_a1,_a2){return dijit.placementRegistry.match.apply(dijit.placementRegistry,arguments);};dijit.getPopupAroundAlignment=function(_a3,_a4){var _a5={};dojo.forEach(_a3,function(pos){switch(pos){case "after":_a5[_a4?"BR":"BL"]=_a4?"BL":"BR";break;case "before":_a5[_a4?"BL":"BR"]=_a4?"BR":"BL";break;case "below-alt":_a4=!_a4;case "below":_a5[_a4?"BL":"BR"]=_a4?"TL":"TR";_a5[_a4?"BR":"BL"]=_a4?"TR":"TL";break;case "above-alt":_a4=!_a4;case "above":default:_a5[_a4?"TL":"TR"]=_a4?"BL":"BR";_a5[_a4?"TR":"TL"]=_a4?"BR":"BL";break;}});return _a5;};}if(!dojo._hasResource["dijit._base.window"]){dojo._hasResource["dijit._base.window"]=true;dojo.provide("dijit._base.window");dijit.getDocumentWindow=function(doc){return dojo.window.get(doc);};}if(!dojo._hasResource["dijit._base.popup"]){dojo._hasResource["dijit._base.popup"]=true;dojo.provide("dijit._base.popup");dijit.popup={_stack:[],_beginZIndex:1000,_idGen:1,_createWrapper:function(_a6){var _a7=_a6.declaredClass?_a6._popupWrapper:(dojo.hasClass(_a6.parentNode,"dijitPopup")&&_a6.parentNode),_a8=_a6.domNode||_a6;if(!_a7){_a7=dojo.create("div",{"class":"dijitPopup",style:{display:"none"},role:"presentation"},dojo.body());_a7.appendChild(_a8);var s=_a8.style;s.display="";s.visibility="";s.position="";s.top="0px";if(_a6.declaredClass){_a6._popupWrapper=_a7;dojo.connect(_a6,"destroy",function(){dojo.destroy(_a7);delete _a6._popupWrapper;});}}return _a7;},moveOffScreen:function(_a9){var _aa=this._createWrapper(_a9);dojo.style(_aa,{visibility:"hidden",top:"-9999px",display:""});},hide:function(_ab){var _ac=this._createWrapper(_ab);dojo.style(_ac,"display","none");},getTopPopup:function(){var _ad=this._stack;for(var pi=_ad.length-1;pi>0&&_ad[pi].parent===_ad[pi-1].widget;pi--){}return _ad[pi];},open:function(_ae){var _af=this._stack,_b0=_ae.popup,_b1=_ae.orient||((_ae.parent?_ae.parent.isLeftToRight():dojo._isBodyLtr())?{"BL":"TL","BR":"TR","TL":"BL","TR":"BR"}:{"BR":"TR","BL":"TL","TR":"BR","TL":"BL"}),_b2=_ae.around,id=(_ae.around&&_ae.around.id)?(_ae.around.id+"_dropdown"):("popup_"+this._idGen++);while(_af.length&&(!_ae.parent||!dojo.isDescendant(_ae.parent.domNode,_af[_af.length-1].widget.domNode))){dijit.popup.close(_af[_af.length-1].widget);}var _b3=this._createWrapper(_b0);dojo.attr(_b3,{id:id,style:{zIndex:this._beginZIndex+_af.length},"class":"dijitPopup "+(_b0.baseClass||_b0["class"]||"").split(" ")[0]+"Popup",dijitPopupParent:_ae.parent?_ae.parent.id:""});if(dojo.isIE||dojo.isMoz){if(!_b0.bgIframe){_b0.bgIframe=new dijit.BackgroundIframe(_b3);}}var _b4=_b2?dijit.placeOnScreenAroundElement(_b3,_b2,_b1,_b0.orient?dojo.hitch(_b0,"orient"):null):dijit.placeOnScreen(_b3,_ae,_b1=="R"?["TR","BR","TL","BL"]:["TL","BL","TR","BR"],_ae.padding);_b3.style.display="";_b3.style.visibility="visible";_b0.domNode.style.visibility="visible";var _b5=[];_b5.push(dojo.connect(_b3,"onkeypress",this,function(evt){if(evt.charOrCode==dojo.keys.ESCAPE&&_ae.onCancel){dojo.stopEvent(evt);_ae.onCancel();}else{if(evt.charOrCode===dojo.keys.TAB){dojo.stopEvent(evt);var _b6=this.getTopPopup();if(_b6&&_b6.onCancel){_b6.onCancel();}}}}));if(_b0.onCancel){_b5.push(dojo.connect(_b0,"onCancel",_ae.onCancel));}_b5.push(dojo.connect(_b0,_b0.onExecute?"onExecute":"onChange",this,function(){var _b7=this.getTopPopup();if(_b7&&_b7.onExecute){_b7.onExecute();}}));_af.push({widget:_b0,parent:_ae.parent,onExecute:_ae.onExecute,onCancel:_ae.onCancel,onClose:_ae.onClose,handlers:_b5});if(_b0.onOpen){_b0.onOpen(_b4);}return _b4;},close:function(_b8){var _b9=this._stack;while((_b8&&dojo.some(_b9,function(_ba){return _ba.widget==_b8;}))||(!_b8&&_b9.length)){var top=_b9.pop(),_bb=top.widget,_bc=top.onClose;if(_bb.onClose){_bb.onClose();}dojo.forEach(top.handlers,dojo.disconnect);if(_bb&&_bb.domNode){this.hide(_bb);}if(_bc){_bc();}}}};dijit._frames=new function(){var _bd=[];this.pop=function(){var _be;if(_bd.length){_be=_bd.pop();_be.style.display="";}else{if(dojo.isIE<9){var _bf=dojo.config["dojoBlankHtmlUrl"]||(dojo.moduleUrl("dojo","resources/blank.html")+"")||"javascript:\"\"";var _c0="<iframe src='"+_bf+"'"+" style='position: absolute; left: 0px; top: 0px;"+"z-index: -1; filter:Alpha(Opacity=\"0\");'>";_be=dojo.doc.createElement(_c0);}else{_be=dojo.create("iframe");_be.src="javascript:\"\"";_be.className="dijitBackgroundIframe";dojo.style(_be,"opacity",0.1);}_be.tabIndex=-1;dijit.setWaiRole(_be,"presentation");}return _be;};this.push=function(_c1){_c1.style.display="none";_bd.push(_c1);};}();dijit.BackgroundIframe=function(_c2){if(!_c2.id){throw new Error("no id");}if(dojo.isIE||dojo.isMoz){var _c3=(this.iframe=dijit._frames.pop());_c2.appendChild(_c3);if(dojo.isIE<7||dojo.isQuirks){this.resize(_c2);this._conn=dojo.connect(_c2,"onresize",this,function(){this.resize(_c2);});}else{dojo.style(_c3,{width:"100%",height:"100%"});}}};dojo.extend(dijit.BackgroundIframe,{resize:function(_c4){if(this.iframe){dojo.style(this.iframe,{width:_c4.offsetWidth+"px",height:_c4.offsetHeight+"px"});}},destroy:function(){if(this._conn){dojo.disconnect(this._conn);this._conn=null;}if(this.iframe){dijit._frames.push(this.iframe);delete this.iframe;}}});}if(!dojo._hasResource["dijit._base.scroll"]){dojo._hasResource["dijit._base.scroll"]=true;dojo.provide("dijit._base.scroll");dijit.scrollIntoView=function(_c5,pos){dojo.window.scrollIntoView(_c5,pos);};}if(!dojo._hasResource["dojo.uacss"]){dojo._hasResource["dojo.uacss"]=true;dojo.provide("dojo.uacss");(function(){var d=dojo,_c6=d.doc.documentElement,ie=d.isIE,_c7=d.isOpera,maj=Math.floor,ff=d.isFF,_c8=d.boxModel.replace(/-/,""),_c9={dj_ie:ie,dj_ie6:maj(ie)==6,dj_ie7:maj(ie)==7,dj_ie8:maj(ie)==8,dj_ie9:maj(ie)==9,dj_quirks:d.isQuirks,dj_iequirks:ie&&d.isQuirks,dj_opera:_c7,dj_khtml:d.isKhtml,dj_webkit:d.isWebKit,dj_safari:d.isSafari,dj_chrome:d.isChrome,dj_gecko:d.isMozilla,dj_ff3:maj(ff)==3};_c9["dj_"+_c8]=true;var _ca="";for(var clz in _c9){if(_c9[clz]){_ca+=clz+" ";}}_c6.className=d.trim(_c6.className+" "+_ca);dojo._loaders.unshift(function(){if(!dojo._isBodyLtr()){var _cb="dj_rtl dijitRtl "+_ca.replace(/ /g,"-rtl ");_c6.className=d.trim(_c6.className+" "+_cb);}});})();}if(!dojo._hasResource["dijit._base.sniff"]){dojo._hasResource["dijit._base.sniff"]=true;dojo.provide("dijit._base.sniff");}if(!dojo._hasResource["dijit._base.typematic"]){dojo._hasResource["dijit._base.typematic"]=true;dojo.provide("dijit._base.typematic");dijit.typematic={_fireEventAndReload:function(){this._timer=null;this._callback(++this._count,this._node,this._evt);this._currentTimeout=Math.max(this._currentTimeout<0?this._initialDelay:(this._subsequentDelay>1?this._subsequentDelay:Math.round(this._currentTimeout*this._subsequentDelay)),this._minDelay);this._timer=setTimeout(dojo.hitch(this,"_fireEventAndReload"),this._currentTimeout);},trigger:function(evt,_cc,_cd,_ce,obj,_cf,_d0,_d1){if(obj!=this._obj){this.stop();this._initialDelay=_d0||500;this._subsequentDelay=_cf||0.9;this._minDelay=_d1||10;this._obj=obj;this._evt=evt;this._node=_cd;this._currentTimeout=-1;this._count=-1;this._callback=dojo.hitch(_cc,_ce);this._fireEventAndReload();this._evt=dojo.mixin({faux:true},evt);}},stop:function(){if(this._timer){clearTimeout(this._timer);this._timer=null;}if(this._obj){this._callback(-1,this._node,this._evt);this._obj=null;}},addKeyListener:function(_d2,_d3,_d4,_d5,_d6,_d7,_d8){if(_d3.keyCode){_d3.charOrCode=_d3.keyCode;dojo.deprecated("keyCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.","","2.0");}else{if(_d3.charCode){_d3.charOrCode=String.fromCharCode(_d3.charCode);dojo.deprecated("charCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.","","2.0");}}return [dojo.connect(_d2,"onkeypress",this,function(evt){if(evt.charOrCode==_d3.charOrCode&&(_d3.ctrlKey===undefined||_d3.ctrlKey==evt.ctrlKey)&&(_d3.altKey===undefined||_d3.altKey==evt.altKey)&&(_d3.metaKey===undefined||_d3.metaKey==(evt.metaKey||false))&&(_d3.shiftKey===undefined||_d3.shiftKey==evt.shiftKey)){dojo.stopEvent(evt);dijit.typematic.trigger(evt,_d4,_d2,_d5,_d3,_d6,_d7,_d8);}else{if(dijit.typematic._obj==_d3){dijit.typematic.stop();}}}),dojo.connect(_d2,"onkeyup",this,function(evt){if(dijit.typematic._obj==_d3){dijit.typematic.stop();}})];},addMouseListener:function(_d9,_da,_db,_dc,_dd,_de){var dc=dojo.connect;return [dc(_d9,"mousedown",this,function(evt){dojo.stopEvent(evt);dijit.typematic.trigger(evt,_da,_d9,_db,_d9,_dc,_dd,_de);}),dc(_d9,"mouseup",this,function(evt){dojo.stopEvent(evt);dijit.typematic.stop();}),dc(_d9,"mouseout",this,function(evt){dojo.stopEvent(evt);dijit.typematic.stop();}),dc(_d9,"mousemove",this,function(evt){evt.preventDefault();}),dc(_d9,"dblclick",this,function(evt){dojo.stopEvent(evt);if(dojo.isIE){dijit.typematic.trigger(evt,_da,_d9,_db,_d9,_dc,_dd,_de);setTimeout(dojo.hitch(this,dijit.typematic.stop),50);}})];},addListener:function(_df,_e0,_e1,_e2,_e3,_e4,_e5,_e6){return this.addKeyListener(_e0,_e1,_e2,_e3,_e4,_e5,_e6).concat(this.addMouseListener(_df,_e2,_e3,_e4,_e5,_e6));}};}if(!dojo._hasResource["dijit._base.wai"]){dojo._hasResource["dijit._base.wai"]=true;dojo.provide("dijit._base.wai");dijit.wai={onload:function(){var div=dojo.create("div",{id:"a11yTestNode",style:{cssText:"border: 1px solid;"+"border-color:red green;"+"position: absolute;"+"height: 5px;"+"top: -999px;"+"background-image: url(\""+(dojo.config.blankGif||dojo.moduleUrl("dojo","resources/blank.gif"))+"\");"}},dojo.body());var cs=dojo.getComputedStyle(div);if(cs){var _e7=cs.backgroundImage;var _e8=(cs.borderTopColor==cs.borderRightColor)||(_e7!=null&&(_e7=="none"||_e7=="url(invalid-url:)"));dojo[_e8?"addClass":"removeClass"](dojo.body(),"dijit_a11y");if(dojo.isIE){div.outerHTML="";}else{dojo.body().removeChild(div);}}}};if(dojo.isIE||dojo.isMoz){dojo._loaders.unshift(dijit.wai.onload);}dojo.mixin(dijit,{hasWaiRole:function(_e9,_ea){var _eb=this.getWaiRole(_e9);return _ea?(_eb.indexOf(_ea)>-1):(_eb.length>0);},getWaiRole:function(_ec){return dojo.trim((dojo.attr(_ec,"role")||"").replace("wairole:",""));},setWaiRole:function(_ed,_ee){dojo.attr(_ed,"role",_ee);},removeWaiRole:function(_ef,_f0){var _f1=dojo.attr(_ef,"role");if(!_f1){return;}if(_f0){var t=dojo.trim((" "+_f1+" ").replace(" "+_f0+" "," "));dojo.attr(_ef,"role",t);}else{_ef.removeAttribute("role");}},hasWaiState:function(_f2,_f3){return _f2.hasAttribute?_f2.hasAttribute("aria-"+_f3):!!_f2.getAttribute("aria-"+_f3);},getWaiState:function(_f4,_f5){return _f4.getAttribute("aria-"+_f5)||"";},setWaiState:function(_f6,_f7,_f8){_f6.setAttribute("aria-"+_f7,_f8);},removeWaiState:function(_f9,_fa){_f9.removeAttribute("aria-"+_fa);}});}if(!dojo._hasResource["dijit._base"]){dojo._hasResource["dijit._base"]=true;dojo.provide("dijit._base");}if(!dojo._hasResource["dojo.date.stamp"]){dojo._hasResource["dojo.date.stamp"]=true;dojo.provide("dojo.date.stamp");dojo.getObject("date.stamp",true,dojo);dojo.date.stamp.fromISOString=function(_fb,_fc){if(!dojo.date.stamp._isoRegExp){dojo.date.stamp._isoRegExp=/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(.\d+)?)?((?:[+-](\d{2}):(\d{2}))|Z)?)?$/;}var _fd=dojo.date.stamp._isoRegExp.exec(_fb),_fe=null;if(_fd){_fd.shift();if(_fd[1]){_fd[1]--;}if(_fd[6]){_fd[6]*=1000;}if(_fc){_fc=new Date(_fc);dojo.forEach(dojo.map(["FullYear","Month","Date","Hours","Minutes","Seconds","Milliseconds"],function(_ff){return _fc["get"+_ff]();}),function(_100,_101){_fd[_101]=_fd[_101]||_100;});}_fe=new Date(_fd[0]||1970,_fd[1]||0,_fd[2]||1,_fd[3]||0,_fd[4]||0,_fd[5]||0,_fd[6]||0);if(_fd[0]<100){_fe.setFullYear(_fd[0]||1970);}var _102=0,_103=_fd[7]&&_fd[7].charAt(0);if(_103!="Z"){_102=((_fd[8]||0)*60)+(Number(_fd[9])||0);if(_103!="-"){_102*=-1;}}if(_103){_102-=_fe.getTimezoneOffset();}if(_102){_fe.setTime(_fe.getTime()+_102*60000);}}return _fe;};dojo.date.stamp.toISOString=function(_104,_105){var _106=function(n){return (n<10)?"0"+n:n;};_105=_105||{};var _107=[],_108=_105.zulu?"getUTC":"get",date="";if(_105.selector!="time"){var year=_104[_108+"FullYear"]();date=["0000".substr((year+"").length)+year,_106(_104[_108+"Month"]()+1),_106(_104[_108+"Date"]())].join("-");}_107.push(date);if(_105.selector!="date"){var time=[_106(_104[_108+"Hours"]()),_106(_104[_108+"Minutes"]()),_106(_104[_108+"Seconds"]())].join(":");var _109=_104[_108+"Milliseconds"]();if(_105.milliseconds){time+="."+(_109<100?"0":"")+_106(_109);}if(_105.zulu){time+="Z";}else{if(_105.selector!="time"){var _10a=_104.getTimezoneOffset();var _10b=Math.abs(_10a);time+=(_10a>0?"-":"+")+_106(Math.floor(_10b/60))+":"+_106(_10b%60);}}_107.push(time);}return _107.join("T");};}if(!dojo._hasResource["dojo.parser"]){dojo._hasResource["dojo.parser"]=true;dojo.provide("dojo.parser");new Date("X");dojo.parser=new function(){var d=dojo;function _10c(_10d){if(d.isString(_10d)){return "string";}if(typeof _10d=="number"){return "number";}if(typeof _10d=="boolean"){return "boolean";}if(d.isFunction(_10d)){return "function";}if(d.isArray(_10d)){return "array";}if(_10d instanceof Date){return "date";}if(_10d instanceof d._Url){return "url";}return "object";};function _10e(_10f,type){switch(type){case "string":return _10f;case "number":return _10f.length?Number(_10f):NaN;case "boolean":return typeof _10f=="boolean"?_10f:!(_10f.toLowerCase()=="false");case "function":if(d.isFunction(_10f)){_10f=_10f.toString();_10f=d.trim(_10f.substring(_10f.indexOf("{")+1,_10f.length-1));}try{if(_10f===""||_10f.search(/[^\w\.]+/i)!=-1){return new Function(_10f);}else{return d.getObject(_10f,false)||new Function(_10f);}}catch(e){return new Function();}case "array":return _10f?_10f.split(/\s*,\s*/):[];case "date":switch(_10f){case "":return new Date("");case "now":return new Date();default:return d.date.stamp.fromISOString(_10f);}case "url":return d.baseUrl+_10f;default:return d.fromJson(_10f);}};var _110={},_111={};d.connect(d,"extend",function(){_111={};});function _112(cls,_113){for(var name in cls){if(name.charAt(0)=="_"){continue;}if(name in _110){continue;}_113[name]=_10c(cls[name]);}return _113;};function _114(_115,_116){var c=_111[_115];if(!c){var cls=d.getObject(_115),_117=null;if(!cls){return null;}if(!_116){_117=_112(cls.prototype,{});}c={cls:cls,params:_117};}else{if(!_116&&!c.params){c.params=_112(c.cls.prototype,{});}}return c;};this._functionFromScript=function(_118,_119){var _11a="";var _11b="";var _11c=(_118.getAttribute(_119+"args")||_118.getAttribute("args"));if(_11c){d.forEach(_11c.split(/\s*,\s*/),function(part,idx){_11a+="var "+part+" = arguments["+idx+"]; ";});}var _11d=_118.getAttribute("with");if(_11d&&_11d.length){d.forEach(_11d.split(/\s*,\s*/),function(part){_11a+="with("+part+"){";_11b+="}";});}return new Function(_11a+_118.innerHTML+_11b);};this.instantiate=function(_11e,_11f,args){var _120=[],_11f=_11f||{};args=args||{};var _121=(args.scope||d._scopeName)+"Type",_122="data-"+(args.scope||d._scopeName)+"-";d.forEach(_11e,function(obj){if(!obj){return;}var node,type,_123,_124,_125,_126;if(obj.node){node=obj.node;type=obj.type;_126=obj.fastpath;_123=obj.clsInfo||(type&&_114(type,_126));_124=_123&&_123.cls;_125=obj.scripts;}else{node=obj;type=_121 in _11f?_11f[_121]:node.getAttribute(_121);_123=type&&_114(type);_124=_123&&_123.cls;_125=(_124&&(_124._noScript||_124.prototype._noScript)?[]:d.query("> script[type^='dojo/']",node));}if(!_123){throw new Error("Could not load class '"+type);}var _127={};if(args.defaults){d._mixin(_127,args.defaults);}if(obj.inherited){d._mixin(_127,obj.inherited);}if(_126){var _128=node.getAttribute(_122+"props");if(_128&&_128.length){try{_128=d.fromJson.call(args.propsThis,"{"+_128+"}");d._mixin(_127,_128);}catch(e){throw new Error(e.toString()+" in data-dojo-props='"+_128+"'");}}var _129=node.getAttribute(_122+"attach-point");if(_129){_127.dojoAttachPoint=_129;}var _12a=node.getAttribute(_122+"attach-event");if(_12a){_127.dojoAttachEvent=_12a;}dojo.mixin(_127,_11f);}else{var _12b=node.attributes;for(var name in _123.params){var item=name in _11f?{value:_11f[name],specified:true}:_12b.getNamedItem(name);if(!item||(!item.specified&&(!dojo.isIE||name.toLowerCase()!="value"))){continue;}var _12c=item.value;switch(name){case "class":_12c="className" in _11f?_11f.className:node.className;break;case "style":_12c="style" in _11f?_11f.style:(node.style&&node.style.cssText);}var _12d=_123.params[name];if(typeof _12c=="string"){_127[name]=_10e(_12c,_12d);}else{_127[name]=_12c;}}}var _12e=[],_12f=[];d.forEach(_125,function(_130){node.removeChild(_130);var _131=(_130.getAttribute(_122+"event")||_130.getAttribute("event")),type=_130.getAttribute("type"),nf=d.parser._functionFromScript(_130,_122);if(_131){if(type=="dojo/connect"){_12e.push({event:_131,func:nf});}else{_127[_131]=nf;}}else{_12f.push(nf);}});var _132=_124.markupFactory||_124.prototype&&_124.prototype.markupFactory;var _133=_132?_132(_127,node,_124):new _124(_127,node);_120.push(_133);var _134=(node.getAttribute(_122+"id")||node.getAttribute("jsId"));if(_134){d.setObject(_134,_133);}d.forEach(_12e,function(_135){d.connect(_133,_135.event,null,_135.func);});d.forEach(_12f,function(func){func.call(_133);});});if(!_11f._started){d.forEach(_120,function(_136){if(!args.noStart&&_136&&dojo.isFunction(_136.startup)&&!_136._started&&(!_136.getParent||!_136.getParent())){_136.startup();}});}return _120;};this.parse=function(_137,args){var root;if(!args&&_137&&_137.rootNode){args=_137;root=args.rootNode;}else{root=_137;}args=args||{};var _138=(args.scope||d._scopeName)+"Type",_139="data-"+(args.scope||d._scopeName)+"-";function scan(_13a,list){var _13b=dojo.clone(_13a.inherited);dojo.forEach(["dir","lang"],function(name){var val=_13a.node.getAttribute(name);if(val){_13b[name]=val;}});var _13c=_13a.clsInfo&&!_13a.clsInfo.cls.prototype._noScript?_13a.scripts:null;var _13d=(!_13a.clsInfo||!_13a.clsInfo.cls.prototype.stopParser)||(args&&args.template);for(var _13e=_13a.node.firstChild;_13e;_13e=_13e.nextSibling){if(_13e.nodeType==1){var type,_13f=_13d&&_13e.getAttribute(_139+"type");if(_13f){type=_13f;}else{type=_13d&&_13e.getAttribute(_138);}var _140=_13f==type;if(type){var _141={"type":type,fastpath:_140,clsInfo:_114(type,_140),node:_13e,scripts:[],inherited:_13b};list.push(_141);scan(_141,list);}else{if(_13c&&_13e.nodeName.toLowerCase()=="script"){type=_13e.getAttribute("type");if(type&&/^dojo\/\w/i.test(type)){_13c.push(_13e);}}else{if(_13d){scan({node:_13e,inherited:_13b},list);}}}}}};var list=[];scan({node:root?dojo.byId(root):dojo.body(),inherited:(args&&args.inherited)||{dir:dojo._isBodyLtr()?"ltr":"rtl"}},list);var _142=args&&args.template?{template:true}:null;return this.instantiate(list,_142,args);};}();(function(){var _143=function(){if(dojo.config.parseOnLoad){dojo.parser.parse();}};if(dojo.getObject("dijit.wai.onload")===dojo._loaders[0]){dojo._loaders.splice(1,0,_143);}else{dojo._loaders.unshift(_143);}})();}if(!dojo._hasResource["dojo.Stateful"]){dojo._hasResource["dojo.Stateful"]=true;dojo.provide("dojo.Stateful");dojo.declare("dojo.Stateful",null,{postscript:function(_144){if(_144){dojo.mixin(this,_144);}},get:function(name){return this[name];},set:function(name,_145){if(typeof name==="object"){for(var x in name){this.set(x,name[x]);}return this;}var _146=this[name];this[name]=_145;if(this._watchCallbacks){this._watchCallbacks(name,_146,_145);}return this;},watch:function(name,_147){var _148=this._watchCallbacks;if(!_148){var self=this;_148=this._watchCallbacks=function(name,_149,_14a,_14b){var _14c=function(_14d){if(_14d){_14d=_14d.slice();for(var i=0,l=_14d.length;i<l;i++){try{_14d[i].call(self,name,_149,_14a);}catch(e){console.error(e);}}}};_14c(_148["_"+name]);if(!_14b){_14c(_148["*"]);}};}if(!_147&&typeof name==="function"){_147=name;name="*";}else{name="_"+name;}var _14e=_148[name];if(typeof _14e!=="object"){_14e=_148[name]=[];}_14e.push(_147);return {unwatch:function(){_14e.splice(dojo.indexOf(_14e,_147),1);}};}});}if(!dojo._hasResource["dijit._WidgetBase"]){dojo._hasResource["dijit._WidgetBase"]=true;dojo.provide("dijit._WidgetBase");(function(){dojo.declare("dijit._WidgetBase",dojo.Stateful,{id:"",lang:"",dir:"","class":"",style:"",title:"",tooltip:"",baseClass:"",srcNodeRef:null,domNode:null,containerNode:null,attributeMap:{id:"",dir:"",lang:"","class":"",style:"",title:""},_blankGif:(dojo.config.blankGif||dojo.moduleUrl("dojo","resources/blank.gif")).toString(),postscript:function(_14f,_150){this.create(_14f,_150);},create:function(_151,_152){this.srcNodeRef=dojo.byId(_152);this._connects=[];this._subscribes=[];if(this.srcNodeRef&&(typeof this.srcNodeRef.id=="string")){this.id=this.srcNodeRef.id;}if(_151){this.params=_151;dojo._mixin(this,_151);}this.postMixInProperties();if(!this.id){this.id=dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));}dijit.registry.add(this);this.buildRendering();if(this.domNode){this._applyAttributes();var _153=this.srcNodeRef;if(_153&&_153.parentNode&&this.domNode!==_153){_153.parentNode.replaceChild(this.domNode,_153);}}if(this.domNode){this.domNode.setAttribute("widgetId",this.id);}this.postCreate();if(this.srcNodeRef&&!this.srcNodeRef.parentNode){delete this.srcNodeRef;}this._created=true;},_applyAttributes:function(){var _154=function(attr,_155){if((_155.params&&attr in _155.params)||_155[attr]){_155.set(attr,_155[attr]);}};for(var attr in this.attributeMap){_154(attr,this);}dojo.forEach(this._getSetterAttributes(),function(a){if(!(a in this.attributeMap)){_154(a,this);}},this);},_getSetterAttributes:function(){var ctor=this.constructor;if(!ctor._setterAttrs){var r=(ctor._setterAttrs=[]),_156,_157=ctor.prototype;for(var _158 in _157){if(dojo.isFunction(_157[_158])&&(_156=_158.match(/^_set([a-zA-Z]*)Attr$/))&&_156[1]){r.push(_156[1].charAt(0).toLowerCase()+_156[1].substr(1));}}}return ctor._setterAttrs;},postMixInProperties:function(){},buildRendering:function(){if(!this.domNode){this.domNode=this.srcNodeRef||dojo.create("div");}if(this.baseClass){var _159=this.baseClass.split(" ");if(!this.isLeftToRight()){_159=_159.concat(dojo.map(_159,function(name){return name+"Rtl";}));}dojo.addClass(this.domNode,_159);}},postCreate:function(){},startup:function(){this._started=true;},destroyRecursive:function(_15a){this._beingDestroyed=true;this.destroyDescendants(_15a);this.destroy(_15a);},destroy:function(_15b){this._beingDestroyed=true;this.uninitialize();var d=dojo,dfe=d.forEach,dun=d.unsubscribe;dfe(this._connects,function(_15c){dfe(_15c,d.disconnect);});dfe(this._subscribes,function(_15d){dun(_15d);});dfe(this._supportingWidgets||[],function(w){if(w.destroyRecursive){w.destroyRecursive();}else{if(w.destroy){w.destroy();}}});this.destroyRendering(_15b);dijit.registry.remove(this.id);this._destroyed=true;},destroyRendering:function(_15e){if(this.bgIframe){this.bgIframe.destroy(_15e);delete this.bgIframe;}if(this.domNode){if(_15e){dojo.removeAttr(this.domNode,"widgetId");}else{dojo.destroy(this.domNode);}delete this.domNode;}if(this.srcNodeRef){if(!_15e){dojo.destroy(this.srcNodeRef);}delete this.srcNodeRef;}},destroyDescendants:function(_15f){dojo.forEach(this.getChildren(),function(_160){if(_160.destroyRecursive){_160.destroyRecursive(_15f);}});},uninitialize:function(){return false;},_setClassAttr:function(_161){var _162=this[this.attributeMap["class"]||"domNode"];dojo.replaceClass(_162,_161,this["class"]);this._set("class",_161);},_setStyleAttr:function(_163){var _164=this[this.attributeMap.style||"domNode"];if(dojo.isObject(_163)){dojo.style(_164,_163);}else{if(_164.style.cssText){_164.style.cssText+="; "+_163;}else{_164.style.cssText=_163;}}this._set("style",_163);},_attrToDom:function(attr,_165){var _166=this.attributeMap[attr];dojo.forEach(dojo.isArray(_166)?_166:[_166],function(_167){var _168=this[_167.node||_167||"domNode"];var type=_167.type||"attribute";switch(type){case "attribute":if(dojo.isFunction(_165)){_165=dojo.hitch(this,_165);}var _169=_167.attribute?_167.attribute:(/^on[A-Z][a-zA-Z]*$/.test(attr)?attr.toLowerCase():attr);dojo.attr(_168,_169,_165);break;case "innerText":_168.innerHTML="";_168.appendChild(dojo.doc.createTextNode(_165));break;case "innerHTML":_168.innerHTML=_165;break;case "class":dojo.replaceClass(_168,_165,this[attr]);break;}},this);},get:function(name){var _16a=this._getAttrNames(name);return this[_16a.g]?this[_16a.g]():this[name];},set:function(name,_16b){if(typeof name==="object"){for(var x in name){this.set(x,name[x]);}return this;}var _16c=this._getAttrNames(name);if(this[_16c.s]){var _16d=this[_16c.s].apply(this,Array.prototype.slice.call(arguments,1));}else{if(name in this.attributeMap){this._attrToDom(name,_16b);}this._set(name,_16b);}return _16d||this;},_attrPairNames:{},_getAttrNames:function(name){var apn=this._attrPairNames;if(apn[name]){return apn[name];}var uc=name.charAt(0).toUpperCase()+name.substr(1);return (apn[name]={n:name+"Node",s:"_set"+uc+"Attr",g:"_get"+uc+"Attr"});},_set:function(name,_16e){var _16f=this[name];this[name]=_16e;if(this._watchCallbacks&&this._created&&_16e!==_16f){this._watchCallbacks(name,_16f,_16e);}},toString:function(){return "[Widget "+this.declaredClass+", "+(this.id||"NO ID")+"]";},getDescendants:function(){return this.containerNode?dojo.query("[widgetId]",this.containerNode).map(dijit.byNode):[];},getChildren:function(){return this.containerNode?dijit.findWidgets(this.containerNode):[];},connect:function(obj,_170,_171){var _172=[dojo._connect(obj,_170,this,_171)];this._connects.push(_172);return _172;},disconnect:function(_173){for(var i=0;i<this._connects.length;i++){if(this._connects[i]==_173){dojo.forEach(_173,dojo.disconnect);this._connects.splice(i,1);return;}}},subscribe:function(_174,_175){var _176=dojo.subscribe(_174,this,_175);this._subscribes.push(_176);return _176;},unsubscribe:function(_177){for(var i=0;i<this._subscribes.length;i++){if(this._subscribes[i]==_177){dojo.unsubscribe(_177);this._subscribes.splice(i,1);return;}}},isLeftToRight:function(){return this.dir?(this.dir=="ltr"):dojo._isBodyLtr();},placeAt:function(_178,_179){if(_178.declaredClass&&_178.addChild){_178.addChild(this,_179);}else{dojo.place(this.domNode,_178,_179);}return this;}});})();}if(!dojo._hasResource["dijit._Widget"]){dojo._hasResource["dijit._Widget"]=true;dojo.provide("dijit._Widget");dojo.connect(dojo,"_connect",function(_17a,_17b){if(_17a&&dojo.isFunction(_17a._onConnect)){_17a._onConnect(_17b);}});dijit._connectOnUseEventHandler=function(_17c){};dijit._lastKeyDownNode=null;if(dojo.isIE){(function(){var _17d=function(evt){dijit._lastKeyDownNode=evt.srcElement;};dojo.doc.attachEvent("onkeydown",_17d);dojo.addOnWindowUnload(function(){dojo.doc.detachEvent("onkeydown",_17d);});})();}else{dojo.doc.addEventListener("keydown",function(evt){dijit._lastKeyDownNode=evt.target;},true);}(function(){dojo.declare("dijit._Widget",dijit._WidgetBase,{_deferredConnects:{onClick:"",onDblClick:"",onKeyDown:"",onKeyPress:"",onKeyUp:"",onMouseMove:"",onMouseDown:"",onMouseOut:"",onMouseOver:"",onMouseLeave:"",onMouseEnter:"",onMouseUp:""},onClick:dijit._connectOnUseEventHandler,onDblClick:dijit._connectOnUseEventHandler,onKeyDown:dijit._connectOnUseEventHandler,onKeyPress:dijit._connectOnUseEventHandler,onKeyUp:dijit._connectOnUseEventHandler,onMouseDown:dijit._connectOnUseEventHandler,onMouseMove:dijit._connectOnUseEventHandler,onMouseOut:dijit._connectOnUseEventHandler,onMouseOver:dijit._connectOnUseEventHandler,onMouseLeave:dijit._connectOnUseEventHandler,onMouseEnter:dijit._connectOnUseEventHandler,onMouseUp:dijit._connectOnUseEventHandler,create:function(_17e,_17f){this._deferredConnects=dojo.clone(this._deferredConnects);for(var attr in this.attributeMap){delete this._deferredConnects[attr];}for(attr in this._deferredConnects){if(this[attr]!==dijit._connectOnUseEventHandler){delete this._deferredConnects[attr];}}this.inherited(arguments);if(this.domNode){for(attr in this.params){this._onConnect(attr);}}},_onConnect:function(_180){if(_180 in this._deferredConnects){var _181=this[this._deferredConnects[_180]||"domNode"];this.connect(_181,_180.toLowerCase(),_180);delete this._deferredConnects[_180];}},focused:false,isFocusable:function(){return this.focus&&(dojo.style(this.domNode,"display")!="none");},onFocus:function(){},onBlur:function(){},_onFocus:function(e){this.onFocus();},_onBlur:function(){this.onBlur();},setAttribute:function(attr,_182){dojo.deprecated(this.declaredClass+"::setAttribute(attr, value) is deprecated. Use set() instead.","","2.0");this.set(attr,_182);},attr:function(name,_183){if(dojo.config.isDebug){var _184=arguments.callee._ach||(arguments.callee._ach={}),_185=(arguments.callee.caller||"unknown caller").toString();if(!_184[_185]){dojo.deprecated(this.declaredClass+"::attr() is deprecated. Use get() or set() instead, called from "+_185,"","2.0");_184[_185]=true;}}var args=arguments.length;if(args>=2||typeof name==="object"){return this.set.apply(this,arguments);}else{return this.get(name);}},nodesWithKeyClick:["input","button"],connect:function(obj,_186,_187){var d=dojo,dc=d._connect,_188=this.inherited(arguments,[obj,_186=="ondijitclick"?"onclick":_186,_187]);if(_186=="ondijitclick"){if(d.indexOf(this.nodesWithKeyClick,obj.nodeName.toLowerCase())==-1){var m=d.hitch(this,_187);_188.push(dc(obj,"onkeydown",this,function(e){if((e.keyCode==d.keys.ENTER||e.keyCode==d.keys.SPACE)&&!e.ctrlKey&&!e.shiftKey&&!e.altKey&&!e.metaKey){dijit._lastKeyDownNode=e.target;if(!("openDropDown" in this&&obj==this._buttonNode)){e.preventDefault();}}}),dc(obj,"onkeyup",this,function(e){if((e.keyCode==d.keys.ENTER||e.keyCode==d.keys.SPACE)&&e.target==dijit._lastKeyDownNode&&!e.ctrlKey&&!e.shiftKey&&!e.altKey&&!e.metaKey){dijit._lastKeyDownNode=null;return m(e);}}));}}return _188;},_onShow:function(){this.onShow();},onShow:function(){},onHide:function(){},onClose:function(){return true;}});})();}if(!dojo._hasResource["dojo.string"]){dojo._hasResource["dojo.string"]=true;dojo.provide("dojo.string");dojo.getObject("string",true,dojo);dojo.string.rep=function(str,num){if(num<=0||!str){return "";}var buf=[];for(;;){if(num&1){buf.push(str);}if(!(num>>=1)){break;}str+=str;}return buf.join("");};dojo.string.pad=function(text,size,ch,end){if(!ch){ch="0";}var out=String(text),pad=dojo.string.rep(ch,Math.ceil((size-out.length)/ch.length));return end?out+pad:pad+out;};dojo.string.substitute=function(_189,map,_18a,_18b){_18b=_18b||dojo.global;_18a=_18a?dojo.hitch(_18b,_18a):function(v){return v;};return _189.replace(/\$\{([^\s\:\}]+)(?:\:([^\s\:\}]+))?\}/g,function(_18c,key,_18d){var _18e=dojo.getObject(key,false,map);if(_18d){_18e=dojo.getObject(_18d,false,_18b).call(_18b,_18e,key);}return _18a(_18e,key).toString();});};dojo.string.trim=String.prototype.trim?dojo.trim:function(str){str=str.replace(/^\s+/,"");for(var i=str.length-1;i>=0;i--){if(/\S/.test(str.charAt(i))){str=str.substring(0,i+1);break;}}return str;};}if(!dojo._hasResource["dojo.cache"]){dojo._hasResource["dojo.cache"]=true;dojo.provide("dojo.cache");var cache={};dojo.cache=function(_18f,url,_190){if(typeof _18f=="string"){var _191=dojo.moduleUrl(_18f,url);}else{_191=_18f;_190=url;}var key=_191.toString();var val=_190;if(_190!=undefined&&!dojo.isString(_190)){val=("value" in _190?_190.value:undefined);}var _192=_190&&_190.sanitize?true:false;if(typeof val=="string"){val=cache[key]=_192?dojo.cache._sanitize(val):val;}else{if(val===null){delete cache[key];}else{if(!(key in cache)){val=dojo._getText(key);cache[key]=_192?dojo.cache._sanitize(val):val;}val=cache[key];}}return val;};dojo.cache._sanitize=function(val){if(val){val=val.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,"");var _193=val.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);if(_193){val=_193[1];}}else{val="";}return val;};}if(!dojo._hasResource["dijit._Templated"]){dojo._hasResource["dijit._Templated"]=true;dojo.provide("dijit._Templated");dojo.declare("dijit._Templated",null,{templateString:null,templatePath:null,widgetsInTemplate:false,_skipNodeCache:false,_earlyTemplatedStartup:false,constructor:function(){this._attachPoints=[];this._attachEvents=[];},_stringRepl:function(tmpl){var _194=this.declaredClass,_195=this;return dojo.string.substitute(tmpl,this,function(_196,key){if(key.charAt(0)=="!"){_196=dojo.getObject(key.substr(1),false,_195);}if(typeof _196=="undefined"){throw new Error(_194+" template:"+key);}if(_196==null){return "";}return key.charAt(0)=="!"?_196:_196.toString().replace(/"/g,"&quot;");},this);},buildRendering:function(){var _197=dijit._Templated.getCachedTemplate(this.templatePath,this.templateString,this._skipNodeCache);var node;if(dojo.isString(_197)){node=dojo._toDom(this._stringRepl(_197));if(node.nodeType!=1){throw new Error("Invalid template: "+_197);}}else{node=_197.cloneNode(true);}this.domNode=node;this.inherited(arguments);this._attachTemplateNodes(node);if(this.widgetsInTemplate){var cw=(this._startupWidgets=dojo.parser.parse(node,{noStart:!this._earlyTemplatedStartup,template:true,inherited:{dir:this.dir,lang:this.lang},propsThis:this,scope:"dojo"}));this._supportingWidgets=dijit.findWidgets(node);this._attachTemplateNodes(cw,function(n,p){return n[p];});}this._fillContent(this.srcNodeRef);},_fillContent:function(_198){var dest=this.containerNode;if(_198&&dest){while(_198.hasChildNodes()){dest.appendChild(_198.firstChild);}}},_attachTemplateNodes:function(_199,_19a){_19a=_19a||function(n,p){return n.getAttribute(p);};var _19b=dojo.isArray(_199)?_199:(_199.all||_199.getElementsByTagName("*"));var x=dojo.isArray(_199)?0:-1;for(;x<_19b.length;x++){var _19c=(x==-1)?_199:_19b[x];if(this.widgetsInTemplate&&(_19a(_19c,"dojoType")||_19a(_19c,"data-dojo-type"))){continue;}var _19d=_19a(_19c,"dojoAttachPoint")||_19a(_19c,"data-dojo-attach-point");if(_19d){var _19e,_19f=_19d.split(/\s*,\s*/);while((_19e=_19f.shift())){if(dojo.isArray(this[_19e])){this[_19e].push(_19c);}else{this[_19e]=_19c;}this._attachPoints.push(_19e);}}var _1a0=_19a(_19c,"dojoAttachEvent")||_19a(_19c,"data-dojo-attach-event");if(_1a0){var _1a1,_1a2=_1a0.split(/\s*,\s*/);var trim=dojo.trim;while((_1a1=_1a2.shift())){if(_1a1){var _1a3=null;if(_1a1.indexOf(":")!=-1){var _1a4=_1a1.split(":");_1a1=trim(_1a4[0]);_1a3=trim(_1a4[1]);}else{_1a1=trim(_1a1);}if(!_1a3){_1a3=_1a1;}this._attachEvents.push(this.connect(_19c,_1a1,_1a3));}}}var role=_19a(_19c,"waiRole");if(role){dijit.setWaiRole(_19c,role);}var _1a5=_19a(_19c,"waiState");if(_1a5){dojo.forEach(_1a5.split(/\s*,\s*/),function(_1a6){if(_1a6.indexOf("-")!=-1){var pair=_1a6.split("-");dijit.setWaiState(_19c,pair[0],pair[1]);}});}}},startup:function(){dojo.forEach(this._startupWidgets,function(w){if(w&&!w._started&&w.startup){w.startup();}});this.inherited(arguments);},destroyRendering:function(){dojo.forEach(this._attachPoints,function(_1a7){delete this[_1a7];},this);this._attachPoints=[];dojo.forEach(this._attachEvents,this.disconnect,this);this._attachEvents=[];this.inherited(arguments);}});dijit._Templated._templateCache={};dijit._Templated.getCachedTemplate=function(_1a8,_1a9,_1aa){var _1ab=dijit._Templated._templateCache;var key=_1a9||_1a8;var _1ac=_1ab[key];if(_1ac){try{if(!_1ac.ownerDocument||_1ac.ownerDocument==dojo.doc){return _1ac;}}catch(e){}dojo.destroy(_1ac);}if(!_1a9){_1a9=dojo.cache(_1a8,{sanitize:true});}_1a9=dojo.string.trim(_1a9);if(_1aa||_1a9.match(/\$\{([^\}]+)\}/g)){return (_1ab[key]=_1a9);}else{var node=dojo._toDom(_1a9);if(node.nodeType!=1){throw new Error("Invalid template: "+_1a9);}return (_1ab[key]=node);}};if(dojo.isIE){dojo.addOnWindowUnload(function(){var _1ad=dijit._Templated._templateCache;for(var key in _1ad){var _1ae=_1ad[key];if(typeof _1ae=="object"){dojo.destroy(_1ae);}delete _1ad[key];}});}dojo.extend(dijit._Widget,{dojoAttachEvent:"",dojoAttachPoint:"",waiRole:"",waiState:""});}if(!dojo._hasResource["dijit._Container"]){dojo._hasResource["dijit._Container"]=true;dojo.provide("dijit._Container");dojo.declare("dijit._Container",null,{isContainer:true,buildRendering:function(){this.inherited(arguments);if(!this.containerNode){this.containerNode=this.domNode;}},addChild:function(_1af,_1b0){var _1b1=this.containerNode;if(_1b0&&typeof _1b0=="number"){var _1b2=this.getChildren();if(_1b2&&_1b2.length>=_1b0){_1b1=_1b2[_1b0-1].domNode;_1b0="after";}}dojo.place(_1af.domNode,_1b1,_1b0);if(this._started&&!_1af._started){_1af.startup();}},removeChild:function(_1b3){if(typeof _1b3=="number"){_1b3=this.getChildren()[_1b3];}if(_1b3){var node=_1b3.domNode;if(node&&node.parentNode){node.parentNode.removeChild(node);}}},hasChildren:function(){return this.getChildren().length>0;},destroyDescendants:function(_1b4){dojo.forEach(this.getChildren(),function(_1b5){_1b5.destroyRecursive(_1b4);});},_getSiblingOfChild:function(_1b6,dir){var node=_1b6.domNode,_1b7=(dir>0?"nextSibling":"previousSibling");do{node=node[_1b7];}while(node&&(node.nodeType!=1||!dijit.byNode(node)));return node&&dijit.byNode(node);},getIndexOfChild:function(_1b8){return dojo.indexOf(this.getChildren(),_1b8);},startup:function(){if(this._started){return;}dojo.forEach(this.getChildren(),function(_1b9){_1b9.startup();});this.inherited(arguments);}});}if(!dojo._hasResource["dijit._Contained"]){dojo._hasResource["dijit._Contained"]=true;dojo.provide("dijit._Contained");dojo.declare("dijit._Contained",null,{getParent:function(){var _1ba=dijit.getEnclosingWidget(this.domNode.parentNode);return _1ba&&_1ba.isContainer?_1ba:null;},_getSibling:function(_1bb){var node=this.domNode;do{node=node[_1bb+"Sibling"];}while(node&&node.nodeType!=1);return node&&dijit.byNode(node);},getPreviousSibling:function(){return this._getSibling("previous");},getNextSibling:function(){return this._getSibling("next");},getIndexInParent:function(){var p=this.getParent();if(!p||!p.getIndexOfChild){return -1;}return p.getIndexOfChild(this);}});}if(!dojo._hasResource["dijit.layout._LayoutWidget"]){dojo._hasResource["dijit.layout._LayoutWidget"]=true;dojo.provide("dijit.layout._LayoutWidget");dojo.declare("dijit.layout._LayoutWidget",[dijit._Widget,dijit._Container,dijit._Contained],{baseClass:"dijitLayoutContainer",isLayoutContainer:true,buildRendering:function(){this.inherited(arguments);dojo.addClass(this.domNode,"dijitContainer");},startup:function(){if(this._started){return;}this.inherited(arguments);var _1bc=this.getParent&&this.getParent();if(!(_1bc&&_1bc.isLayoutContainer)){this.resize();this.connect(dojo.isIE?this.domNode:dojo.global,"onresize",function(){this.resize();});}},resize:function(_1bd,_1be){var node=this.domNode;if(_1bd){dojo.marginBox(node,_1bd);if(_1bd.t){node.style.top=_1bd.t+"px";}if(_1bd.l){node.style.left=_1bd.l+"px";}}var mb=_1be||{};dojo.mixin(mb,_1bd||{});if(!("h" in mb)||!("w" in mb)){mb=dojo.mixin(dojo.marginBox(node),mb);}var cs=dojo.getComputedStyle(node);var me=dojo._getMarginExtents(node,cs);var be=dojo._getBorderExtents(node,cs);var bb=(this._borderBox={w:mb.w-(me.w+be.w),h:mb.h-(me.h+be.h)});var pe=dojo._getPadExtents(node,cs);this._contentBox={l:dojo._toPixelValue(node,cs.paddingLeft),t:dojo._toPixelValue(node,cs.paddingTop),w:bb.w-pe.w,h:bb.h-pe.h};this.layout();},layout:function(){},_setupChild:function(_1bf){var cls=this.baseClass+"-child "+(_1bf.baseClass?this.baseClass+"-"+_1bf.baseClass:"");dojo.addClass(_1bf.domNode,cls);},addChild:function(_1c0,_1c1){this.inherited(arguments);if(this._started){this._setupChild(_1c0);}},removeChild:function(_1c2){var cls=this.baseClass+"-child"+(_1c2.baseClass?" "+this.baseClass+"-"+_1c2.baseClass:"");dojo.removeClass(_1c2.domNode,cls);this.inherited(arguments);}});dijit.layout.marginBox2contentBox=function(node,mb){var cs=dojo.getComputedStyle(node);var me=dojo._getMarginExtents(node,cs);var pb=dojo._getPadBorderExtents(node,cs);return {l:dojo._toPixelValue(node,cs.paddingLeft),t:dojo._toPixelValue(node,cs.paddingTop),w:mb.w-(me.w+pb.w),h:mb.h-(me.h+pb.h)};};(function(){var _1c3=function(word){return word.substring(0,1).toUpperCase()+word.substring(1);};var size=function(_1c4,dim){_1c4.resize?_1c4.resize(dim):dojo.marginBox(_1c4.domNode,dim);dojo.mixin(_1c4,dojo.marginBox(_1c4.domNode));dojo.mixin(_1c4,dim);};dijit.layout.layoutChildren=function(_1c5,dim,_1c6,_1c7,_1c8){dim=dojo.mixin({},dim);dojo.addClass(_1c5,"dijitLayoutContainer");_1c6=dojo.filter(_1c6,function(item){return item.region!="center"&&item.layoutAlign!="client";}).concat(dojo.filter(_1c6,function(item){return item.region=="center"||item.layoutAlign=="client";}));dojo.forEach(_1c6,function(_1c9){var elm=_1c9.domNode,pos=(_1c9.region||_1c9.layoutAlign);var _1ca=elm.style;_1ca.left=dim.l+"px";_1ca.top=dim.t+"px";_1ca.bottom=_1ca.right="auto";dojo.addClass(elm,"dijitAlign"+_1c3(pos));var _1cb={};if(_1c7&&_1c7==_1c9.id){_1cb[_1c9.region=="top"||_1c9.region=="bottom"?"h":"w"]=_1c8;}if(pos=="top"||pos=="bottom"){_1cb.w=dim.w;size(_1c9,_1cb);dim.h-=_1c9.h;if(pos=="top"){dim.t+=_1c9.h;}else{_1ca.top=dim.t+dim.h+"px";}}else{if(pos=="left"||pos=="right"){_1cb.h=dim.h;size(_1c9,_1cb);dim.w-=_1c9.w;if(pos=="left"){dim.l+=_1c9.w;}else{_1ca.left=dim.l+dim.w+"px";}}else{if(pos=="client"||pos=="center"){size(_1c9,dim);}}}});};})();}if(!dojo._hasResource["dijit._CssStateMixin"]){dojo._hasResource["dijit._CssStateMixin"]=true;dojo.provide("dijit._CssStateMixin");dojo.declare("dijit._CssStateMixin",[],{cssStateNodes:{},hovering:false,active:false,_applyAttributes:function(){this.inherited(arguments);dojo.forEach(["onmouseenter","onmouseleave","onmousedown"],function(e){this.connect(this.domNode,e,"_cssMouseEvent");},this);dojo.forEach(["disabled","readOnly","checked","selected","focused","state","hovering","active"],function(attr){this.watch(attr,dojo.hitch(this,"_setStateClass"));},this);for(var ap in this.cssStateNodes){this._trackMouseState(this[ap],this.cssStateNodes[ap]);}this._setStateClass();},_cssMouseEvent:function(_1cc){if(!this.disabled){switch(_1cc.type){case "mouseenter":case "mouseover":this._set("hovering",true);this._set("active",this._mouseDown);break;case "mouseleave":case "mouseout":this._set("hovering",false);this._set("active",false);break;case "mousedown":this._set("active",true);this._mouseDown=true;var _1cd=this.connect(dojo.body(),"onmouseup",function(){this._mouseDown=false;this._set("active",false);this.disconnect(_1cd);});break;}}},_setStateClass:function(){var _1ce=this.baseClass.split(" ");function _1cf(_1d0){_1ce=_1ce.concat(dojo.map(_1ce,function(c){return c+_1d0;}),"dijit"+_1d0);};if(!this.isLeftToRight()){_1cf("Rtl");}if(this.checked){_1cf("Checked");}if(this.state){_1cf(this.state);}if(this.selected){_1cf("Selected");}if(this.disabled){_1cf("Disabled");}else{if(this.readOnly){_1cf("ReadOnly");}else{if(this.active){_1cf("Active");}else{if(this.hovering){_1cf("Hover");}}}}if(this._focused){_1cf("Focused");}var tn=this.stateNode||this.domNode,_1d1={};dojo.forEach(tn.className.split(" "),function(c){_1d1[c]=true;});if("_stateClasses" in this){dojo.forEach(this._stateClasses,function(c){delete _1d1[c];});}dojo.forEach(_1ce,function(c){_1d1[c]=true;});var _1d2=[];for(var c in _1d1){_1d2.push(c);}tn.className=_1d2.join(" ");this._stateClasses=_1ce;},_trackMouseState:function(node,_1d3){var _1d4=false,_1d5=false,_1d6=false;var self=this,cn=dojo.hitch(this,"connect",node);function _1d7(){var _1d8=("disabled" in self&&self.disabled)||("readonly" in self&&self.readonly);dojo.toggleClass(node,_1d3+"Hover",_1d4&&!_1d5&&!_1d8);dojo.toggleClass(node,_1d3+"Active",_1d5&&!_1d8);dojo.toggleClass(node,_1d3+"Focused",_1d6&&!_1d8);};cn("onmouseenter",function(){_1d4=true;_1d7();});cn("onmouseleave",function(){_1d4=false;_1d5=false;_1d7();});cn("onmousedown",function(){_1d5=true;_1d7();});cn("onmouseup",function(){_1d5=false;_1d7();});cn("onfocus",function(){_1d6=true;_1d7();});cn("onblur",function(){_1d6=false;_1d7();});this.watch("disabled",_1d7);this.watch("readOnly",_1d7);}});}if(!dojo._hasResource["dijit.form._FormWidget"]){dojo._hasResource["dijit.form._FormWidget"]=true;dojo.provide("dijit.form._FormWidget");dojo.declare("dijit.form._FormWidget",[dijit._Widget,dijit._Templated,dijit._CssStateMixin],{name:"",alt:"",value:"",type:"text",tabIndex:"0",disabled:false,intermediateChanges:false,scrollOnFocus:true,attributeMap:dojo.delegate(dijit._Widget.prototype.attributeMap,{value:"focusNode",id:"focusNode",tabIndex:"focusNode",alt:"focusNode",title:"focusNode"}),postMixInProperties:function(){this.nameAttrSetting=this.name?("name=\""+this.name.replace(/'/g,"&quot;")+"\""):"";this.inherited(arguments);},postCreate:function(){this.inherited(arguments);this.connect(this.domNode,"onmousedown","_onMouseDown");},_setDisabledAttr:function(_1d9){this._set("disabled",_1d9);dojo.attr(this.focusNode,"disabled",_1d9);if(this.valueNode){dojo.attr(this.valueNode,"disabled",_1d9);}dijit.setWaiState(this.focusNode,"disabled",_1d9);if(_1d9){this._set("hovering",false);this._set("active",false);var _1da="tabIndex" in this.attributeMap?this.attributeMap.tabIndex:"focusNode";dojo.forEach(dojo.isArray(_1da)?_1da:[_1da],function(_1db){var node=this[_1db];if(dojo.isWebKit||dijit.hasDefaultTabStop(node)){node.setAttribute("tabIndex","-1");}else{node.removeAttribute("tabIndex");}},this);}else{if(this.tabIndex!=""){this.focusNode.setAttribute("tabIndex",this.tabIndex);}}},setDisabled:function(_1dc){dojo.deprecated("setDisabled("+_1dc+") is deprecated. Use set('disabled',"+_1dc+") instead.","","2.0");this.set("disabled",_1dc);},_onFocus:function(e){if(this.scrollOnFocus){dojo.window.scrollIntoView(this.domNode);}this.inherited(arguments);},isFocusable:function(){return !this.disabled&&this.focusNode&&(dojo.style(this.domNode,"display")!="none");},focus:function(){if(!this.disabled){dijit.focus(this.focusNode);}},compare:function(val1,val2){if(typeof val1=="number"&&typeof val2=="number"){return (isNaN(val1)&&isNaN(val2))?0:val1-val2;}else{if(val1>val2){return 1;}else{if(val1<val2){return -1;}else{return 0;}}}},onChange:function(_1dd){},_onChangeActive:false,_handleOnChange:function(_1de,_1df){if(this._lastValueReported==undefined&&(_1df===null||!this._onChangeActive)){this._resetValue=this._lastValueReported=_1de;}this._pendingOnChange=this._pendingOnChange||(typeof _1de!=typeof this._lastValueReported)||(this.compare(_1de,this._lastValueReported)!=0);if((this.intermediateChanges||_1df||_1df===undefined)&&this._pendingOnChange){this._lastValueReported=_1de;this._pendingOnChange=false;if(this._onChangeActive){if(this._onChangeHandle){clearTimeout(this._onChangeHandle);}this._onChangeHandle=setTimeout(dojo.hitch(this,function(){this._onChangeHandle=null;this.onChange(_1de);}),0);}}},create:function(){this.inherited(arguments);this._onChangeActive=true;},destroy:function(){if(this._onChangeHandle){clearTimeout(this._onChangeHandle);this.onChange(this._lastValueReported);}this.inherited(arguments);},setValue:function(_1e0){dojo.deprecated("dijit.form._FormWidget:setValue("+_1e0+") is deprecated. Use set('value',"+_1e0+") instead.","","2.0");this.set("value",_1e0);},getValue:function(){dojo.deprecated(this.declaredClass+"::getValue() is deprecated. Use get('value') instead.","","2.0");return this.get("value");},_onMouseDown:function(e){if(!e.ctrlKey&&dojo.mouseButtons.isLeft(e)&&this.isFocusable()){var _1e1=this.connect(dojo.body(),"onmouseup",function(){if(this.isFocusable()){this.focus();}this.disconnect(_1e1);});}}});dojo.declare("dijit.form._FormValueWidget",dijit.form._FormWidget,{readOnly:false,attributeMap:dojo.delegate(dijit.form._FormWidget.prototype.attributeMap,{value:"",readOnly:"focusNode"}),_setReadOnlyAttr:function(_1e2){dojo.attr(this.focusNode,"readOnly",_1e2);dijit.setWaiState(this.focusNode,"readonly",_1e2);this._set("readOnly",_1e2);},postCreate:function(){this.inherited(arguments);if(dojo.isIE){this.connect(this.focusNode||this.domNode,"onkeydown",this._onKeyDown);}if(this._resetValue===undefined){this._lastValueReported=this._resetValue=this.value;}},_setValueAttr:function(_1e3,_1e4){this._handleOnChange(_1e3,_1e4);},_handleOnChange:function(_1e5,_1e6){this._set("value",_1e5);this.inherited(arguments);},undo:function(){this._setValueAttr(this._lastValueReported,false);},reset:function(){this._hasBeenBlurred=false;this._setValueAttr(this._resetValue,true);},_onKeyDown:function(e){if(e.keyCode==dojo.keys.ESCAPE&&!(e.ctrlKey||e.altKey||e.metaKey)){var te;if(dojo.isIE){e.preventDefault();te=document.createEventObject();te.keyCode=dojo.keys.ESCAPE;te.shiftKey=e.shiftKey;e.srcElement.fireEvent("onkeypress",te);}}},_layoutHackIE7:function(){if(dojo.isIE==7){var _1e7=this.domNode;var _1e8=_1e7.parentNode;var _1e9=_1e7.firstChild||_1e7;var _1ea=_1e9.style.filter;var _1eb=this;while(_1e8&&_1e8.clientHeight==0){(function ping(){var _1ec=_1eb.connect(_1e8,"onscroll",function(e){_1eb.disconnect(_1ec);_1e9.style.filter=(new Date()).getMilliseconds();setTimeout(function(){_1e9.style.filter=_1ea;},0);});})();_1e8=_1e8.parentNode;}}}});}if(!dojo._hasResource["dijit.dijit"]){dojo._hasResource["dijit.dijit"]=true;dojo.provide("dijit.dijit");}if(!dojo._hasResource["dijit._KeyNavContainer"]){dojo._hasResource["dijit._KeyNavContainer"]=true;dojo.provide("dijit._KeyNavContainer");dojo.declare("dijit._KeyNavContainer",dijit._Container,{tabIndex:"0",_keyNavCodes:{},connectKeyNavHandlers:function(_1ed,_1ee){var _1ef=(this._keyNavCodes={});var prev=dojo.hitch(this,this.focusPrev);var next=dojo.hitch(this,this.focusNext);dojo.forEach(_1ed,function(code){_1ef[code]=prev;});dojo.forEach(_1ee,function(code){_1ef[code]=next;});_1ef[dojo.keys.HOME]=dojo.hitch(this,"focusFirstChild");_1ef[dojo.keys.END]=dojo.hitch(this,"focusLastChild");this.connect(this.domNode,"onkeypress","_onContainerKeypress");this.connect(this.domNode,"onfocus","_onContainerFocus");},startupKeyNavChildren:function(){dojo.forEach(this.getChildren(),dojo.hitch(this,"_startupChild"));},addChild:function(_1f0,_1f1){dijit._KeyNavContainer.superclass.addChild.apply(this,arguments);this._startupChild(_1f0);},focus:function(){this.focusFirstChild();},focusFirstChild:function(){var _1f2=this._getFirstFocusableChild();if(_1f2){this.focusChild(_1f2);}},focusLastChild:function(){var _1f3=this._getLastFocusableChild();if(_1f3){this.focusChild(_1f3);}},focusNext:function(){var _1f4=this._getNextFocusableChild(this.focusedChild,1);this.focusChild(_1f4);},focusPrev:function(){var _1f5=this._getNextFocusableChild(this.focusedChild,-1);this.focusChild(_1f5,true);},focusChild:function(_1f6,last){if(this.focusedChild&&_1f6!==this.focusedChild){this._onChildBlur(this.focusedChild);}_1f6.focus(last?"end":"start");this._set("focusedChild",_1f6);},_startupChild:function(_1f7){_1f7.set("tabIndex","-1");this.connect(_1f7,"_onFocus",function(){_1f7.set("tabIndex",this.tabIndex);});this.connect(_1f7,"_onBlur",function(){_1f7.set("tabIndex","-1");});},_onContainerFocus:function(evt){if(evt.target!==this.domNode){return;}this.focusFirstChild();dojo.attr(this.domNode,"tabIndex","-1");},_onBlur:function(evt){if(this.tabIndex){dojo.attr(this.domNode,"tabIndex",this.tabIndex);}this.inherited(arguments);},_onContainerKeypress:function(evt){if(evt.ctrlKey||evt.altKey){return;}var func=this._keyNavCodes[evt.charOrCode];if(func){func();dojo.stopEvent(evt);}},_onChildBlur:function(_1f8){},_getFirstFocusableChild:function(){return this._getNextFocusableChild(null,1);},_getLastFocusableChild:function(){return this._getNextFocusableChild(null,-1);},_getNextFocusableChild:function(_1f9,dir){if(_1f9){_1f9=this._getSiblingOfChild(_1f9,dir);}var _1fa=this.getChildren();for(var i=0;i<_1fa.length;i++){if(!_1f9){_1f9=_1fa[(dir>0)?0:(_1fa.length-1)];}if(_1f9.isFocusable()){return _1f9;}_1f9=this._getSiblingOfChild(_1f9,dir);}return null;}});}if(!dojo._hasResource["dijit.MenuItem"]){dojo._hasResource["dijit.MenuItem"]=true;dojo.provide("dijit.MenuItem");dojo.declare("dijit.MenuItem",[dijit._Widget,dijit._Templated,dijit._Contained,dijit._CssStateMixin],{templateString:dojo.cache("dijit","templates/MenuItem.html","<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" role=\"menuitem\" tabIndex=\"-1\"\r\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\r\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\r\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitIcon dijitMenuItemIcon\" dojoAttachPoint=\"iconNode\"/>\r\n\t</td>\r\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" dojoAttachPoint=\"containerNode\"></td>\r\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" dojoAttachPoint=\"accelKeyNode\"></td>\r\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">\r\n\t\t<div dojoAttachPoint=\"arrowWrapper\" style=\"visibility: hidden\">\r\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuExpand\"/>\r\n\t\t\t<span class=\"dijitMenuExpandA11y\">+</span>\r\n\t\t</div>\r\n\t</td>\r\n</tr>\r\n"),attributeMap:dojo.delegate(dijit._Widget.prototype.attributeMap,{label:{node:"containerNode",type:"innerHTML"},iconClass:{node:"iconNode",type:"class"}}),baseClass:"dijitMenuItem",label:"",iconClass:"",accelKey:"",disabled:false,_fillContent:function(_1fb){if(_1fb&&!("label" in this.params)){this.set("label",_1fb.innerHTML);}},buildRendering:function(){this.inherited(arguments);var _1fc=this.id+"_text";dojo.attr(this.containerNode,"id",_1fc);if(this.accelKeyNode){dojo.attr(this.accelKeyNode,"id",this.id+"_accel");_1fc+=" "+this.id+"_accel";}dijit.setWaiState(this.domNode,"labelledby",_1fc);dojo.setSelectable(this.domNode,false);},_onHover:function(){this.getParent().onItemHover(this);},_onUnhover:function(){this.getParent().onItemUnhover(this);this._set("hovering",false);},_onClick:function(evt){this.getParent().onItemClick(this,evt);dojo.stopEvent(evt);},onClick:function(evt){},focus:function(){try{if(dojo.isIE==8){this.containerNode.focus();}dijit.focus(this.focusNode);}catch(e){}},_onFocus:function(){this._setSelected(true);this.getParent()._onItemFocus(this);this.inherited(arguments);},_setSelected:function(_1fd){dojo.toggleClass(this.domNode,"dijitMenuItemSelected",_1fd);},setLabel:function(_1fe){dojo.deprecated("dijit.MenuItem.setLabel() is deprecated. Use set('label', ...) instead.","","2.0");this.set("label",_1fe);},setDisabled:function(_1ff){dojo.deprecated("dijit.Menu.setDisabled() is deprecated. Use set('disabled', bool) instead.","","2.0");this.set("disabled",_1ff);},_setDisabledAttr:function(_200){dijit.setWaiState(this.focusNode,"disabled",_200?"true":"false");this._set("disabled",_200);},_setAccelKeyAttr:function(_201){this.accelKeyNode.style.display=_201?"":"none";this.accelKeyNode.innerHTML=_201;dojo.attr(this.containerNode,"colSpan",_201?"1":"2");this._set("accelKey",_201);}});}if(!dojo._hasResource["dijit.PopupMenuItem"]){dojo._hasResource["dijit.PopupMenuItem"]=true;dojo.provide("dijit.PopupMenuItem");dojo.declare("dijit.PopupMenuItem",dijit.MenuItem,{_fillContent:function(){if(this.srcNodeRef){var _202=dojo.query("*",this.srcNodeRef);dijit.PopupMenuItem.superclass._fillContent.call(this,_202[0]);this.dropDownContainer=this.srcNodeRef;}},startup:function(){if(this._started){return;}this.inherited(arguments);if(!this.popup){var node=dojo.query("[widgetId]",this.dropDownContainer)[0];this.popup=dijit.byNode(node);}dojo.body().appendChild(this.popup.domNode);this.popup.startup();this.popup.domNode.style.display="none";if(this.arrowWrapper){dojo.style(this.arrowWrapper,"visibility","");}dijit.setWaiState(this.focusNode,"haspopup","true");},destroyDescendants:function(){if(this.popup){if(!this.popup._destroyed){this.popup.destroyRecursive();}delete this.popup;}this.inherited(arguments);}});}if(!dojo._hasResource["dijit.CheckedMenuItem"]){dojo._hasResource["dijit.CheckedMenuItem"]=true;dojo.provide("dijit.CheckedMenuItem");dojo.declare("dijit.CheckedMenuItem",dijit.MenuItem,{templateString:dojo.cache("dijit","templates/CheckedMenuItem.html","<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" role=\"menuitemcheckbox\" tabIndex=\"-1\"\r\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\r\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\r\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" dojoAttachPoint=\"iconNode\"/>\r\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">&#10003;</span>\r\n\t</td>\r\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" dojoAttachPoint=\"containerNode,labelNode\"></td>\r\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" dojoAttachPoint=\"accelKeyNode\"></td>\r\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">&nbsp;</td>\r\n</tr>\r\n"),checked:false,_setCheckedAttr:function(_203){dojo.toggleClass(this.domNode,"dijitCheckedMenuItemChecked",_203);dijit.setWaiState(this.domNode,"checked",_203);this._set("checked",_203);},onChange:function(_204){},_onClick:function(e){if(!this.disabled){this.set("checked",!this.checked);this.onChange(this.checked);}this.inherited(arguments);}});}if(!dojo._hasResource["dijit.MenuSeparator"]){dojo._hasResource["dijit.MenuSeparator"]=true;dojo.provide("dijit.MenuSeparator");dojo.declare("dijit.MenuSeparator",[dijit._Widget,dijit._Templated,dijit._Contained],{templateString:dojo.cache("dijit","templates/MenuSeparator.html","<tr class=\"dijitMenuSeparator\">\r\n\t<td class=\"dijitMenuSeparatorIconCell\">\r\n\t\t<div class=\"dijitMenuSeparatorTop\"></div>\r\n\t\t<div class=\"dijitMenuSeparatorBottom\"></div>\r\n\t</td>\r\n\t<td colspan=\"3\" class=\"dijitMenuSeparatorLabelCell\">\r\n\t\t<div class=\"dijitMenuSeparatorTop dijitMenuSeparatorLabel\"></div>\r\n\t\t<div class=\"dijitMenuSeparatorBottom\"></div>\r\n\t</td>\r\n</tr>\r\n"),buildRendering:function(){this.inherited(arguments);dojo.setSelectable(this.domNode,false);},isFocusable:function(){return false;}});}if(!dojo._hasResource["dijit.Menu"]){dojo._hasResource["dijit.Menu"]=true;dojo.provide("dijit.Menu");dojo.declare("dijit._MenuBase",[dijit._Widget,dijit._Templated,dijit._KeyNavContainer],{parentMenu:null,popupDelay:500,startup:function(){if(this._started){return;}dojo.forEach(this.getChildren(),function(_205){_205.startup();});this.startupKeyNavChildren();this.inherited(arguments);},onExecute:function(){},onCancel:function(_206){},_moveToPopup:function(evt){if(this.focusedChild&&this.focusedChild.popup&&!this.focusedChild.disabled){this.focusedChild._onClick(evt);}else{var _207=this._getTopMenu();if(_207&&_207._isMenuBar){_207.focusNext();}}},_onPopupHover:function(evt){if(this.currentPopup&&this.currentPopup._pendingClose_timer){var _208=this.currentPopup.parentMenu;if(_208.focusedChild){_208.focusedChild._setSelected(false);}_208.focusedChild=this.currentPopup.from_item;_208.focusedChild._setSelected(true);this._stopPendingCloseTimer(this.currentPopup);}},onItemHover:function(item){if(this.isActive){this.focusChild(item);if(this.focusedChild.popup&&!this.focusedChild.disabled&&!this.hover_timer){this.hover_timer=setTimeout(dojo.hitch(this,"_openPopup"),this.popupDelay);}}if(this.focusedChild){this.focusChild(item);}this._hoveredChild=item;},_onChildBlur:function(item){this._stopPopupTimer();item._setSelected(false);var _209=item.popup;if(_209){this._stopPendingCloseTimer(_209);_209._pendingClose_timer=setTimeout(function(){_209._pendingClose_timer=null;if(_209.parentMenu){_209.parentMenu.currentPopup=null;}dijit.popup.close(_209);},this.popupDelay);}},onItemUnhover:function(item){if(this.isActive){this._stopPopupTimer();}if(this._hoveredChild==item){this._hoveredChild=null;}},_stopPopupTimer:function(){if(this.hover_timer){clearTimeout(this.hover_timer);this.hover_timer=null;}},_stopPendingCloseTimer:function(_20a){if(_20a._pendingClose_timer){clearTimeout(_20a._pendingClose_timer);_20a._pendingClose_timer=null;}},_stopFocusTimer:function(){if(this._focus_timer){clearTimeout(this._focus_timer);this._focus_timer=null;}},_getTopMenu:function(){for(var top=this;top.parentMenu;top=top.parentMenu){}return top;},onItemClick:function(item,evt){if(typeof this.isShowingNow=="undefined"){this._markActive();}this.focusChild(item);if(item.disabled){return false;}if(item.popup){this._openPopup();}else{this.onExecute();item.onClick(evt);}},_openPopup:function(){this._stopPopupTimer();var _20b=this.focusedChild;if(!_20b){return;}var _20c=_20b.popup;if(_20c.isShowingNow){return;}if(this.currentPopup){this._stopPendingCloseTimer(this.currentPopup);dijit.popup.close(this.currentPopup);}_20c.parentMenu=this;_20c.from_item=_20b;var self=this;dijit.popup.open({parent:this,popup:_20c,around:_20b.domNode,orient:this._orient||(this.isLeftToRight()?{"TR":"TL","TL":"TR","BR":"BL","BL":"BR"}:{"TL":"TR","TR":"TL","BL":"BR","BR":"BL"}),onCancel:function(){self.focusChild(_20b);self._cleanUp();_20b._setSelected(true);self.focusedChild=_20b;},onExecute:dojo.hitch(this,"_cleanUp")});this.currentPopup=_20c;_20c.connect(_20c.domNode,"onmouseenter",dojo.hitch(self,"_onPopupHover"));if(_20c.focus){_20c._focus_timer=setTimeout(dojo.hitch(_20c,function(){this._focus_timer=null;this.focus();}),0);}},_markActive:function(){this.isActive=true;dojo.replaceClass(this.domNode,"dijitMenuActive","dijitMenuPassive");},onOpen:function(e){this.isShowingNow=true;this._markActive();},_markInactive:function(){this.isActive=false;dojo.replaceClass(this.domNode,"dijitMenuPassive","dijitMenuActive");},onClose:function(){this._stopFocusTimer();this._markInactive();this.isShowingNow=false;this.parentMenu=null;},_closeChild:function(){this._stopPopupTimer();var _20d=this.focusedChild&&this.focusedChild.from_item;if(this.currentPopup){if(dijit._curFocus&&dojo.isDescendant(dijit._curFocus,this.currentPopup.domNode)){this.focusedChild.focusNode.focus();}dijit.popup.close(this.currentPopup);this.currentPopup=null;}if(this.focusedChild){this.focusedChild._setSelected(false);this.focusedChild._onUnhover();this.focusedChild=null;}},_onItemFocus:function(item){if(this._hoveredChild&&this._hoveredChild!=item){this._hoveredChild._onUnhover();}},_onBlur:function(){this._cleanUp();this.inherited(arguments);},_cleanUp:function(){this._closeChild();if(typeof this.isShowingNow=="undefined"){this._markInactive();}}});dojo.declare("dijit.Menu",dijit._MenuBase,{constructor:function(){this._bindings=[];},templateString:dojo.cache("dijit","templates/Menu.html","<table class=\"dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable\" role=\"menu\" tabIndex=\"${tabIndex}\" dojoAttachEvent=\"onkeypress:_onKeyPress\" cellspacing=\"0\">\r\n\t<tbody class=\"dijitReset\" dojoAttachPoint=\"containerNode\"></tbody>\r\n</table>\r\n"),baseClass:"dijitMenu",targetNodeIds:[],contextMenuForWindow:false,leftClickToOpen:false,refocus:true,postCreate:function(){if(this.contextMenuForWindow){this.bindDomNode(dojo.body());}else{dojo.forEach(this.targetNodeIds,this.bindDomNode,this);}var k=dojo.keys,l=this.isLeftToRight();this._openSubMenuKey=l?k.RIGHT_ARROW:k.LEFT_ARROW;this._closeSubMenuKey=l?k.LEFT_ARROW:k.RIGHT_ARROW;this.connectKeyNavHandlers([k.UP_ARROW],[k.DOWN_ARROW]);},_onKeyPress:function(evt){if(evt.ctrlKey||evt.altKey){return;}switch(evt.charOrCode){case this._openSubMenuKey:this._moveToPopup(evt);dojo.stopEvent(evt);break;case this._closeSubMenuKey:if(this.parentMenu){if(this.parentMenu._isMenuBar){this.parentMenu.focusPrev();}else{this.onCancel(false);}}else{dojo.stopEvent(evt);}break;}},_iframeContentWindow:function(_20e){var win=dojo.window.get(this._iframeContentDocument(_20e))||this._iframeContentDocument(_20e)["__parent__"]||(_20e.name&&dojo.doc.frames[_20e.name])||null;return win;},_iframeContentDocument:function(_20f){var doc=_20f.contentDocument||(_20f.contentWindow&&_20f.contentWindow.document)||(_20f.name&&dojo.doc.frames[_20f.name]&&dojo.doc.frames[_20f.name].document)||null;return doc;},bindDomNode:function(node){node=dojo.byId(node);var cn;if(node.tagName.toLowerCase()=="iframe"){var _210=node,win=this._iframeContentWindow(_210);cn=dojo.withGlobal(win,dojo.body);}else{cn=(node==dojo.body()?dojo.doc.documentElement:node);}var _211={node:node,iframe:_210};dojo.attr(node,"_dijitMenu"+this.id,this._bindings.push(_211));var _212=dojo.hitch(this,function(cn){return [dojo.connect(cn,this.leftClickToOpen?"onclick":"oncontextmenu",this,function(evt){dojo.stopEvent(evt);this._scheduleOpen(evt.target,_210,{x:evt.pageX,y:evt.pageY});}),dojo.connect(cn,"onkeydown",this,function(evt){if(evt.shiftKey&&evt.keyCode==dojo.keys.F10){dojo.stopEvent(evt);this._scheduleOpen(evt.target,_210);}})];});_211.connects=cn?_212(cn):[];if(_210){_211.onloadHandler=dojo.hitch(this,function(){var win=this._iframeContentWindow(_210);cn=dojo.withGlobal(win,dojo.body);_211.connects=_212(cn);});if(_210.addEventListener){_210.addEventListener("load",_211.onloadHandler,false);}else{_210.attachEvent("onload",_211.onloadHandler);}}},unBindDomNode:function(_213){var node;try{node=dojo.byId(_213);}catch(e){return;}var _214="_dijitMenu"+this.id;if(node&&dojo.hasAttr(node,_214)){var bid=dojo.attr(node,_214)-1,b=this._bindings[bid];dojo.forEach(b.connects,dojo.disconnect);var _215=b.iframe;if(_215){if(_215.removeEventListener){_215.removeEventListener("load",b.onloadHandler,false);}else{_215.detachEvent("onload",b.onloadHandler);}}dojo.removeAttr(node,_214);delete this._bindings[bid];}},_scheduleOpen:function(_216,_217,_218){if(!this._openTimer){this._openTimer=setTimeout(dojo.hitch(this,function(){delete this._openTimer;this._openMyself({target:_216,iframe:_217,coords:_218});}),1);}},_openMyself:function(args){var _219=args.target,_21a=args.iframe,_21b=args.coords;if(_21b){if(_21a){var od=_219.ownerDocument,ifc=dojo.position(_21a,true),win=this._iframeContentWindow(_21a),_21c=dojo.withGlobal(win,"_docScroll",dojo);var cs=dojo.getComputedStyle(_21a),tp=dojo._toPixelValue,left=(dojo.isIE&&dojo.isQuirks?0:tp(_21a,cs.paddingLeft))+(dojo.isIE&&dojo.isQuirks?tp(_21a,cs.borderLeftWidth):0),top=(dojo.isIE&&dojo.isQuirks?0:tp(_21a,cs.paddingTop))+(dojo.isIE&&dojo.isQuirks?tp(_21a,cs.borderTopWidth):0);_21b.x+=ifc.x+left-_21c.x;_21b.y+=ifc.y+top-_21c.y;}}else{_21b=dojo.position(_219,true);_21b.x+=10;_21b.y+=10;}var self=this;var _21d=dijit.getFocus(this);function _21e(){if(self.refocus){dijit.focus(_21d);}dijit.popup.close(self);};dijit.popup.open({popup:this,x:_21b.x,y:_21b.y,onExecute:_21e,onCancel:_21e,orient:this.isLeftToRight()?"L":"R"});this.focus();this._onBlur=function(){this.inherited("_onBlur",arguments);dijit.popup.close(this);};},uninitialize:function(){dojo.forEach(this._bindings,function(b){if(b){this.unBindDomNode(b.node);}},this);this.inherited(arguments);}});}if(!dojo._hasResource["dojox.html.metrics"]){dojo._hasResource["dojox.html.metrics"]=true;dojo.provide("dojox.html.metrics");(function(){var dhm=dojox.html.metrics;dhm.getFontMeasurements=function(){var _21f={"1em":0,"1ex":0,"100%":0,"12pt":0,"16px":0,"xx-small":0,"x-small":0,"small":0,"medium":0,"large":0,"x-large":0,"xx-large":0};if(dojo.isIE){dojo.doc.documentElement.style.fontSize="100%";}var div=dojo.doc.createElement("div");var ds=div.style;ds.position="absolute";ds.left="-100px";ds.top="0";ds.width="30px";ds.height="1000em";ds.borderWidth="0";ds.margin="0";ds.padding="0";ds.outline="0";ds.lineHeight="1";ds.overflow="hidden";dojo.body().appendChild(div);for(var p in _21f){ds.fontSize=p;_21f[p]=Math.round(div.offsetHeight*12/16)*16/12/1000;}dojo.body().removeChild(div);div=null;return _21f;};var _220=null;dhm.getCachedFontMeasurements=function(_221){if(_221||!_220){_220=dhm.getFontMeasurements();}return _220;};var _222=null,_223={};dhm.getTextBox=function(text,_224,_225){var m,s;if(!_222){m=_222=dojo.doc.createElement("div");var c=dojo.doc.createElement("div");c.appendChild(m);s=c.style;s.overflow="scroll";s.position="absolute";s.left="0px";s.top="-10000px";s.width="1px";s.height="1px";s.visibility="hidden";s.borderWidth="0";s.margin="0";s.padding="0";s.outline="0";dojo.body().appendChild(c);}else{m=_222;}m.className="";s=m.style;s.borderWidth="0";s.margin="0";s.padding="0";s.outline="0";if(arguments.length>1&&_224){for(var i in _224){if(i in _223){continue;}s[i]=_224[i];}}if(arguments.length>2&&_225){m.className=_225;}m.innerHTML=text;var box=dojo.position(m);box.w=m.parentNode.scrollWidth;return box;};var _226={w:16,h:16};dhm.getScrollbar=function(){return {w:_226.w,h:_226.h};};dhm._fontResizeNode=null;dhm.initOnFontResize=function(_227){var f=dhm._fontResizeNode=dojo.doc.createElement("iframe");var fs=f.style;fs.position="absolute";fs.width="5em";fs.height="10em";fs.top="-10000px";if(dojo.isIE){f.onreadystatechange=function(){if(f.contentWindow.document.readyState=="complete"){f.onresize=f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize;}};}else{f.onload=function(){f.contentWindow.onresize=f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize;};}f.setAttribute("src","javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'");dojo.body().appendChild(f);dhm.initOnFontResize=function(){};};dhm.onFontResize=function(){};dhm._fontresize=function(){dhm.onFontResize();};dojo.addOnUnload(function(){var f=dhm._fontResizeNode;if(f){if(dojo.isIE&&f.onresize){f.onresize=null;}else{if(f.contentWindow&&f.contentWindow.onresize){f.contentWindow.onresize=null;}}dhm._fontResizeNode=null;}});dojo.addOnLoad(function(){try{var n=dojo.doc.createElement("div");n.style.cssText="top:0;left:0;width:100px;height:100px;overflow:scroll;position:absolute;visibility:hidden;";dojo.body().appendChild(n);_226.w=n.offsetWidth-n.clientWidth;_226.h=n.offsetHeight-n.clientHeight;dojo.body().removeChild(n);delete n;}catch(e){}if("fontSizeWatch" in dojo.config&&!!dojo.config.fontSizeWatch){dhm.initOnFontResize();}});})();}if(!dojo._hasResource["dojox.grid.util"]){dojo._hasResource["dojox.grid.util"]=true;dojo.provide("dojox.grid.util");(function(){var dgu=dojox.grid.util;dgu.na="...";dgu.rowIndexTag="gridRowIndex";dgu.gridViewTag="gridView";dgu.fire=function(ob,ev,args){var fn=ob&&ev&&ob[ev];return fn&&(args?fn.apply(ob,args):ob[ev]());};dgu.setStyleHeightPx=function(_228,_229){if(_229>=0){var s=_228.style;var v=_229+"px";if(_228&&s["height"]!=v){s["height"]=v;}}};dgu.mouseEvents=["mouseover","mouseout","mousedown","mouseup","click","dblclick","contextmenu"];dgu.keyEvents=["keyup","keydown","keypress"];dgu.funnelEvents=function(_22a,_22b,_22c,_22d){var evts=(_22d?_22d:dgu.mouseEvents.concat(dgu.keyEvents));for(var i=0,l=evts.length;i<l;i++){_22b.connect(_22a,"on"+evts[i],_22c);}};dgu.removeNode=function(_22e){_22e=dojo.byId(_22e);_22e&&_22e.parentNode&&_22e.parentNode.removeChild(_22e);return _22e;};dgu.arrayCompare=function(inA,inB){for(var i=0,l=inA.length;i<l;i++){if(inA[i]!=inB[i]){return false;}}return (inA.length==inB.length);};dgu.arrayInsert=function(_22f,_230,_231){if(_22f.length<=_230){_22f[_230]=_231;}else{_22f.splice(_230,0,_231);}};dgu.arrayRemove=function(_232,_233){_232.splice(_233,1);};dgu.arraySwap=function(_234,inI,inJ){var _235=_234[inI];_234[inI]=_234[inJ];_234[inJ]=_235;};})();}if(!dojo._hasResource["dojox.grid._Scroller"]){dojo._hasResource["dojox.grid._Scroller"]=true;dojo.provide("dojox.grid._Scroller");(function(){var _236=function(_237){var i=0,n,p=_237.parentNode;while((n=p.childNodes[i++])){if(n==_237){return i-1;}}return -1;};var _238=function(_239){if(!_239){return;}var _23a=function(inW){return inW.domNode&&dojo.isDescendant(inW.domNode,_239,true);};var ws=dijit.registry.filter(_23a);for(var i=0,w;(w=ws[i]);i++){w.destroy();}delete ws;};var _23b=function(_23c){var node=dojo.byId(_23c);return (node&&node.tagName?node.tagName.toLowerCase():"");};var _23d=function(_23e,_23f){var _240=[];var i=0,n;while((n=_23e.childNodes[i])){i++;if(_23b(n)==_23f){_240.push(n);}}return _240;};var _241=function(_242){return _23d(_242,"div");};dojo.declare("dojox.grid._Scroller",null,{constructor:function(_243){this.setContentNodes(_243);this.pageHeights=[];this.pageNodes=[];this.stack=[];},rowCount:0,defaultRowHeight:32,keepRows:100,contentNode:null,scrollboxNode:null,defaultPageHeight:0,keepPages:10,pageCount:0,windowHeight:0,firstVisibleRow:0,lastVisibleRow:0,averageRowHeight:0,page:0,pageTop:0,init:function(_244,_245,_246){switch(arguments.length){case 3:this.rowsPerPage=_246;case 2:this.keepRows=_245;case 1:this.rowCount=_244;default:break;}this.defaultPageHeight=this.defaultRowHeight*this.rowsPerPage;this.pageCount=this._getPageCount(this.rowCount,this.rowsPerPage);this.setKeepInfo(this.keepRows);this.invalidate();if(this.scrollboxNode){this.scrollboxNode.scrollTop=0;this.scroll(0);this.scrollboxNode.onscroll=dojo.hitch(this,"onscroll");}},_getPageCount:function(_247,_248){return _247?(Math.ceil(_247/_248)||1):0;},destroy:function(){this.invalidateNodes();delete this.contentNodes;delete this.contentNode;delete this.scrollboxNode;},setKeepInfo:function(_249){this.keepRows=_249;this.keepPages=!this.keepRows?this.keepPages:Math.max(Math.ceil(this.keepRows/this.rowsPerPage),2);},setContentNodes:function(_24a){this.contentNodes=_24a;this.colCount=(this.contentNodes?this.contentNodes.length:0);this.pageNodes=[];for(var i=0;i<this.colCount;i++){this.pageNodes[i]=[];}},getDefaultNodes:function(){return this.pageNodes[0]||[];},invalidate:function(){this._invalidating=true;this.invalidateNodes();this.pageHeights=[];this.height=(this.pageCount?(this.pageCount-1)*this.defaultPageHeight+this.calcLastPageHeight():0);this.resize();this._invalidating=false;},updateRowCount:function(_24b){this.invalidateNodes();this.rowCount=_24b;var _24c=this.pageCount;if(_24c===0){this.height=1;}this.pageCount=this._getPageCount(this.rowCount,this.rowsPerPage);if(this.pageCount<_24c){for(var i=_24c-1;i>=this.pageCount;i--){this.height-=this.getPageHeight(i);delete this.pageHeights[i];}}else{if(this.pageCount>_24c){this.height+=this.defaultPageHeight*(this.pageCount-_24c-1)+this.calcLastPageHeight();}}this.resize();},pageExists:function(_24d){return Boolean(this.getDefaultPageNode(_24d));},measurePage:function(_24e){if(this.grid.rowHeight){var _24f=this.grid.rowHeight+1;return ((_24e+1)*this.rowsPerPage>this.rowCount?this.rowCount-_24e*this.rowsPerPage:this.rowsPerPage)*_24f;}var n=this.getDefaultPageNode(_24e);return (n&&n.innerHTML)?n.offsetHeight:undefined;},positionPage:function(_250,_251){for(var i=0;i<this.colCount;i++){this.pageNodes[i][_250].style.top=_251+"px";}},repositionPages:function(_252){var _253=this.getDefaultNodes();var last=0;for(var i=0;i<this.stack.length;i++){last=Math.max(this.stack[i],last);}var n=_253[_252];var y=(n?this.getPageNodePosition(n)+this.getPageHeight(_252):0);for(var p=_252+1;p<=last;p++){n=_253[p];if(n){if(this.getPageNodePosition(n)==y){return;}this.positionPage(p,y);}y+=this.getPageHeight(p);}},installPage:function(_254){for(var i=0;i<this.colCount;i++){this.contentNodes[i].appendChild(this.pageNodes[i][_254]);}},preparePage:function(_255,_256){var p=(_256?this.popPage():null);for(var i=0;i<this.colCount;i++){var _257=this.pageNodes[i];var _258=(p===null?this.createPageNode():this.invalidatePageNode(p,_257));_258.pageIndex=_255;_257[_255]=_258;}},renderPage:function(_259){var _25a=[];var i,j;for(i=0;i<this.colCount;i++){_25a[i]=this.pageNodes[i][_259];}for(i=0,j=_259*this.rowsPerPage;(i<this.rowsPerPage)&&(j<this.rowCount);i++,j++){this.renderRow(j,_25a);}},removePage:function(_25b){for(var i=0,j=_25b*this.rowsPerPage;i<this.rowsPerPage;i++,j++){this.removeRow(j);}},destroyPage:function(_25c){for(var i=0;i<this.colCount;i++){var n=this.invalidatePageNode(_25c,this.pageNodes[i]);if(n){dojo.destroy(n);}}},pacify:function(_25d){},pacifying:false,pacifyTicks:200,setPacifying:function(_25e){if(this.pacifying!=_25e){this.pacifying=_25e;this.pacify(this.pacifying);}},startPacify:function(){this.startPacifyTicks=new Date().getTime();},doPacify:function(){var _25f=(new Date().getTime()-this.startPacifyTicks)>this.pacifyTicks;this.setPacifying(true);this.startPacify();return _25f;},endPacify:function(){this.setPacifying(false);},resize:function(){if(this.scrollboxNode){this.windowHeight=this.scrollboxNode.clientHeight;}for(var i=0;i<this.colCount;i++){dojox.grid.util.setStyleHeightPx(this.contentNodes[i],Math.max(1,this.height));}var _260=(!this._invalidating);if(!_260){var ah=this.grid.get("autoHeight");if(typeof ah=="number"&&ah<=Math.min(this.rowsPerPage,this.rowCount)){_260=true;}}if(_260){this.needPage(this.page,this.pageTop);}var _261=(this.page<this.pageCount-1)?this.rowsPerPage:((this.rowCount%this.rowsPerPage)||this.rowsPerPage);var _262=this.getPageHeight(this.page);this.averageRowHeight=(_262>0&&_261>0)?(_262/_261):0;},calcLastPageHeight:function(){if(!this.pageCount){return 0;}var _263=this.pageCount-1;var _264=((this.rowCount%this.rowsPerPage)||(this.rowsPerPage))*this.defaultRowHeight;this.pageHeights[_263]=_264;return _264;},updateContentHeight:function(inDh){this.height+=inDh;this.resize();},updatePageHeight:function(_265,_266,_267){if(this.pageExists(_265)){var oh=this.getPageHeight(_265);var h=(this.measurePage(_265));if(h===undefined){h=oh;}this.pageHeights[_265]=h;if(oh!=h){this.updateContentHeight(h-oh);var ah=this.grid.get("autoHeight");if((typeof ah=="number"&&ah>this.rowCount)||(ah===true&&!_266)){if(!_267){this.grid.sizeChange();}else{var ns=this.grid.viewsNode.style;ns.height=parseInt(ns.height)+h-oh+"px";this.repositionPages(_265);}}else{this.repositionPages(_265);}}return h;}return 0;},rowHeightChanged:function(_268,_269){this.updatePageHeight(Math.floor(_268/this.rowsPerPage),false,_269);},invalidateNodes:function(){while(this.stack.length){this.destroyPage(this.popPage());}},createPageNode:function(){var p=document.createElement("div");dojo.attr(p,"role","presentation");p.style.position="absolute";p.style[dojo._isBodyLtr()?"left":"right"]="0";return p;},getPageHeight:function(_26a){var ph=this.pageHeights[_26a];return (ph!==undefined?ph:this.defaultPageHeight);},pushPage:function(_26b){return this.stack.push(_26b);},popPage:function(){return this.stack.shift();},findPage:function(_26c){var i=0,h=0;for(var ph=0;i<this.pageCount;i++,h+=ph){ph=this.getPageHeight(i);if(h+ph>=_26c){break;}}this.page=i;this.pageTop=h;},buildPage:function(_26d,_26e,_26f){this.preparePage(_26d,_26e);this.positionPage(_26d,_26f);this.installPage(_26d);this.renderPage(_26d);this.pushPage(_26d);},needPage:function(_270,_271){var h=this.getPageHeight(_270),oh=h;if(!this.pageExists(_270)){this.buildPage(_270,(!this.grid._autoHeight&&this.keepPages&&(this.stack.length>=this.keepPages)),_271);h=this.updatePageHeight(_270,true);}else{this.positionPage(_270,_271);}return h;},onscroll:function(){this.scroll(this.scrollboxNode.scrollTop);},scroll:function(_272){this.grid.scrollTop=_272;if(this.colCount){this.startPacify();this.findPage(_272);var h=this.height;var b=this.getScrollBottom(_272);for(var p=this.page,y=this.pageTop;(p<this.pageCount)&&((b<0)||(y<b));p++){y+=this.needPage(p,y);}this.firstVisibleRow=this.getFirstVisibleRow(this.page,this.pageTop,_272);this.lastVisibleRow=this.getLastVisibleRow(p-1,y,b);if(h!=this.height){this.repositionPages(p-1);}this.endPacify();}},getScrollBottom:function(_273){return (this.windowHeight>=0?_273+this.windowHeight:-1);},processNodeEvent:function(e,_274){var t=e.target;while(t&&(t!=_274)&&t.parentNode&&(t.parentNode.parentNode!=_274)){t=t.parentNode;}if(!t||!t.parentNode||(t.parentNode.parentNode!=_274)){return false;}var page=t.parentNode;e.topRowIndex=page.pageIndex*this.rowsPerPage;e.rowIndex=e.topRowIndex+_236(t);e.rowTarget=t;return true;},processEvent:function(e){return this.processNodeEvent(e,this.contentNode);},renderRow:function(_275,_276){},removeRow:function(_277){},getDefaultPageNode:function(_278){return this.getDefaultNodes()[_278];},positionPageNode:function(_279,_27a){},getPageNodePosition:function(_27b){return _27b.offsetTop;},invalidatePageNode:function(_27c,_27d){var p=_27d[_27c];if(p){delete _27d[_27c];this.removePage(_27c,p);_238(p);p.innerHTML="";}return p;},getPageRow:function(_27e){return _27e*this.rowsPerPage;},getLastPageRow:function(_27f){return Math.min(this.rowCount,this.getPageRow(_27f+1))-1;},getFirstVisibleRow:function(_280,_281,_282){if(!this.pageExists(_280)){return 0;}var row=this.getPageRow(_280);var _283=this.getDefaultNodes();var rows=_241(_283[_280]);for(var i=0,l=rows.length;i<l&&_281<_282;i++,row++){_281+=rows[i].offsetHeight;}return (row?row-1:row);},getLastVisibleRow:function(_284,_285,_286){if(!this.pageExists(_284)){return 0;}var _287=this.getDefaultNodes();var row=this.getLastPageRow(_284);var rows=_241(_287[_284]);for(var i=rows.length-1;i>=0&&_285>_286;i--,row--){_285-=rows[i].offsetHeight;}return row+1;},findTopRow:function(_288){var _289=this.getDefaultNodes();var rows=_241(_289[this.page]);for(var i=0,l=rows.length,t=this.pageTop,h;i<l;i++){h=rows[i].offsetHeight;t+=h;if(t>=_288){this.offset=h-(t-_288);return i+this.page*this.rowsPerPage;}}return -1;},findScrollTop:function(_28a){var _28b=Math.floor(_28a/this.rowsPerPage);var t=0;var i,l;for(i=0;i<_28b;i++){t+=this.getPageHeight(i);}this.pageTop=t;this.page=_28b;this.needPage(_28b,this.pageTop);var _28c=this.getDefaultNodes();var rows=_241(_28c[_28b]);var r=_28a-this.rowsPerPage*_28b;for(i=0,l=rows.length;i<l&&i<r;i++){t+=rows[i].offsetHeight;}return t;},dummy:0});})();}if(!dojo._hasResource["dojox.grid.cells._base"]){dojo._hasResource["dojox.grid.cells._base"]=true;dojo.provide("dojox.grid.cells._base");dojo.declare("dojox.grid._DeferredTextWidget",dijit._Widget,{deferred:null,_destroyOnRemove:true,postCreate:function(){if(this.deferred){this.deferred.addBoth(dojo.hitch(this,function(text){if(this.domNode){this.domNode.innerHTML=text;}}));}}});(function(){var _28d=function(_28e){try{dojox.grid.util.fire(_28e,"focus");dojox.grid.util.fire(_28e,"select");}catch(e){}};var _28f=function(){setTimeout(dojo.hitch.apply(dojo,arguments),0);};var dgc=dojox.grid.cells;dojo.declare("dojox.grid.cells._Base",null,{styles:"",classes:"",editable:false,alwaysEditing:false,formatter:null,defaultValue:"...",value:null,hidden:false,noresize:false,draggable:true,_valueProp:"value",_formatPending:false,constructor:function(_290){this._props=_290||{};dojo.mixin(this,_290);if(this.draggable===undefined){this.draggable=true;}},_defaultFormat:function(_291,_292){var s=this.grid.formatterScope||this;var f=this.formatter;if(f&&s&&typeof f=="string"){f=this.formatter=s[f];}var v=(_291!=this.defaultValue&&f)?f.apply(s,_292):_291;if(typeof v=="undefined"){return this.defaultValue;}if(v&&v.addBoth){v=new dojox.grid._DeferredTextWidget({deferred:v},dojo.create("span",{innerHTML:this.defaultValue}));}if(v&&v.declaredClass&&v.startup){return "<div class='dojoxGridStubNode' linkWidget='"+v.id+"' cellIdx='"+this.index+"'>"+this.defaultValue+"</div>";}return v;},format:function(_293,_294){var f,i=this.grid.edit.info,d=this.get?this.get(_293,_294):(this.value||this.defaultValue);d=(d&&d.replace&&this.grid.escapeHTMLInData)?d.replace(/&/g,"&amp;").replace(/</g,"&lt;"):d;if(this.editable&&(this.alwaysEditing||(i.rowIndex==_293&&i.cell==this))){return this.formatEditing(d,_293);}else{return this._defaultFormat(d,[d,_293,this]);}},formatEditing:function(_295,_296){},getNode:function(_297){return this.view.getCellNode(_297,this.index);},getHeaderNode:function(){return this.view.getHeaderCellNode(this.index);},getEditNode:function(_298){return (this.getNode(_298)||0).firstChild||0;},canResize:function(){var uw=this.unitWidth;return uw&&(uw!=="auto");},isFlex:function(){var uw=this.unitWidth;return uw&&dojo.isString(uw)&&(uw=="auto"||uw.slice(-1)=="%");},applyEdit:function(_299,_29a){this.grid.edit.applyCellEdit(_299,this,_29a);},cancelEdit:function(_29b){this.grid.doCancelEdit(_29b);},_onEditBlur:function(_29c){if(this.grid.edit.isEditCell(_29c,this.index)){this.grid.edit.apply();}},registerOnBlur:function(_29d,_29e){if(this.commitOnBlur){dojo.connect(_29d,"onblur",function(e){setTimeout(dojo.hitch(this,"_onEditBlur",_29e),250);});}},needFormatNode:function(_29f,_2a0){this._formatPending=true;_28f(this,"_formatNode",_29f,_2a0);},cancelFormatNode:function(){this._formatPending=false;},_formatNode:function(_2a1,_2a2){if(this._formatPending){this._formatPending=false;dojo.setSelectable(this.grid.domNode,true);this.formatNode(this.getEditNode(_2a2),_2a1,_2a2);}},formatNode:function(_2a3,_2a4,_2a5){if(dojo.isIE){_28f(this,"focus",_2a5,_2a3);}else{this.focus(_2a5,_2a3);}},dispatchEvent:function(m,e){if(m in this){return this[m](e);}},getValue:function(_2a6){return this.getEditNode(_2a6)[this._valueProp];},setValue:function(_2a7,_2a8){var n=this.getEditNode(_2a7);if(n){n[this._valueProp]=_2a8;}},focus:function(_2a9,_2aa){_28d(_2aa||this.getEditNode(_2a9));},save:function(_2ab){this.value=this.value||this.getValue(_2ab);},restore:function(_2ac){this.setValue(_2ac,this.value);},_finish:function(_2ad){dojo.setSelectable(this.grid.domNode,false);this.cancelFormatNode();},apply:function(_2ae){this.applyEdit(this.getValue(_2ae),_2ae);this._finish(_2ae);},cancel:function(_2af){this.cancelEdit(_2af);this._finish(_2af);}});dgc._Base.markupFactory=function(node,_2b0){var d=dojo;var _2b1=d.trim(d.attr(node,"formatter")||"");if(_2b1){_2b0.formatter=dojo.getObject(_2b1)||_2b1;}var get=d.trim(d.attr(node,"get")||"");if(get){_2b0.get=dojo.getObject(get);}var _2b2=function(attr,cell,_2b3){var _2b4=d.trim(d.attr(node,attr)||"");if(_2b4){cell[_2b3||attr]=!(_2b4.toLowerCase()=="false");}};_2b2("sortDesc",_2b0);_2b2("editable",_2b0);_2b2("alwaysEditing",_2b0);_2b2("noresize",_2b0);_2b2("draggable",_2b0);var _2b5=d.trim(d.attr(node,"loadingText")||d.attr(node,"defaultValue")||"");if(_2b5){_2b0.defaultValue=_2b5;}var _2b6=function(attr,cell,_2b7){var _2b8=d.trim(d.attr(node,attr)||"")||undefined;if(_2b8){cell[_2b7||attr]=_2b8;}};_2b6("styles",_2b0);_2b6("headerStyles",_2b0);_2b6("cellStyles",_2b0);_2b6("classes",_2b0);_2b6("headerClasses",_2b0);_2b6("cellClasses",_2b0);};dojo.declare("dojox.grid.cells.Cell",dgc._Base,{constructor:function(){this.keyFilter=this.keyFilter;},keyFilter:null,formatEditing:function(_2b9,_2ba){this.needFormatNode(_2b9,_2ba);return "<input class=\"dojoxGridInput\" type=\"text\" value=\""+_2b9+"\">";},formatNode:function(_2bb,_2bc,_2bd){this.inherited(arguments);this.registerOnBlur(_2bb,_2bd);},doKey:function(e){if(this.keyFilter){var key=String.fromCharCode(e.charCode);if(key.search(this.keyFilter)==-1){dojo.stopEvent(e);}}},_finish:function(_2be){this.inherited(arguments);var n=this.getEditNode(_2be);try{dojox.grid.util.fire(n,"blur");}catch(e){}}});dgc.Cell.markupFactory=function(node,_2bf){dgc._Base.markupFactory(node,_2bf);var d=dojo;var _2c0=d.trim(d.attr(node,"keyFilter")||"");if(_2c0){_2bf.keyFilter=new RegExp(_2c0);}};dojo.declare("dojox.grid.cells.RowIndex",dgc.Cell,{name:"Row",postscript:function(){this.editable=false;},get:function(_2c1){return _2c1+1;}});dgc.RowIndex.markupFactory=function(node,_2c2){dgc.Cell.markupFactory(node,_2c2);};dojo.declare("dojox.grid.cells.Select",dgc.Cell,{options:null,values:null,returnIndex:-1,constructor:function(_2c3){this.values=this.values||this.options;},formatEditing:function(_2c4,_2c5){this.needFormatNode(_2c4,_2c5);var h=["<select class=\"dojoxGridSelect\">"];for(var i=0,o,v;((o=this.options[i])!==undefined)&&((v=this.values[i])!==undefined);i++){h.push("<option",(_2c4==v?" selected":"")," value=\""+v+"\"",">",o,"</option>");}h.push("</select>");return h.join("");},getValue:function(_2c6){var n=this.getEditNode(_2c6);if(n){var i=n.selectedIndex,o=n.options[i];return this.returnIndex>-1?i:o.value||o.innerHTML;}}});dgc.Select.markupFactory=function(node,cell){dgc.Cell.markupFactory(node,cell);var d=dojo;var _2c7=d.trim(d.attr(node,"options")||"");if(_2c7){var o=_2c7.split(",");if(o[0]!=_2c7){cell.options=o;}}var _2c8=d.trim(d.attr(node,"values")||"");if(_2c8){var v=_2c8.split(",");if(v[0]!=_2c8){cell.values=v;}}};dojo.declare("dojox.grid.cells.AlwaysEdit",dgc.Cell,{alwaysEditing:true,_formatNode:function(_2c9,_2ca){this.formatNode(this.getEditNode(_2ca),_2c9,_2ca);},applyStaticValue:function(_2cb){var e=this.grid.edit;e.applyCellEdit(this.getValue(_2cb),this,_2cb);e.start(this,_2cb,true);}});dgc.AlwaysEdit.markupFactory=function(node,cell){dgc.Cell.markupFactory(node,cell);};dojo.declare("dojox.grid.cells.Bool",dgc.AlwaysEdit,{_valueProp:"checked",formatEditing:function(_2cc,_2cd){return "<input class=\"dojoxGridInput\" type=\"checkbox\""+(_2cc?" checked=\"checked\"":"")+" style=\"width: auto\" />";},doclick:function(e){if(e.target.tagName=="INPUT"){this.applyStaticValue(e.rowIndex);}}});dgc.Bool.markupFactory=function(node,cell){dgc.AlwaysEdit.markupFactory(node,cell);};})();}if(!dojo._hasResource["dojox.grid.cells"]){dojo._hasResource["dojox.grid.cells"]=true;dojo.provide("dojox.grid.cells");}if(!dojo._hasResource["dojo.dnd.common"]){dojo._hasResource["dojo.dnd.common"]=true;dojo.provide("dojo.dnd.common");dojo.getObject("dnd",true,dojo);dojo.dnd.getCopyKeyState=dojo.isCopyKey;dojo.dnd._uniqueId=0;dojo.dnd.getUniqueId=function(){var id;do{id=dojo._scopeName+"Unique"+(++dojo.dnd._uniqueId);}while(dojo.byId(id));return id;};dojo.dnd._empty={};dojo.dnd.isFormElement=function(e){var t=e.target;if(t.nodeType==3){t=t.parentNode;}return " button textarea input select option ".indexOf(" "+t.tagName.toLowerCase()+" ")>=0;};}if(!dojo._hasResource["dojo.dnd.autoscroll"]){dojo._hasResource["dojo.dnd.autoscroll"]=true;dojo.provide("dojo.dnd.autoscroll");dojo.getObject("dnd",true,dojo);dojo.dnd.getViewport=dojo.window.getBox;dojo.dnd.V_TRIGGER_AUTOSCROLL=32;dojo.dnd.H_TRIGGER_AUTOSCROLL=32;dojo.dnd.V_AUTOSCROLL_VALUE=16;dojo.dnd.H_AUTOSCROLL_VALUE=16;dojo.dnd.autoScroll=function(e){var v=dojo.window.getBox(),dx=0,dy=0;if(e.clientX<dojo.dnd.H_TRIGGER_AUTOSCROLL){dx=-dojo.dnd.H_AUTOSCROLL_VALUE;}else{if(e.clientX>v.w-dojo.dnd.H_TRIGGER_AUTOSCROLL){dx=dojo.dnd.H_AUTOSCROLL_VALUE;}}if(e.clientY<dojo.dnd.V_TRIGGER_AUTOSCROLL){dy=-dojo.dnd.V_AUTOSCROLL_VALUE;}else{if(e.clientY>v.h-dojo.dnd.V_TRIGGER_AUTOSCROLL){dy=dojo.dnd.V_AUTOSCROLL_VALUE;}}window.scrollBy(dx,dy);};dojo.dnd._validNodes={"div":1,"p":1,"td":1};dojo.dnd._validOverflow={"auto":1,"scroll":1};dojo.dnd.autoScrollNodes=function(e){for(var n=e.target;n;){if(n.nodeType==1&&(n.tagName.toLowerCase() in dojo.dnd._validNodes)){var s=dojo.getComputedStyle(n);if(s.overflow.toLowerCase() in dojo.dnd._validOverflow){var b=dojo._getContentBox(n,s),t=dojo.position(n,true);var w=Math.min(dojo.dnd.H_TRIGGER_AUTOSCROLL,b.w/2),h=Math.min(dojo.dnd.V_TRIGGER_AUTOSCROLL,b.h/2),rx=e.pageX-t.x,ry=e.pageY-t.y,dx=0,dy=0;if(dojo.isWebKit||dojo.isOpera){rx+=dojo.body().scrollLeft;ry+=dojo.body().scrollTop;}if(rx>0&&rx<b.w){if(rx<w){dx=-w;}else{if(rx>b.w-w){dx=w;}}}if(ry>0&&ry<b.h){if(ry<h){dy=-h;}else{if(ry>b.h-h){dy=h;}}}var _2ce=n.scrollLeft,_2cf=n.scrollTop;n.scrollLeft=n.scrollLeft+dx;n.scrollTop=n.scrollTop+dy;if(_2ce!=n.scrollLeft||_2cf!=n.scrollTop){return;}}}try{n=n.parentNode;}catch(x){n=null;}}dojo.dnd.autoScroll(e);};}if(!dojo._hasResource["dojo.dnd.Mover"]){dojo._hasResource["dojo.dnd.Mover"]=true;dojo.provide("dojo.dnd.Mover");dojo.declare("dojo.dnd.Mover",null,{constructor:function(node,e,host){this.node=dojo.byId(node);var pos=e.touches?e.touches[0]:e;this.marginBox={l:pos.pageX,t:pos.pageY};this.mouseButton=e.button;var h=(this.host=host),d=node.ownerDocument;this.events=[dojo.connect(d,"onmousemove",this,"onFirstMove"),dojo.connect(d,"ontouchmove",this,"onFirstMove"),dojo.connect(d,"onmousemove",this,"onMouseMove"),dojo.connect(d,"ontouchmove",this,"onMouseMove"),dojo.connect(d,"onmouseup",this,"onMouseUp"),dojo.connect(d,"ontouchend",this,"onMouseUp"),dojo.connect(d,"ondragstart",dojo.stopEvent),dojo.connect(d.body,"onselectstart",dojo.stopEvent)];if(h&&h.onMoveStart){h.onMoveStart(this);}},onMouseMove:function(e){dojo.dnd.autoScroll(e);var m=this.marginBox,pos=e.touches?e.touches[0]:e;this.host.onMove(this,{l:m.l+pos.pageX,t:m.t+pos.pageY},e);dojo.stopEvent(e);},onMouseUp:function(e){if(dojo.isWebKit&&dojo.isMac&&this.mouseButton==2?e.button==0:this.mouseButton==e.button){this.destroy();}dojo.stopEvent(e);},onFirstMove:function(e){var s=this.node.style,l,t,h=this.host;switch(s.position){case "relative":case "absolute":l=Math.round(parseFloat(s.left))||0;t=Math.round(parseFloat(s.top))||0;break;default:s.position="absolute";var m=dojo.marginBox(this.node);var b=dojo.doc.body;var bs=dojo.getComputedStyle(b);var bm=dojo._getMarginBox(b,bs);var bc=dojo._getContentBox(b,bs);l=m.l-(bc.l-bm.l);t=m.t-(bc.t-bm.t);break;}this.marginBox.l=l-this.marginBox.l;this.marginBox.t=t-this.marginBox.t;if(h&&h.onFirstMove){h.onFirstMove(this,e);}dojo.disconnect(this.events.shift());dojo.disconnect(this.events.shift());},destroy:function(){dojo.forEach(this.events,dojo.disconnect);var h=this.host;if(h&&h.onMoveStop){h.onMoveStop(this);}this.events=this.node=this.host=null;}});}if(!dojo._hasResource["dojo.dnd.Moveable"]){dojo._hasResource["dojo.dnd.Moveable"]=true;dojo.provide("dojo.dnd.Moveable");dojo.declare("dojo.dnd.Moveable",null,{handle:"",delay:0,skip:false,constructor:function(node,_2d0){this.node=dojo.byId(node);if(!_2d0){_2d0={};}this.handle=_2d0.handle?dojo.byId(_2d0.handle):null;if(!this.handle){this.handle=this.node;}this.delay=_2d0.delay>0?_2d0.delay:0;this.skip=_2d0.skip;this.mover=_2d0.mover?_2d0.mover:dojo.dnd.Mover;this.events=[dojo.connect(this.handle,"onmousedown",this,"onMouseDown"),dojo.connect(this.handle,"ontouchstart",this,"onMouseDown"),dojo.connect(this.handle,"ondragstart",this,"onSelectStart"),dojo.connect(this.handle,"onselectstart",this,"onSelectStart")];},markupFactory:function(_2d1,node){return new dojo.dnd.Moveable(node,_2d1);},destroy:function(){dojo.forEach(this.events,dojo.disconnect);this.events=this.node=this.handle=null;},onMouseDown:function(e){if(this.skip&&dojo.dnd.isFormElement(e)){return;}if(this.delay){this.events.push(dojo.connect(this.handle,"onmousemove",this,"onMouseMove"),dojo.connect(this.handle,"ontouchmove",this,"onMouseMove"),dojo.connect(this.handle,"onmouseup",this,"onMouseUp"),dojo.connect(this.handle,"ontouchend",this,"onMouseUp"));var pos=e.touches?e.touches[0]:e;this._lastX=pos.pageX;this._lastY=pos.pageY;}else{this.onDragDetected(e);}dojo.stopEvent(e);},onMouseMove:function(e){var pos=e.touches?e.touches[0]:e;if(Math.abs(pos.pageX-this._lastX)>this.delay||Math.abs(pos.pageY-this._lastY)>this.delay){this.onMouseUp(e);this.onDragDetected(e);}dojo.stopEvent(e);},onMouseUp:function(e){for(var i=0;i<2;++i){dojo.disconnect(this.events.pop());}dojo.stopEvent(e);},onSelectStart:function(e){if(!this.skip||!dojo.dnd.isFormElement(e)){dojo.stopEvent(e);}},onDragDetected:function(e){new this.mover(this.node,e,this);},onMoveStart:function(_2d2){dojo.publish("/dnd/move/start",[_2d2]);dojo.addClass(dojo.body(),"dojoMove");dojo.addClass(this.node,"dojoMoveItem");},onMoveStop:function(_2d3){dojo.publish("/dnd/move/stop",[_2d3]);dojo.removeClass(dojo.body(),"dojoMove");dojo.removeClass(this.node,"dojoMoveItem");},onFirstMove:function(_2d4,e){},onMove:function(_2d5,_2d6,e){this.onMoving(_2d5,_2d6);var s=_2d5.node.style;s.left=_2d6.l+"px";s.top=_2d6.t+"px";this.onMoved(_2d5,_2d6);},onMoving:function(_2d7,_2d8){},onMoved:function(_2d9,_2da){}});}if(!dojo._hasResource["dojox.grid._Builder"]){dojo._hasResource["dojox.grid._Builder"]=true;dojo.provide("dojox.grid._Builder");(function(){var dg=dojox.grid;var _2db=function(td){return td.cellIndex>=0?td.cellIndex:dojo.indexOf(td.parentNode.cells,td);};var _2dc=function(tr){return tr.rowIndex>=0?tr.rowIndex:dojo.indexOf(tr.parentNode.childNodes,tr);};var _2dd=function(_2de,_2df){return _2de&&((_2de.rows||0)[_2df]||_2de.childNodes[_2df]);};var _2e0=function(node){for(var n=node;n&&n.tagName!="TABLE";n=n.parentNode){}return n;};var _2e1=function(_2e2,_2e3){for(var n=_2e2;n&&_2e3(n);n=n.parentNode){}return n;};var _2e4=function(_2e5){var name=_2e5.toUpperCase();return function(node){return node.tagName!=name;};};var _2e6=dojox.grid.util.rowIndexTag;var _2e7=dojox.grid.util.gridViewTag;dg._Builder=dojo.extend(function(view){if(view){this.view=view;this.grid=view.grid;}},{view:null,_table:"<table class=\"dojoxGridRowTable\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" role=\"presentation\"",getTableArray:function(){var html=[this._table];if(this.view.viewWidth){html.push([" style=\"width:",this.view.viewWidth,";\""].join(""));}html.push(">");return html;},generateCellMarkup:function(_2e8,_2e9,_2ea,_2eb){var _2ec=[],html;if(_2eb){var _2ed=_2e8.index!=_2e8.grid.getSortIndex()?"":_2e8.grid.sortInfo>0?"aria-sort=\"ascending\"":"aria-sort=\"descending\"";if(!_2e8.id){_2e8.id=this.grid.id+"Hdr"+_2e8.index;}html=["<th tabIndex=\"-1\" aria-readonly=\"true\" role=\"columnheader\"",_2ed,"id=\"",_2e8.id,"\""];}else{var _2ee=this.grid.editable&&!_2e8.editable?"aria-readonly=\"true\"":"";html=["<td tabIndex=\"-1\" role=\"gridcell\"",_2ee];}if(_2e8.colSpan){html.push(" colspan=\"",_2e8.colSpan,"\"");}if(_2e8.rowSpan){html.push(" rowspan=\"",_2e8.rowSpan,"\"");}html.push(" class=\"dojoxGridCell ");if(_2e8.classes){html.push(_2e8.classes," ");}if(_2ea){html.push(_2ea," ");}_2ec.push(html.join(""));_2ec.push("");html=["\" idx=\"",_2e8.index,"\" style=\""];if(_2e9&&_2e9[_2e9.length-1]!=";"){_2e9+=";";}html.push(_2e8.styles,_2e9||"",_2e8.hidden?"display:none;":"");if(_2e8.unitWidth){html.push("width:",_2e8.unitWidth,";");}_2ec.push(html.join(""));_2ec.push("");html=["\""];if(_2e8.attrs){html.push(" ",_2e8.attrs);}html.push(">");_2ec.push(html.join(""));_2ec.push("");_2ec.push(_2eb?"</th>":"</td>");return _2ec;},isCellNode:function(_2ef){return Boolean(_2ef&&_2ef!=dojo.doc&&dojo.attr(_2ef,"idx"));},getCellNodeIndex:function(_2f0){return _2f0?Number(dojo.attr(_2f0,"idx")):-1;},getCellNode:function(_2f1,_2f2){for(var i=0,row;(row=_2dd(_2f1.firstChild,i));i++){for(var j=0,cell;(cell=row.cells[j]);j++){if(this.getCellNodeIndex(cell)==_2f2){return cell;}}}return null;},findCellTarget:function(_2f3,_2f4){var n=_2f3;while(n&&(!this.isCellNode(n)||(n.offsetParent&&_2e7 in n.offsetParent.parentNode&&n.offsetParent.parentNode[_2e7]!=this.view.id))&&(n!=_2f4)){n=n.parentNode;}return n!=_2f4?n:null;},baseDecorateEvent:function(e){e.dispatch="do"+e.type;e.grid=this.grid;e.sourceView=this.view;e.cellNode=this.findCellTarget(e.target,e.rowNode);e.cellIndex=this.getCellNodeIndex(e.cellNode);e.cell=(e.cellIndex>=0?this.grid.getCell(e.cellIndex):null);},findTarget:function(_2f5,_2f6){var n=_2f5;while(n&&(n!=this.domNode)&&(!(_2f6 in n)||(_2e7 in n&&n[_2e7]!=this.view.id))){n=n.parentNode;}return (n!=this.domNode)?n:null;},findRowTarget:function(_2f7){return this.findTarget(_2f7,_2e6);},isIntraNodeEvent:function(e){try{return (e.cellNode&&e.relatedTarget&&dojo.isDescendant(e.relatedTarget,e.cellNode));}catch(x){return false;}},isIntraRowEvent:function(e){try{var row=e.relatedTarget&&this.findRowTarget(e.relatedTarget);return !row&&(e.rowIndex==-1)||row&&(e.rowIndex==row.gridRowIndex);}catch(x){return false;}},dispatchEvent:function(e){if(e.dispatch in this){return this[e.dispatch](e);}return false;},domouseover:function(e){if(e.cellNode&&(e.cellNode!=this.lastOverCellNode)){this.lastOverCellNode=e.cellNode;this.grid.onMouseOver(e);}this.grid.onMouseOverRow(e);},domouseout:function(e){if(e.cellNode&&(e.cellNode==this.lastOverCellNode)&&!this.isIntraNodeEvent(e,this.lastOverCellNode)){this.lastOverCellNode=null;this.grid.onMouseOut(e);if(!this.isIntraRowEvent(e)){this.grid.onMouseOutRow(e);}}},domousedown:function(e){if(e.cellNode){this.grid.onMouseDown(e);}this.grid.onMouseDownRow(e);}});dg._ContentBuilder=dojo.extend(function(view){dg._Builder.call(this,view);},dg._Builder.prototype,{update:function(){this.prepareHtml();},prepareHtml:function(){var _2f8=this.grid.get,_2f9=this.view.structure.cells;for(var j=0,row;(row=_2f9[j]);j++){for(var i=0,cell;(cell=row[i]);i++){cell.get=cell.get||(cell.value==undefined)&&_2f8;cell.markup=this.generateCellMarkup(cell,cell.cellStyles,cell.cellClasses,false);if(!this.grid.editable&&cell.editable){this.grid.editable=true;}}}},generateHtml:function(_2fa,_2fb){var html=this.getTableArray(),v=this.view,_2fc=v.structure.cells,item=this.grid.getItem(_2fb);dojox.grid.util.fire(this.view,"onBeforeRow",[_2fb,_2fc]);for(var j=0,row;(row=_2fc[j]);j++){if(row.hidden||row.header){continue;}html.push(!row.invisible?"<tr>":"<tr class=\"dojoxGridInvisible\">");for(var i=0,cell,m,cc,cs;(cell=row[i]);i++){m=cell.markup;cc=cell.customClasses=[];cs=cell.customStyles=[];m[5]=cell.format(_2fb,item);m[1]=cc.join(" ");m[3]=cs.join(";");html.push.apply(html,m);}html.push("</tr>");}html.push("</table>");return html.join("");},decorateEvent:function(e){e.rowNode=this.findRowTarget(e.target);if(!e.rowNode){return false;}e.rowIndex=e.rowNode[_2e6];this.baseDecorateEvent(e);e.cell=this.grid.getCell(e.cellIndex);return true;}});dg._HeaderBuilder=dojo.extend(function(view){this.moveable=null;dg._Builder.call(this,view);},dg._Builder.prototype,{_skipBogusClicks:false,overResizeWidth:4,minColWidth:1,update:function(){if(this.tableMap){this.tableMap.mapRows(this.view.structure.cells);}else{this.tableMap=new dg._TableMap(this.view.structure.cells);}},generateHtml:function(_2fd,_2fe){var html=this.getTableArray(),_2ff=this.view.structure.cells;dojox.grid.util.fire(this.view,"onBeforeRow",[-1,_2ff]);for(var j=0,row;(row=_2ff[j]);j++){if(row.hidden){continue;}html.push(!row.invisible?"<tr>":"<tr class=\"dojoxGridInvisible\">");for(var i=0,cell,_300;(cell=row[i]);i++){cell.customClasses=[];cell.customStyles=[];if(this.view.simpleStructure){if(cell.draggable){if(cell.headerClasses){if(cell.headerClasses.indexOf("dojoDndItem")==-1){cell.headerClasses+=" dojoDndItem";}}else{cell.headerClasses="dojoDndItem";}}if(cell.attrs){if(cell.attrs.indexOf("dndType='gridColumn_")==-1){cell.attrs+=" dndType='gridColumn_"+this.grid.id+"'";}}else{cell.attrs="dndType='gridColumn_"+this.grid.id+"'";}}_300=this.generateCellMarkup(cell,cell.headerStyles,cell.headerClasses,true);_300[5]=(_2fe!=undefined?_2fe:_2fd(cell));_300[3]=cell.customStyles.join(";");_300[1]=cell.customClasses.join(" ");html.push(_300.join(""));}html.push("</tr>");}html.push("</table>");return html.join("");},getCellX:function(e){var n,x=e.layerX;if(dojo.isMoz){n=_2e1(e.target,_2e4("th"));x-=(n&&n.offsetLeft)||0;var t=e.sourceView.getScrollbarWidth();if(!dojo._isBodyLtr()){table=_2e1(n,_2e4("table"));x-=(table&&table.offsetLeft)||0;}}n=_2e1(e.target,function(){if(!n||n==e.cellNode){return false;}x+=(n.offsetLeft<0?0:n.offsetLeft);return true;});return x;},decorateEvent:function(e){this.baseDecorateEvent(e);e.rowIndex=-1;e.cellX=this.getCellX(e);return true;},prepareResize:function(e,mod){do{var i=_2db(e.cellNode);e.cellNode=(i?e.cellNode.parentNode.cells[i+mod]:null);e.cellIndex=(e.cellNode?this.getCellNodeIndex(e.cellNode):-1);}while(e.cellNode&&e.cellNode.style.display=="none");return Boolean(e.cellNode);},canResize:function(e){if(!e.cellNode||e.cellNode.colSpan>1){return false;}var cell=this.grid.getCell(e.cellIndex);return !cell.noresize&&cell.canResize();},overLeftResizeArea:function(e){if(dojo.hasClass(dojo.body(),"dojoDndMove")){return false;}if(dojo.isIE){var tN=e.target;if(dojo.hasClass(tN,"dojoxGridArrowButtonNode")||dojo.hasClass(tN,"dojoxGridArrowButtonChar")){return false;}}if(dojo._isBodyLtr()){return (e.cellIndex>0)&&(e.cellX>0&&e.cellX<this.overResizeWidth)&&this.prepareResize(e,-1);}var t=e.cellNode&&(e.cellX>0&&e.cellX<this.overResizeWidth);return t;},overRightResizeArea:function(e){if(dojo.hasClass(dojo.body(),"dojoDndMove")){return false;}if(dojo.isIE){var tN=e.target;if(dojo.hasClass(tN,"dojoxGridArrowButtonNode")||dojo.hasClass(tN,"dojoxGridArrowButtonChar")){return false;}}if(dojo._isBodyLtr()){return e.cellNode&&(e.cellX>=e.cellNode.offsetWidth-this.overResizeWidth);}return (e.cellIndex>0)&&(e.cellX>=e.cellNode.offsetWidth-this.overResizeWidth)&&this.prepareResize(e,-1);},domousemove:function(e){if(!this.moveable){var c=(this.overRightResizeArea(e)?"dojoxGridColResize":(this.overLeftResizeArea(e)?"dojoxGridColResize":""));if(c&&!this.canResize(e)){c="dojoxGridColNoResize";}dojo.toggleClass(e.sourceView.headerNode,"dojoxGridColNoResize",(c=="dojoxGridColNoResize"));dojo.toggleClass(e.sourceView.headerNode,"dojoxGridColResize",(c=="dojoxGridColResize"));if(dojo.isIE){var t=e.sourceView.headerNode.scrollLeft;e.sourceView.headerNode.scrollLeft=t;}if(c){dojo.stopEvent(e);}}},domousedown:function(e){if(!this.moveable){if((this.overRightResizeArea(e)||this.overLeftResizeArea(e))&&this.canResize(e)){this.beginColumnResize(e);}else{this.grid.onMouseDown(e);this.grid.onMouseOverRow(e);}}},doclick:function(e){if(this._skipBogusClicks){dojo.stopEvent(e);return true;}return false;},colResizeSetup:function(e,_301){var _302=dojo.contentBox(e.sourceView.headerNode);if(_301){this.lineDiv=document.createElement("div");var vw=(dojo.position||dojo._abs)(e.sourceView.headerNode,true);var _303=dojo.contentBox(e.sourceView.domNode);var l=e.pageX;if(!dojo._isBodyLtr()&&dojo.isIE<8){l-=dojox.html.metrics.getScrollbar().w;}dojo.style(this.lineDiv,{top:vw.y+"px",left:l+"px",height:(_303.h+_302.h)+"px"});dojo.addClass(this.lineDiv,"dojoxGridResizeColLine");this.lineDiv._origLeft=l;dojo.body().appendChild(this.lineDiv);}var _304=[],_305=this.tableMap.findOverlappingNodes(e.cellNode);for(var i=0,cell;(cell=_305[i]);i++){_304.push({node:cell,index:this.getCellNodeIndex(cell),width:cell.offsetWidth});}var view=e.sourceView;var adj=dojo._isBodyLtr()?1:-1;var _306=e.grid.views.views;var _307=[];for(var j=view.idx+adj,_308;(_308=_306[j]);j=j+adj){_307.push({node:_308.headerNode,left:window.parseInt(_308.headerNode.style.left)});}var _309=view.headerContentNode.firstChild;var drag={scrollLeft:e.sourceView.headerNode.scrollLeft,view:view,node:e.cellNode,index:e.cellIndex,w:dojo.contentBox(e.cellNode).w,vw:_302.w,table:_309,tw:dojo.contentBox(_309).w,spanners:_304,followers:_307};return drag;},beginColumnResize:function(e){this.moverDiv=document.createElement("div");dojo.style(this.moverDiv,{position:"absolute",left:0});dojo.body().appendChild(this.moverDiv);dojo.addClass(this.grid.domNode,"dojoxGridColumnResizing");var m=(this.moveable=new dojo.dnd.Moveable(this.moverDiv));var drag=this.colResizeSetup(e,true);m.onMove=dojo.hitch(this,"doResizeColumn",drag);dojo.connect(m,"onMoveStop",dojo.hitch(this,function(){this.endResizeColumn(drag);if(drag.node.releaseCapture){drag.node.releaseCapture();}this.moveable.destroy();delete this.moveable;this.moveable=null;dojo.removeClass(this.grid.domNode,"dojoxGridColumnResizing");}));if(e.cellNode.setCapture){e.cellNode.setCapture();}m.onMouseDown(e);},doResizeColumn:function(_30a,_30b,_30c){var _30d=_30c.l;var data={deltaX:_30d,w:_30a.w+(dojo._isBodyLtr()?_30d:-_30d),vw:_30a.vw+_30d,tw:_30a.tw+_30d};this.dragRecord={inDrag:_30a,mover:_30b,leftTop:_30c};if(data.w>=this.minColWidth){if(!_30b){this.doResizeNow(_30a,data);}else{dojo.style(this.lineDiv,"left",(this.lineDiv._origLeft+data.deltaX)+"px");}}},endResizeColumn:function(_30e){if(this.dragRecord){var _30f=this.dragRecord.leftTop;var _310=dojo._isBodyLtr()?_30f.l:-_30f.l;_310+=Math.max(_30e.w+_310,this.minColWidth)-(_30e.w+_310);if(dojo.isWebKit&&_30e.spanners.length){_310+=dojo._getPadBorderExtents(_30e.spanners[0].node).w;}var data={deltaX:_310,w:_30e.w+_310,vw:_30e.vw+_310,tw:_30e.tw+_310};this.doResizeNow(_30e,data);delete this.dragRecord;}dojo.destroy(this.lineDiv);dojo.destroy(this.moverDiv);dojo.destroy(this.moverDiv);delete this.moverDiv;this._skipBogusClicks=true;_30e.view.update();this._skipBogusClicks=false;this.grid.onResizeColumn(_30e.index);},doResizeNow:function(_311,data){_311.view.convertColPctToFixed();if(_311.view.flexCells&&!_311.view.testFlexCells()){var t=_2e0(_311.node);if(t){(t.style.width="");}}var i,s,sw,f,fl;for(i=0;(s=_311.spanners[i]);i++){sw=s.width+data.deltaX;s.node.style.width=sw+"px";_311.view.setColWidth(s.index,sw);}if(dojo._isBodyLtr()||!dojo.isIE){for(i=0;(f=_311.followers[i]);i++){fl=f.left+data.deltaX;f.node.style.left=fl+"px";}}_311.node.style.width=data.w+"px";_311.view.setColWidth(_311.index,data.w);_311.view.headerNode.style.width=data.vw+"px";_311.view.setColumnsWidth(data.tw);if(!dojo._isBodyLtr()){_311.view.headerNode.scrollLeft=_311.scrollLeft+data.deltaX;}}});dg._TableMap=dojo.extend(function(rows){this.mapRows(rows);},{map:null,mapRows:function(_312){var _313=_312.length;if(!_313){return;}this.map=[];var row;for(var k=0;(row=_312[k]);k++){this.map[k]=[];}for(var j=0;(row=_312[j]);j++){for(var i=0,x=0,cell,_314,_315;(cell=row[i]);i++){while(this.map[j][x]){x++;}this.map[j][x]={c:i,r:j};_315=cell.rowSpan||1;_314=cell.colSpan||1;for(var y=0;y<_315;y++){for(var s=0;s<_314;s++){this.map[j+y][x+s]=this.map[j][x];}}x+=_314;}}},dumpMap:function(){for(var j=0,row,h="";(row=this.map[j]);j++,h=""){for(var i=0,cell;(cell=row[i]);i++){h+=cell.r+","+cell.c+" ";}}},getMapCoords:function(_316,_317){for(var j=0,row;(row=this.map[j]);j++){for(var i=0,cell;(cell=row[i]);i++){if(cell.c==_317&&cell.r==_316){return {j:j,i:i};}}}return {j:-1,i:-1};},getNode:function(_318,_319,_31a){var row=_318&&_318.rows[_319];return row&&row.cells[_31a];},_findOverlappingNodes:function(_31b,_31c,_31d){var _31e=[];var m=this.getMapCoords(_31c,_31d);for(var j=0,row;(row=this.map[j]);j++){if(j==m.j){continue;}var rw=row[m.i];var n=(rw?this.getNode(_31b,rw.r,rw.c):null);if(n){_31e.push(n);}}return _31e;},findOverlappingNodes:function(_31f){return this._findOverlappingNodes(_2e0(_31f),_2dc(_31f.parentNode),_2db(_31f));}});})();}if(!dojo._hasResource["dojo.dnd.Container"]){dojo._hasResource["dojo.dnd.Container"]=true;dojo.provide("dojo.dnd.Container");dojo.declare("dojo.dnd.Container",null,{skipForm:false,constructor:function(node,_320){this.node=dojo.byId(node);if(!_320){_320={};}this.creator=_320.creator||null;this.skipForm=_320.skipForm;this.parent=_320.dropParent&&dojo.byId(_320.dropParent);this.map={};this.current=null;this.containerState="";dojo.addClass(this.node,"dojoDndContainer");if(!(_320&&_320._skipStartup)){this.startup();}this.events=[dojo.connect(this.node,"onmouseover",this,"onMouseOver"),dojo.connect(this.node,"onmouseout",this,"onMouseOut"),dojo.connect(this.node,"ondragstart",this,"onSelectStart"),dojo.connect(this.node,"onselectstart",this,"onSelectStart")];},creator:function(){},getItem:function(key){return this.map[key];},setItem:function(key,data){this.map[key]=data;},delItem:function(key){delete this.map[key];},forInItems:function(f,o){o=o||dojo.global;var m=this.map,e=dojo.dnd._empty;for(var i in m){if(i in e){continue;}f.call(o,m[i],i,this);}return o;},clearItems:function(){this.map={};},getAllNodes:function(){return dojo.query("> .dojoDndItem",this.parent);},sync:function(){var map={};this.getAllNodes().forEach(function(node){if(node.id){var item=this.getItem(node.id);if(item){map[node.id]=item;return;}}else{node.id=dojo.dnd.getUniqueId();}var type=node.getAttribute("dndType"),data=node.getAttribute("dndData");map[node.id]={data:data||node.innerHTML,type:type?type.split(/\s*,\s*/):["text"]};},this);this.map=map;return this;},insertNodes:function(data,_321,_322){if(!this.parent.firstChild){_322=null;}else{if(_321){if(!_322){_322=this.parent.firstChild;}}else{if(_322){_322=_322.nextSibling;}}}if(_322){for(var i=0;i<data.length;++i){var t=this._normalizedCreator(data[i]);this.setItem(t.node.id,{data:t.data,type:t.type});this.parent.insertBefore(t.node,_322);}}else{for(var i=0;i<data.length;++i){var t=this._normalizedCreator(data[i]);this.setItem(t.node.id,{data:t.data,type:t.type});this.parent.appendChild(t.node);}}return this;},destroy:function(){dojo.forEach(this.events,dojo.disconnect);this.clearItems();this.node=this.parent=this.current=null;},markupFactory:function(_323,node){_323._skipStartup=true;return new dojo.dnd.Container(node,_323);},startup:function(){if(!this.parent){this.parent=this.node;if(this.parent.tagName.toLowerCase()=="table"){var c=this.parent.getElementsByTagName("tbody");if(c&&c.length){this.parent=c[0];}}}this.defaultCreator=dojo.dnd._defaultCreator(this.parent);this.sync();},onMouseOver:function(e){var n=e.relatedTarget;while(n){if(n==this.node){break;}try{n=n.parentNode;}catch(x){n=null;}}if(!n){this._changeState("Container","Over");this.onOverEvent();}n=this._getChildByEvent(e);if(this.current==n){return;}if(this.current){this._removeItemClass(this.current,"Over");}if(n){this._addItemClass(n,"Over");}this.current=n;},onMouseOut:function(e){for(var n=e.relatedTarget;n;){if(n==this.node){return;}try{n=n.parentNode;}catch(x){n=null;}}if(this.current){this._removeItemClass(this.current,"Over");this.current=null;}this._changeState("Container","");this.onOutEvent();},onSelectStart:function(e){if(!this.skipForm||!dojo.dnd.isFormElement(e)){dojo.stopEvent(e);}},onOverEvent:function(){},onOutEvent:function(){},_changeState:function(type,_324){var _325="dojoDnd"+type;var _326=type.toLowerCase()+"State";dojo.replaceClass(this.node,_325+_324,_325+this[_326]);this[_326]=_324;},_addItemClass:function(node,type){dojo.addClass(node,"dojoDndItem"+type);},_removeItemClass:function(node,type){dojo.removeClass(node,"dojoDndItem"+type);},_getChildByEvent:function(e){var node=e.target;if(node){for(var _327=node.parentNode;_327;node=_327,_327=node.parentNode){if(_327==this.parent&&dojo.hasClass(node,"dojoDndItem")){return node;}}}return null;},_normalizedCreator:function(item,hint){var t=(this.creator||this.defaultCreator).call(this,item,hint);if(!dojo.isArray(t.type)){t.type=["text"];}if(!t.node.id){t.node.id=dojo.dnd.getUniqueId();}dojo.addClass(t.node,"dojoDndItem");return t;}});dojo.dnd._createNode=function(tag){if(!tag){return dojo.dnd._createSpan;}return function(text){return dojo.create(tag,{innerHTML:text});};};dojo.dnd._createTrTd=function(text){var tr=dojo.create("tr");dojo.create("td",{innerHTML:text},tr);return tr;};dojo.dnd._createSpan=function(text){return dojo.create("span",{innerHTML:text});};dojo.dnd._defaultCreatorNodes={ul:"li",ol:"li",div:"div",p:"div"};dojo.dnd._defaultCreator=function(node){var tag=node.tagName.toLowerCase();var c=tag=="tbody"||tag=="thead"?dojo.dnd._createTrTd:dojo.dnd._createNode(dojo.dnd._defaultCreatorNodes[tag]);return function(item,hint){var _328=item&&dojo.isObject(item),data,type,n;if(_328&&item.tagName&&item.nodeType&&item.getAttribute){data=item.getAttribute("dndData")||item.innerHTML;type=item.getAttribute("dndType");type=type?type.split(/\s*,\s*/):["text"];n=item;}else{data=(_328&&item.data)?item.data:item;type=(_328&&item.type)?item.type:["text"];n=(hint=="avatar"?dojo.dnd._createSpan:c)(String(data));}if(!n.id){n.id=dojo.dnd.getUniqueId();}return {node:n,data:data,type:type};};};}if(!dojo._hasResource["dojo.dnd.Selector"]){dojo._hasResource["dojo.dnd.Selector"]=true;dojo.provide("dojo.dnd.Selector");dojo.declare("dojo.dnd.Selector",dojo.dnd.Container,{constructor:function(node,_329){if(!_329){_329={};}this.singular=_329.singular;this.autoSync=_329.autoSync;this.selection={};this.anchor=null;this.simpleSelection=false;this.events.push(dojo.connect(this.node,"onmousedown",this,"onMouseDown"),dojo.connect(this.node,"onmouseup",this,"onMouseUp"));},singular:false,getSelectedNodes:function(){var t=new dojo.NodeList();var e=dojo.dnd._empty;for(var i in this.selection){if(i in e){continue;}t.push(dojo.byId(i));}return t;},selectNone:function(){return this._removeSelection()._removeAnchor();},selectAll:function(){this.forInItems(function(data,id){this._addItemClass(dojo.byId(id),"Selected");this.selection[id]=1;},this);return this._removeAnchor();},deleteSelectedNodes:function(){var e=dojo.dnd._empty;for(var i in this.selection){if(i in e){continue;}var n=dojo.byId(i);this.delItem(i);dojo.destroy(n);}this.anchor=null;this.selection={};return this;},forInSelectedItems:function(f,o){o=o||dojo.global;var s=this.selection,e=dojo.dnd._empty;for(var i in s){if(i in e){continue;}f.call(o,this.getItem(i),i,this);}},sync:function(){dojo.dnd.Selector.superclass.sync.call(this);if(this.anchor){if(!this.getItem(this.anchor.id)){this.anchor=null;}}var t=[],e=dojo.dnd._empty;for(var i in this.selection){if(i in e){continue;}if(!this.getItem(i)){t.push(i);}}dojo.forEach(t,function(i){delete this.selection[i];},this);return this;},insertNodes:function(_32a,data,_32b,_32c){var _32d=this._normalizedCreator;this._normalizedCreator=function(item,hint){var t=_32d.call(this,item,hint);if(_32a){if(!this.anchor){this.anchor=t.node;this._removeItemClass(t.node,"Selected");this._addItemClass(this.anchor,"Anchor");}else{if(this.anchor!=t.node){this._removeItemClass(t.node,"Anchor");this._addItemClass(t.node,"Selected");}}this.selection[t.node.id]=1;}else{this._removeItemClass(t.node,"Selected");this._removeItemClass(t.node,"Anchor");}return t;};dojo.dnd.Selector.superclass.insertNodes.call(this,data,_32b,_32c);this._normalizedCreator=_32d;return this;},destroy:function(){dojo.dnd.Selector.superclass.destroy.call(this);this.selection=this.anchor=null;},markupFactory:function(_32e,node){_32e._skipStartup=true;return new dojo.dnd.Selector(node,_32e);},onMouseDown:function(e){if(this.autoSync){this.sync();}if(!this.current){return;}if(!this.singular&&!dojo.isCopyKey(e)&&!e.shiftKey&&(this.current.id in this.selection)){this.simpleSelection=true;if(e.button===dojo.mouseButtons.LEFT){dojo.stopEvent(e);}return;}if(!this.singular&&e.shiftKey){if(!dojo.isCopyKey(e)){this._removeSelection();}var c=this.getAllNodes();if(c.length){if(!this.anchor){this.anchor=c[0];this._addItemClass(this.anchor,"Anchor");}this.selection[this.anchor.id]=1;if(this.anchor!=this.current){var i=0;for(;i<c.length;++i){var node=c[i];if(node==this.anchor||node==this.current){break;}}for(++i;i<c.length;++i){var node=c[i];if(node==this.anchor||node==this.current){break;}this._addItemClass(node,"Selected");this.selection[node.id]=1;}this._addItemClass(this.current,"Selected");this.selection[this.current.id]=1;}}}else{if(this.singular){if(this.anchor==this.current){if(dojo.isCopyKey(e)){this.selectNone();}}else{this.selectNone();this.anchor=this.current;this._addItemClass(this.anchor,"Anchor");this.selection[this.current.id]=1;}}else{if(dojo.isCopyKey(e)){if(this.anchor==this.current){delete this.selection[this.anchor.id];this._removeAnchor();}else{if(this.current.id in this.selection){this._removeItemClass(this.current,"Selected");delete this.selection[this.current.id];}else{if(this.anchor){this._removeItemClass(this.anchor,"Anchor");this._addItemClass(this.anchor,"Selected");}this.anchor=this.current;this._addItemClass(this.current,"Anchor");this.selection[this.current.id]=1;}}}else{if(!(this.current.id in this.selection)){this.selectNone();this.anchor=this.current;this._addItemClass(this.current,"Anchor");this.selection[this.current.id]=1;}}}}dojo.stopEvent(e);},onMouseUp:function(e){if(!this.simpleSelection){return;}this.simpleSelection=false;this.selectNone();if(this.current){this.anchor=this.current;this._addItemClass(this.anchor,"Anchor");this.selection[this.current.id]=1;}},onMouseMove:function(e){this.simpleSelection=false;},onOverEvent:function(){this.onmousemoveEvent=dojo.connect(this.node,"onmousemove",this,"onMouseMove");},onOutEvent:function(){dojo.disconnect(this.onmousemoveEvent);delete this.onmousemoveEvent;},_removeSelection:function(){var e=dojo.dnd._empty;for(var i in this.selection){if(i in e){continue;}var node=dojo.byId(i);if(node){this._removeItemClass(node,"Selected");}}this.selection={};return this;},_removeAnchor:function(){if(this.anchor){this._removeItemClass(this.anchor,"Anchor");this.anchor=null;}return this;}});}if(!dojo._hasResource["dojo.dnd.Avatar"]){dojo._hasResource["dojo.dnd.Avatar"]=true;dojo.provide("dojo.dnd.Avatar");dojo.declare("dojo.dnd.Avatar",null,{constructor:function(_32f){this.manager=_32f;this.construct();},construct:function(){this.isA11y=dojo.hasClass(dojo.body(),"dijit_a11y");var a=dojo.create("table",{"class":"dojoDndAvatar",style:{position:"absolute",zIndex:"1999",margin:"0px"}}),_330=this.manager.source,node,b=dojo.create("tbody",null,a),tr=dojo.create("tr",null,b),td=dojo.create("td",null,tr),icon=this.isA11y?dojo.create("span",{id:"a11yIcon",innerHTML:this.manager.copy?"+":"<"},td):null,span=dojo.create("span",{innerHTML:_330.generateText?this._generateText():""},td),k=Math.min(5,this.manager.nodes.length),i=0;dojo.attr(tr,{"class":"dojoDndAvatarHeader",style:{opacity:0.9}});for(;i<k;++i){if(_330.creator){node=_330._normalizedCreator(_330.getItem(this.manager.nodes[i].id).data,"avatar").node;}else{node=this.manager.nodes[i].cloneNode(true);if(node.tagName.toLowerCase()=="tr"){var _331=dojo.create("table"),_332=dojo.create("tbody",null,_331);_332.appendChild(node);node=_331;}}node.id="";tr=dojo.create("tr",null,b);td=dojo.create("td",null,tr);td.appendChild(node);dojo.attr(tr,{"class":"dojoDndAvatarItem",style:{opacity:(9-i)/10}});}this.node=a;},destroy:function(){dojo.destroy(this.node);this.node=false;},update:function(){dojo[(this.manager.canDropFlag?"add":"remove")+"Class"](this.node,"dojoDndAvatarCanDrop");if(this.isA11y){var icon=dojo.byId("a11yIcon");var text="+";if(this.manager.canDropFlag&&!this.manager.copy){text="< ";}else{if(!this.manager.canDropFlag&&!this.manager.copy){text="o";}else{if(!this.manager.canDropFlag){text="x";}}}icon.innerHTML=text;}dojo.query(("tr.dojoDndAvatarHeader td span"+(this.isA11y?" span":"")),this.node).forEach(function(node){node.innerHTML=this._generateText();},this);},_generateText:function(){return this.manager.nodes.length.toString();}});}if(!dojo._hasResource["dojo.dnd.Manager"]){dojo._hasResource["dojo.dnd.Manager"]=true;dojo.provide("dojo.dnd.Manager");dojo.declare("dojo.dnd.Manager",null,{constructor:function(){this.avatar=null;this.source=null;this.nodes=[];this.copy=true;this.target=null;this.canDropFlag=false;this.events=[];},OFFSET_X:16,OFFSET_Y:16,overSource:function(_333){if(this.avatar){this.target=(_333&&_333.targetState!="Disabled")?_333:null;this.canDropFlag=Boolean(this.target);this.avatar.update();}dojo.publish("/dnd/source/over",[_333]);},outSource:function(_334){if(this.avatar){if(this.target==_334){this.target=null;this.canDropFlag=false;this.avatar.update();dojo.publish("/dnd/source/over",[null]);}}else{dojo.publish("/dnd/source/over",[null]);}},startDrag:function(_335,_336,copy){this.source=_335;this.nodes=_336;this.copy=Boolean(copy);this.avatar=this.makeAvatar();dojo.body().appendChild(this.avatar.node);dojo.publish("/dnd/start",[_335,_336,this.copy]);this.events=[dojo.connect(dojo.doc,"onmousemove",this,"onMouseMove"),dojo.connect(dojo.doc,"onmouseup",this,"onMouseUp"),dojo.connect(dojo.doc,"onkeydown",this,"onKeyDown"),dojo.connect(dojo.doc,"onkeyup",this,"onKeyUp"),dojo.connect(dojo.doc,"ondragstart",dojo.stopEvent),dojo.connect(dojo.body(),"onselectstart",dojo.stopEvent)];var c="dojoDnd"+(copy?"Copy":"Move");dojo.addClass(dojo.body(),c);},canDrop:function(flag){var _337=Boolean(this.target&&flag);if(this.canDropFlag!=_337){this.canDropFlag=_337;this.avatar.update();}},stopDrag:function(){dojo.removeClass(dojo.body(),["dojoDndCopy","dojoDndMove"]);dojo.forEach(this.events,dojo.disconnect);this.events=[];this.avatar.destroy();this.avatar=null;this.source=this.target=null;this.nodes=[];},makeAvatar:function(){return new dojo.dnd.Avatar(this);},updateAvatar:function(){this.avatar.update();},onMouseMove:function(e){var a=this.avatar;if(a){dojo.dnd.autoScrollNodes(e);var s=a.node.style;s.left=(e.pageX+this.OFFSET_X)+"px";s.top=(e.pageY+this.OFFSET_Y)+"px";var copy=Boolean(this.source.copyState(dojo.isCopyKey(e)));if(this.copy!=copy){this._setCopyStatus(copy);}}},onMouseUp:function(e){if(this.avatar){if(this.target&&this.canDropFlag){var copy=Boolean(this.source.copyState(dojo.isCopyKey(e))),_338=[this.source,this.nodes,copy,this.target,e];dojo.publish("/dnd/drop/before",_338);dojo.publish("/dnd/drop",_338);}else{dojo.publish("/dnd/cancel");}this.stopDrag();}},onKeyDown:function(e){if(this.avatar){switch(e.keyCode){case dojo.keys.CTRL:var copy=Boolean(this.source.copyState(true));if(this.copy!=copy){this._setCopyStatus(copy);}break;case dojo.keys.ESCAPE:dojo.publish("/dnd/cancel");this.stopDrag();break;}}},onKeyUp:function(e){if(this.avatar&&e.keyCode==dojo.keys.CTRL){var copy=Boolean(this.source.copyState(false));if(this.copy!=copy){this._setCopyStatus(copy);}}},_setCopyStatus:function(copy){this.copy=copy;this.source._markDndStatus(this.copy);this.updateAvatar();dojo.replaceClass(dojo.body(),"dojoDnd"+(this.copy?"Copy":"Move"),"dojoDnd"+(this.copy?"Move":"Copy"));}});dojo.dnd._manager=null;dojo.dnd.manager=function(){if(!dojo.dnd._manager){dojo.dnd._manager=new dojo.dnd.Manager();}return dojo.dnd._manager;};}if(!dojo._hasResource["dojo.dnd.Source"]){dojo._hasResource["dojo.dnd.Source"]=true;dojo.provide("dojo.dnd.Source");dojo.declare("dojo.dnd.Source",dojo.dnd.Selector,{isSource:true,horizontal:false,copyOnly:false,selfCopy:false,selfAccept:true,skipForm:false,withHandles:false,autoSync:false,delay:0,accept:["text"],generateText:true,constructor:function(node,_339){dojo.mixin(this,dojo.mixin({},_339));var type=this.accept;if(type.length){this.accept={};for(var i=0;i<type.length;++i){this.accept[type[i]]=1;}}this.isDragging=false;this.mouseDown=false;this.targetAnchor=null;this.targetBox=null;this.before=true;this._lastX=0;this._lastY=0;this.sourceState="";if(this.isSource){dojo.addClass(this.node,"dojoDndSource");}this.targetState="";if(this.accept){dojo.addClass(this.node,"dojoDndTarget");}if(this.horizontal){dojo.addClass(this.node,"dojoDndHorizontal");}this.topics=[dojo.subscribe("/dnd/source/over",this,"onDndSourceOver"),dojo.subscribe("/dnd/start",this,"onDndStart"),dojo.subscribe("/dnd/drop",this,"onDndDrop"),dojo.subscribe("/dnd/cancel",this,"onDndCancel")];},checkAcceptance:function(_33a,_33b){if(this==_33a){return !this.copyOnly||this.selfAccept;}for(var i=0;i<_33b.length;++i){var type=_33a.getItem(_33b[i].id).type;var flag=false;for(var j=0;j<type.length;++j){if(type[j] in this.accept){flag=true;break;}}if(!flag){return false;}}return true;},copyState:function(_33c,self){if(_33c){return true;}if(arguments.length<2){self=this==dojo.dnd.manager().target;}if(self){if(this.copyOnly){return this.selfCopy;}}else{return this.copyOnly;}return false;},destroy:function(){dojo.dnd.Source.superclass.destroy.call(this);dojo.forEach(this.topics,dojo.unsubscribe);this.targetAnchor=null;},markupFactory:function(_33d,node){_33d._skipStartup=true;return new dojo.dnd.Source(node,_33d);},onMouseMove:function(e){if(this.isDragging&&this.targetState=="Disabled"){return;}dojo.dnd.Source.superclass.onMouseMove.call(this,e);var m=dojo.dnd.manager();if(!this.isDragging){if(this.mouseDown&&this.isSource&&(Math.abs(e.pageX-this._lastX)>this.delay||Math.abs(e.pageY-this._lastY)>this.delay)){var _33e=this.getSelectedNodes();if(_33e.length){m.startDrag(this,_33e,this.copyState(dojo.isCopyKey(e),true));}}}if(this.isDragging){var _33f=false;if(this.current){if(!this.targetBox||this.targetAnchor!=this.current){this.targetBox=dojo.position(this.current,true);}if(this.horizontal){_33f=(e.pageX-this.targetBox.x)<(this.targetBox.w/2);}else{_33f=(e.pageY-this.targetBox.y)<(this.targetBox.h/2);}}if(this.current!=this.targetAnchor||_33f!=this.before){this._markTargetAnchor(_33f);m.canDrop(!this.current||m.source!=this||!(this.current.id in this.selection));}}},onMouseDown:function(e){if(!this.mouseDown&&this._legalMouseDown(e)&&(!this.skipForm||!dojo.dnd.isFormElement(e))){this.mouseDown=true;this._lastX=e.pageX;this._lastY=e.pageY;dojo.dnd.Source.superclass.onMouseDown.call(this,e);}},onMouseUp:function(e){if(this.mouseDown){this.mouseDown=false;dojo.dnd.Source.superclass.onMouseUp.call(this,e);}},onDndSourceOver:function(_340){if(this!=_340){this.mouseDown=false;if(this.targetAnchor){this._unmarkTargetAnchor();}}else{if(this.isDragging){var m=dojo.dnd.manager();m.canDrop(this.targetState!="Disabled"&&(!this.current||m.source!=this||!(this.current.id in this.selection)));}}},onDndStart:function(_341,_342,copy){if(this.autoSync){this.sync();}if(this.isSource){this._changeState("Source",this==_341?(copy?"Copied":"Moved"):"");}var _343=this.accept&&this.checkAcceptance(_341,_342);this._changeState("Target",_343?"":"Disabled");if(this==_341){dojo.dnd.manager().overSource(this);}this.isDragging=true;},onDndDrop:function(_344,_345,copy,_346){if(this==_346){this.onDrop(_344,_345,copy);}this.onDndCancel();},onDndCancel:function(){if(this.targetAnchor){this._unmarkTargetAnchor();this.targetAnchor=null;}this.before=true;this.isDragging=false;this.mouseDown=false;this._changeState("Source","");this._changeState("Target","");},onDrop:function(_347,_348,copy){if(this!=_347){this.onDropExternal(_347,_348,copy);}else{this.onDropInternal(_348,copy);}},onDropExternal:function(_349,_34a,copy){var _34b=this._normalizedCreator;if(this.creator){this._normalizedCreator=function(node,hint){return _34b.call(this,_349.getItem(node.id).data,hint);};}else{if(copy){this._normalizedCreator=function(node,hint){var t=_349.getItem(node.id);var n=node.cloneNode(true);n.id=dojo.dnd.getUniqueId();return {node:n,data:t.data,type:t.type};};}else{this._normalizedCreator=function(node,hint){var t=_349.getItem(node.id);_349.delItem(node.id);return {node:node,data:t.data,type:t.type};};}}this.selectNone();if(!copy&&!this.creator){_349.selectNone();}this.insertNodes(true,_34a,this.before,this.current);if(!copy&&this.creator){_349.deleteSelectedNodes();}this._normalizedCreator=_34b;},onDropInternal:function(_34c,copy){var _34d=this._normalizedCreator;if(this.current&&this.current.id in this.selection){return;}if(copy){if(this.creator){this._normalizedCreator=function(node,hint){return _34d.call(this,this.getItem(node.id).data,hint);};}else{this._normalizedCreator=function(node,hint){var t=this.getItem(node.id);var n=node.cloneNode(true);n.id=dojo.dnd.getUniqueId();return {node:n,data:t.data,type:t.type};};}}else{if(!this.current){return;}this._normalizedCreator=function(node,hint){var t=this.getItem(node.id);return {node:node,data:t.data,type:t.type};};}this._removeSelection();this.insertNodes(true,_34c,this.before,this.current);this._normalizedCreator=_34d;},onDraggingOver:function(){},onDraggingOut:function(){},onOverEvent:function(){dojo.dnd.Source.superclass.onOverEvent.call(this);dojo.dnd.manager().overSource(this);if(this.isDragging&&this.targetState!="Disabled"){this.onDraggingOver();}},onOutEvent:function(){dojo.dnd.Source.superclass.onOutEvent.call(this);dojo.dnd.manager().outSource(this);if(this.isDragging&&this.targetState!="Disabled"){this.onDraggingOut();}},_markTargetAnchor:function(_34e){if(this.current==this.targetAnchor&&this.before==_34e){return;}if(this.targetAnchor){this._removeItemClass(this.targetAnchor,this.before?"Before":"After");}this.targetAnchor=this.current;this.targetBox=null;this.before=_34e;if(this.targetAnchor){this._addItemClass(this.targetAnchor,this.before?"Before":"After");}},_unmarkTargetAnchor:function(){if(!this.targetAnchor){return;}this._removeItemClass(this.targetAnchor,this.before?"Before":"After");this.targetAnchor=null;this.targetBox=null;this.before=true;},_markDndStatus:function(copy){this._changeState("Source",copy?"Copied":"Moved");},_legalMouseDown:function(e){if(!dojo.mouseButtons.isLeft(e)){return false;}if(!this.withHandles){return true;}for(var node=e.target;node&&node!==this.node;node=node.parentNode){if(dojo.hasClass(node,"dojoDndHandle")){return true;}if(dojo.hasClass(node,"dojoDndItem")||dojo.hasClass(node,"dojoDndIgnore")){break;}}return false;}});dojo.declare("dojo.dnd.Target",dojo.dnd.Source,{constructor:function(node,_34f){this.isSource=false;dojo.removeClass(this.node,"dojoDndSource");},markupFactory:function(_350,node){_350._skipStartup=true;return new dojo.dnd.Target(node,_350);}});dojo.declare("dojo.dnd.AutoSource",dojo.dnd.Source,{constructor:function(node,_351){this.autoSync=true;},markupFactory:function(_352,node){_352._skipStartup=true;return new dojo.dnd.AutoSource(node,_352);}});}if(!dojo._hasResource["dojox.grid._View"]){dojo._hasResource["dojox.grid._View"]=true;dojo.provide("dojox.grid._View");(function(){var _353=function(_354,_355){return _354.style.cssText==undefined?_354.getAttribute("style"):_354.style.cssText;};dojo.declare("dojox.grid._View",[dijit._Widget,dijit._Templated],{defaultWidth:"18em",viewWidth:"",templateString:"<div class=\"dojoxGridView\" role=\"presentation\">\r\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" role=\"presentation\">\r\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" role=\"presentation\">\r\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" role=\"row\"></div>\r\n\t\t</div>\r\n\t</div>\r\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" role=\"presentation\" />\r\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" role=\"presentation\" />\r\n\t<div class=\"dojoxGridScrollbox\" dojoAttachPoint=\"scrollboxNode\" role=\"presentation\">\r\n\t\t<div class=\"dojoxGridContent\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\" role=\"presentation\"></div>\r\n\t</div>\r\n</div>\r\n",themeable:false,classTag:"dojoxGrid",marginBottom:0,rowPad:2,_togglingColumn:-1,_headerBuilderClass:dojox.grid._HeaderBuilder,_contentBuilderClass:dojox.grid._ContentBuilder,postMixInProperties:function(){this.rowNodes={};},postCreate:function(){this.connect(this.scrollboxNode,"onscroll","doscroll");dojox.grid.util.funnelEvents(this.contentNode,this,"doContentEvent",["mouseover","mouseout","click","dblclick","contextmenu","mousedown"]);dojox.grid.util.funnelEvents(this.headerNode,this,"doHeaderEvent",["dblclick","mouseover","mouseout","mousemove","mousedown","click","contextmenu"]);this.content=new this._contentBuilderClass(this);this.header=new this._headerBuilderClass(this);if(!dojo._isBodyLtr()){this.headerNodeContainer.style.width="";}},destroy:function(){dojo.destroy(this.headerNode);delete this.headerNode;for(var i in this.rowNodes){dojo.destroy(this.rowNodes[i]);}this.rowNodes={};if(this.source){this.source.destroy();}this.inherited(arguments);},focus:function(){if(dojo.isIE||dojo.isWebKit||dojo.isOpera){this.hiddenFocusNode.focus();}else{this.scrollboxNode.focus();}},setStructure:function(_356){var vs=(this.structure=_356);if(vs.width&&!isNaN(vs.width)){this.viewWidth=vs.width+"em";}else{this.viewWidth=vs.width||(vs.noscroll?"auto":this.viewWidth);}this._onBeforeRow=vs.onBeforeRow||function(){};this._onAfterRow=vs.onAfterRow||function(){};this.noscroll=vs.noscroll;if(this.noscroll){this.scrollboxNode.style.overflow="hidden";}this.simpleStructure=Boolean(vs.cells.length==1);this.testFlexCells();this.updateStructure();},_cleanupRowWidgets:function(_357){if(_357){dojo.forEach(dojo.query("[widgetId]",_357).map(dijit.byNode),function(w){if(w._destroyOnRemove){w.destroy();delete w;}else{if(w.domNode&&w.domNode.parentNode){w.domNode.parentNode.removeChild(w.domNode);}}});}},onBeforeRow:function(_358,_359){this._onBeforeRow(_358,_359);if(_358>=0){this._cleanupRowWidgets(this.getRowNode(_358));}},onAfterRow:function(_35a,_35b,_35c){this._onAfterRow(_35a,_35b,_35c);var g=this.grid;dojo.forEach(dojo.query(".dojoxGridStubNode",_35c),function(n){if(n&&n.parentNode){var lw=n.getAttribute("linkWidget");var _35d=window.parseInt(dojo.attr(n,"cellIdx"),10);var _35e=g.getCell(_35d);var w=dijit.byId(lw);if(w){n.parentNode.replaceChild(w.domNode,n);if(!w._started){w.startup();}}else{n.innerHTML="";}}},this);},testFlexCells:function(){this.flexCells=false;for(var j=0,row;(row=this.structure.cells[j]);j++){for(var i=0,cell;(cell=row[i]);i++){cell.view=this;this.flexCells=this.flexCells||cell.isFlex();}}return this.flexCells;},updateStructure:function(){this.header.update();this.content.update();},getScrollbarWidth:function(){var _35f=this.hasVScrollbar();var _360=dojo.style(this.scrollboxNode,"overflow");if(this.noscroll||!_360||_360=="hidden"){_35f=false;}else{if(_360=="scroll"){_35f=true;}}return (_35f?dojox.html.metrics.getScrollbar().w:0);},getColumnsWidth:function(){var h=this.headerContentNode;return h&&h.firstChild?h.firstChild.offsetWidth:0;},setColumnsWidth:function(_361){this.headerContentNode.firstChild.style.width=_361+"px";if(this.viewWidth){this.viewWidth=_361+"px";}},getWidth:function(){return this.viewWidth||(this.getColumnsWidth()+this.getScrollbarWidth())+"px";},getContentWidth:function(){return Math.max(0,dojo._getContentBox(this.domNode).w-this.getScrollbarWidth())+"px";},render:function(){this.scrollboxNode.style.height="";this.renderHeader();if(this._togglingColumn>=0){this.setColumnsWidth(this.getColumnsWidth()-this._togglingColumn);this._togglingColumn=-1;}var _362=this.grid.layout.cells;var _363=dojo.hitch(this,function(node,_364){!dojo._isBodyLtr()&&(_364=!_364);var inc=_364?-1:1;var idx=this.header.getCellNodeIndex(node)+inc;var cell=_362[idx];while(cell&&cell.getHeaderNode()&&cell.getHeaderNode().style.display=="none"){idx+=inc;cell=_362[idx];}if(cell){return cell.getHeaderNode();}return null;});if(this.grid.columnReordering&&this.simpleStructure){if(this.source){this.source.destroy();}var _365="dojoxGrid_bottomMarker";var _366="dojoxGrid_topMarker";if(this.bottomMarker){dojo.destroy(this.bottomMarker);}this.bottomMarker=dojo.byId(_365);if(this.topMarker){dojo.destroy(this.topMarker);}this.topMarker=dojo.byId(_366);if(!this.bottomMarker){this.bottomMarker=dojo.create("div",{"id":_365,"class":"dojoxGridColPlaceBottom"},dojo.body());this._hide(this.bottomMarker);this.topMarker=dojo.create("div",{"id":_366,"class":"dojoxGridColPlaceTop"},dojo.body());this._hide(this.topMarker);}this.arrowDim=dojo.contentBox(this.bottomMarker);var _367=dojo.contentBox(this.headerContentNode.firstChild.rows[0]).h;this.source=new dojo.dnd.Source(this.headerContentNode.firstChild.rows[0],{horizontal:true,accept:["gridColumn_"+this.grid.id],viewIndex:this.index,generateText:false,onMouseDown:dojo.hitch(this,function(e){this.header.decorateEvent(e);if((this.header.overRightResizeArea(e)||this.header.overLeftResizeArea(e))&&this.header.canResize(e)&&!this.header.moveable){this.header.beginColumnResize(e);}else{if(this.grid.headerMenu){this.grid.headerMenu.onCancel(true);}if(e.button===(dojo.isIE?1:0)){dojo.dnd.Source.prototype.onMouseDown.call(this.source,e);}}}),onMouseOver:dojo.hitch(this,function(e){var src=this.source;if(src._getChildByEvent(e)){dojo.dnd.Source.prototype.onMouseOver.apply(src,arguments);}}),_markTargetAnchor:dojo.hitch(this,function(_368){var src=this.source;if(src.current==src.targetAnchor&&src.before==_368){return;}if(src.targetAnchor&&_363(src.targetAnchor,src.before)){src._removeItemClass(_363(src.targetAnchor,src.before),src.before?"After":"Before");}dojo.dnd.Source.prototype._markTargetAnchor.call(src,_368);var _369=_368?src.targetAnchor:_363(src.targetAnchor,src.before);var _36a=0;if(!_369){_369=src.targetAnchor;_36a=dojo.contentBox(_369).w+this.arrowDim.w/2+2;}var pos=(dojo.position||dojo._abs)(_369,true);var left=Math.floor(pos.x-this.arrowDim.w/2+_36a);dojo.style(this.bottomMarker,"visibility","visible");dojo.style(this.topMarker,"visibility","visible");dojo.style(this.bottomMarker,{"left":left+"px","top":(_367+pos.y)+"px"});dojo.style(this.topMarker,{"left":left+"px","top":(pos.y-this.arrowDim.h)+"px"});if(src.targetAnchor&&_363(src.targetAnchor,src.before)){src._addItemClass(_363(src.targetAnchor,src.before),src.before?"After":"Before");}}),_unmarkTargetAnchor:dojo.hitch(this,function(){var src=this.source;if(!src.targetAnchor){return;}if(src.targetAnchor&&_363(src.targetAnchor,src.before)){src._removeItemClass(_363(src.targetAnchor,src.before),src.before?"After":"Before");}this._hide(this.bottomMarker);this._hide(this.topMarker);dojo.dnd.Source.prototype._unmarkTargetAnchor.call(src);}),destroy:dojo.hitch(this,function(){dojo.disconnect(this._source_conn);dojo.unsubscribe(this._source_sub);dojo.dnd.Source.prototype.destroy.call(this.source);if(this.bottomMarker){dojo.destroy(this.bottomMarker);delete this.bottomMarker;}if(this.topMarker){dojo.destroy(this.topMarker);delete this.topMarker;}}),onDndCancel:dojo.hitch(this,function(){dojo.dnd.Source.prototype.onDndCancel.call(this.source);this._hide(this.bottomMarker);this._hide(this.topMarker);})});this._source_conn=dojo.connect(this.source,"onDndDrop",this,"_onDndDrop");this._source_sub=dojo.subscribe("/dnd/drop/before",this,"_onDndDropBefore");this.source.startup();}},_hide:function(node){dojo.style(node,{left:"-10000px",top:"-10000px","visibility":"hidden"});},_onDndDropBefore:function(_36b,_36c,copy){if(dojo.dnd.manager().target!==this.source){return;}this.source._targetNode=this.source.targetAnchor;this.source._beforeTarget=this.source.before;var _36d=this.grid.views.views;var _36e=_36d[_36b.viewIndex];var _36f=_36d[this.index];if(_36f!=_36e){_36e.convertColPctToFixed();_36f.convertColPctToFixed();}},_onDndDrop:function(_370,_371,copy){if(dojo.dnd.manager().target!==this.source){if(dojo.dnd.manager().source===this.source){this._removingColumn=true;}return;}this._hide(this.bottomMarker);this._hide(this.topMarker);var _372=function(n){return n?dojo.attr(n,"idx"):null;};var w=dojo.marginBox(_371[0]).w;if(_370.viewIndex!==this.index){var _373=this.grid.views.views;var _374=_373[_370.viewIndex];var _375=_373[this.index];if(_374.viewWidth&&_374.viewWidth!="auto"){_374.setColumnsWidth(_374.getColumnsWidth()-w);}if(_375.viewWidth&&_375.viewWidth!="auto"){_375.setColumnsWidth(_375.getColumnsWidth());}}var stn=this.source._targetNode;var stb=this.source._beforeTarget;!dojo._isBodyLtr()&&(stb=!stb);var _376=this.grid.layout;var idx=this.index;delete this.source._targetNode;delete this.source._beforeTarget;_376.moveColumn(_370.viewIndex,idx,_372(_371[0]),_372(stn),stb);},renderHeader:function(){this.headerContentNode.innerHTML=this.header.generateHtml(this._getHeaderContent);if(this.flexCells){this.contentWidth=this.getContentWidth();this.headerContentNode.firstChild.style.width=this.contentWidth;}dojox.grid.util.fire(this,"onAfterRow",[-1,this.structure.cells,this.headerContentNode]);},_getHeaderContent:function(_377){var n=_377.name||_377.grid.getCellName(_377);var ret=["<div class=\"dojoxGridSortNode"];if(_377.index!=_377.grid.getSortIndex()){ret.push("\">");}else{ret=ret.concat([" ",_377.grid.sortInfo>0?"dojoxGridSortUp":"dojoxGridSortDown","\"><div class=\"dojoxGridArrowButtonChar\">",_377.grid.sortInfo>0?"&#9650;":"&#9660;","</div><div class=\"dojoxGridArrowButtonNode\" role=\"presentation\"></div>","<div class=\"dojoxGridColCaption\">"]);}ret=ret.concat([n,"</div></div>"]);return ret.join("");},resize:function(){this.adaptHeight();this.adaptWidth();},hasHScrollbar:function(_378){var _379=this._hasHScroll||false;if(this._hasHScroll==undefined||_378){if(this.noscroll){this._hasHScroll=false;}else{var _37a=dojo.style(this.scrollboxNode,"overflow");if(_37a=="hidden"){this._hasHScroll=false;}else{if(_37a=="scroll"){this._hasHScroll=true;}else{this._hasHScroll=(this.scrollboxNode.offsetWidth-this.getScrollbarWidth()<this.contentNode.offsetWidth);}}}}if(_379!==this._hasHScroll){this.grid.update();}return this._hasHScroll;},hasVScrollbar:function(_37b){var _37c=this._hasVScroll||false;if(this._hasVScroll==undefined||_37b){if(this.noscroll){this._hasVScroll=false;}else{var _37d=dojo.style(this.scrollboxNode,"overflow");if(_37d=="hidden"){this._hasVScroll=false;}else{if(_37d=="scroll"){this._hasVScroll=true;}else{this._hasVScroll=(this.scrollboxNode.scrollHeight>this.scrollboxNode.clientHeight);}}}}if(_37c!==this._hasVScroll){this.grid.update();}return this._hasVScroll;},convertColPctToFixed:function(){var _37e=false;this.grid.initialWidth="";var _37f=dojo.query("th",this.headerContentNode);var _380=dojo.map(_37f,function(c,vIdx){var w=c.style.width;dojo.attr(c,"vIdx",vIdx);if(w&&w.slice(-1)=="%"){_37e=true;}else{if(w&&w.slice(-2)=="px"){return window.parseInt(w,10);}}return dojo.contentBox(c).w;});if(_37e){dojo.forEach(this.grid.layout.cells,function(cell,idx){if(cell.view==this){var _381=cell.view.getHeaderCellNode(cell.index);if(_381&&dojo.hasAttr(_381,"vIdx")){var vIdx=window.parseInt(dojo.attr(_381,"vIdx"));this.setColWidth(idx,_380[vIdx]);dojo.removeAttr(_381,"vIdx");}}},this);return true;}return false;},adaptHeight:function(_382){if(!this.grid._autoHeight){var h=(this.domNode.style.height&&parseInt(this.domNode.style.height.replace(/px/,""),10))||this.domNode.clientHeight;var self=this;var _383=function(){var v;for(var i in self.grid.views.views){v=self.grid.views.views[i];if(v!==self&&v.hasHScrollbar()){return true;}}return false;};if(_382||(this.noscroll&&_383())){h-=dojox.html.metrics.getScrollbar().h;}dojox.grid.util.setStyleHeightPx(this.scrollboxNode,h);}this.hasVScrollbar(true);},adaptWidth:function(){if(this.flexCells){this.contentWidth=this.getContentWidth();this.headerContentNode.firstChild.style.width=this.contentWidth;}var w=this.scrollboxNode.offsetWidth-this.getScrollbarWidth();if(!this._removingColumn){w=Math.max(w,this.getColumnsWidth())+"px";}else{w=Math.min(w,this.getColumnsWidth())+"px";this._removingColumn=false;}var cn=this.contentNode;cn.style.width=w;this.hasHScrollbar(true);},setSize:function(w,h){var ds=this.domNode.style;var hs=this.headerNode.style;if(w){ds.width=w;hs.width=w;}ds.height=(h>=0?h+"px":"");},renderRow:function(_384){var _385=this.createRowNode(_384);this.buildRow(_384,_385);this.grid.edit.restore(this,_384);return _385;},createRowNode:function(_386){var node=document.createElement("div");node.className=this.classTag+"Row";if(this instanceof dojox.grid._RowSelector){dojo.attr(node,"role","presentation");}else{dojo.attr(node,"role","row");if(this.grid.selectionMode!="none"){dojo.attr(node,"aria-selected","false");}}node[dojox.grid.util.gridViewTag]=this.id;node[dojox.grid.util.rowIndexTag]=_386;this.rowNodes[_386]=node;return node;},buildRow:function(_387,_388){this.buildRowContent(_387,_388);this.styleRow(_387,_388);},buildRowContent:function(_389,_38a){_38a.innerHTML=this.content.generateHtml(_389,_389);if(this.flexCells&&this.contentWidth){_38a.firstChild.style.width=this.contentWidth;}dojox.grid.util.fire(this,"onAfterRow",[_389,this.structure.cells,_38a]);},rowRemoved:function(_38b){if(_38b>=0){this._cleanupRowWidgets(this.getRowNode(_38b));}this.grid.edit.save(this,_38b);delete this.rowNodes[_38b];},getRowNode:function(_38c){return this.rowNodes[_38c];},getCellNode:function(_38d,_38e){var row=this.getRowNode(_38d);if(row){return this.content.getCellNode(row,_38e);}},getHeaderCellNode:function(_38f){if(this.headerContentNode){return this.header.getCellNode(this.headerContentNode,_38f);}},styleRow:function(_390,_391){_391._style=_353(_391);this.styleRowNode(_390,_391);},styleRowNode:function(_392,_393){if(_393){this.doStyleRowNode(_392,_393);}},doStyleRowNode:function(_394,_395){this.grid.styleRowNode(_394,_395);},updateRow:function(_396){var _397=this.getRowNode(_396);if(_397){_397.style.height="";this.buildRow(_396,_397);}return _397;},updateRowStyles:function(_398){this.styleRowNode(_398,this.getRowNode(_398));},lastTop:0,firstScroll:0,doscroll:function(_399){var _39a=dojo._isBodyLtr();if(this.firstScroll<2){if((!_39a&&this.firstScroll==1)||(_39a&&this.firstScroll===0)){var s=dojo.marginBox(this.headerNodeContainer);if(dojo.isIE){this.headerNodeContainer.style.width=s.w+this.getScrollbarWidth()+"px";}else{if(dojo.isMoz){this.headerNodeContainer.style.width=s.w-this.getScrollbarWidth()+"px";this.scrollboxNode.scrollLeft=_39a?this.scrollboxNode.clientWidth-this.scrollboxNode.scrollWidth:this.scrollboxNode.scrollWidth-this.scrollboxNode.clientWidth;}}}this.firstScroll++;}this.headerNode.scrollLeft=this.scrollboxNode.scrollLeft;var top=this.scrollboxNode.scrollTop;if(top!==this.lastTop){this.grid.scrollTo(top);}},setScrollTop:function(_39b){this.lastTop=_39b;this.scrollboxNode.scrollTop=_39b;return this.scrollboxNode.scrollTop;},doContentEvent:function(e){if(this.content.decorateEvent(e)){this.grid.onContentEvent(e);}},doHeaderEvent:function(e){if(this.header.decorateEvent(e)){this.grid.onHeaderEvent(e);}},dispatchContentEvent:function(e){return this.content.dispatchEvent(e);},dispatchHeaderEvent:function(e){return this.header.dispatchEvent(e);},setColWidth:function(_39c,_39d){this.grid.setCellWidth(_39c,_39d+"px");},update:function(){if(!this.domNode){return;}this.content.update();this.grid.update();var left=this.scrollboxNode.scrollLeft;this.scrollboxNode.scrollLeft=left;this.headerNode.scrollLeft=left;}});dojo.declare("dojox.grid._GridAvatar",dojo.dnd.Avatar,{construct:function(){var dd=dojo.doc;var a=dd.createElement("table");a.cellPadding=a.cellSpacing="0";a.className="dojoxGridDndAvatar";a.style.position="absolute";a.style.zIndex=1999;a.style.margin="0px";var b=dd.createElement("tbody");var tr=dd.createElement("tr");var td=dd.createElement("td");var img=dd.createElement("td");tr.className="dojoxGridDndAvatarItem";img.className="dojoxGridDndAvatarItemImage";img.style.width="16px";var _39e=this.manager.source,node;if(_39e.creator){node=_39e._normalizedCreator(_39e.getItem(this.manager.nodes[0].id).data,"avatar").node;}else{node=this.manager.nodes[0].cloneNode(true);var _39f,_3a0;if(node.tagName.toLowerCase()=="tr"){_39f=dd.createElement("table");_3a0=dd.createElement("tbody");_3a0.appendChild(node);_39f.appendChild(_3a0);node=_39f;}else{if(node.tagName.toLowerCase()=="th"){_39f=dd.createElement("table");_3a0=dd.createElement("tbody");var r=dd.createElement("tr");_39f.cellPadding=_39f.cellSpacing="0";r.appendChild(node);_3a0.appendChild(r);_39f.appendChild(_3a0);node=_39f;}}}node.id="";td.appendChild(node);tr.appendChild(img);tr.appendChild(td);dojo.style(tr,"opacity",0.9);b.appendChild(tr);a.appendChild(b);this.node=a;var m=dojo.dnd.manager();this.oldOffsetY=m.OFFSET_Y;m.OFFSET_Y=1;},destroy:function(){dojo.dnd.manager().OFFSET_Y=this.oldOffsetY;this.inherited(arguments);}});var _3a1=dojo.dnd.manager().makeAvatar;dojo.dnd.manager().makeAvatar=function(){var src=this.source;if(src.viewIndex!==undefined&&!dojo.hasClass(dojo.body(),"dijit_a11y")){return new dojox.grid._GridAvatar(this);}return _3a1.call(dojo.dnd.manager());};})();}if(!dojo._hasResource["dojox.grid._RowSelector"]){dojo._hasResource["dojox.grid._RowSelector"]=true;dojo.provide("dojox.grid._RowSelector");dojo.declare("dojox.grid._RowSelector",dojox.grid._View,{defaultWidth:"2em",noscroll:true,padBorderWidth:2,buildRendering:function(){this.inherited("buildRendering",arguments);this.scrollboxNode.style.overflow="hidden";this.headerNode.style.visibility="hidden";},getWidth:function(){return this.viewWidth||this.defaultWidth;},buildRowContent:function(_3a2,_3a3){var w=this.contentWidth||0;_3a3.innerHTML="<table class=\"dojoxGridRowbarTable\" style=\"width:"+w+"px;height:1px;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" role=\"presentation\"><tr><td class=\"dojoxGridRowbarInner\">&nbsp;</td></tr></table>";},renderHeader:function(){},updateRow:function(){},resize:function(){this.adaptHeight();},adaptWidth:function(){if(!("contentWidth" in this)&&this.contentNode){this.contentWidth=this.contentNode.offsetWidth-this.padBorderWidth;}},doStyleRowNode:function(_3a4,_3a5){var n=["dojoxGridRowbar dojoxGridNonNormalizedCell"];if(this.grid.rows.isOver(_3a4)){n.push("dojoxGridRowbarOver");}if(this.grid.selection.isSelected(_3a4)){n.push("dojoxGridRowbarSelected");}_3a5.className=n.join(" ");},domouseover:function(e){this.grid.onMouseOverRow(e);},domouseout:function(e){if(!this.isIntraRowEvent(e)){this.grid.onMouseOutRow(e);}}});}if(!dojo._hasResource["dojox.grid._Layout"]){dojo._hasResource["dojox.grid._Layout"]=true;dojo.provide("dojox.grid._Layout");dojo.declare("dojox.grid._Layout",null,{constructor:function(_3a6){this.grid=_3a6;},cells:[],structure:null,defaultWidth:"6em",moveColumn:function(_3a7,_3a8,_3a9,_3aa,_3ab){var _3ac=this.structure[_3a7].cells[0];var _3ad=this.structure[_3a8].cells[0];var cell=null;var _3ae=0;var _3af=0;for(var i=0,c;c=_3ac[i];i++){if(c.index==_3a9){_3ae=i;break;}}cell=_3ac.splice(_3ae,1)[0];cell.view=this.grid.views.views[_3a8];for(i=0,c=null;c=_3ad[i];i++){if(c.index==_3aa){_3af=i;break;}}if(!_3ab){_3af+=1;}_3ad.splice(_3af,0,cell);var _3b0=this.grid.getCell(this.grid.getSortIndex());if(_3b0){_3b0._currentlySorted=this.grid.getSortAsc();}this.cells=[];_3a9=0;var v;for(i=0;v=this.structure[i];i++){for(var j=0,cs;cs=v.cells[j];j++){for(var k=0;c=cs[k];k++){c.index=_3a9;this.cells.push(c);if("_currentlySorted" in c){var si=_3a9+1;si*=c._currentlySorted?1:-1;this.grid.sortInfo=si;delete c._currentlySorted;}_3a9++;}}}dojo.forEach(this.cells,function(c){var _3b1=c.markup[2].split(" ");var _3b2=parseInt(_3b1[1].substring(5));if(_3b2!=c.index){_3b1[1]="idx=\""+c.index+"\"";c.markup[2]=_3b1.join(" ");}});this.grid.setupHeaderMenu();},setColumnVisibility:function(_3b3,_3b4){var cell=this.cells[_3b3];if(cell.hidden==_3b4){cell.hidden=!_3b4;var v=cell.view,w=v.viewWidth;if(w&&w!="auto"){v._togglingColumn=dojo.marginBox(cell.getHeaderNode()).w||0;}v.update();return true;}else{return false;}},addCellDef:function(_3b5,_3b6,_3b7){var self=this;var _3b8=function(_3b9){var w=0;if(_3b9.colSpan>1){w=0;}else{w=_3b9.width||self._defaultCellProps.width||self.defaultWidth;if(!isNaN(w)){w=w+"em";}}return w;};var _3ba={grid:this.grid,subrow:_3b5,layoutIndex:_3b6,index:this.cells.length};if(_3b7&&_3b7 instanceof dojox.grid.cells._Base){var _3bb=dojo.clone(_3b7);_3ba.unitWidth=_3b8(_3bb._props);_3bb=dojo.mixin(_3bb,this._defaultCellProps,_3b7._props,_3ba);return _3bb;}var _3bc=_3b7.type||_3b7.cellType||this._defaultCellProps.type||this._defaultCellProps.cellType||dojox.grid.cells.Cell;_3ba.unitWidth=_3b8(_3b7);return new _3bc(dojo.mixin({},this._defaultCellProps,_3b7,_3ba));},addRowDef:function(_3bd,_3be){var _3bf=[];var _3c0=0,_3c1=0,_3c2=true;for(var i=0,def,cell;(def=_3be[i]);i++){cell=this.addCellDef(_3bd,i,def);_3bf.push(cell);this.cells.push(cell);if(_3c2&&cell.relWidth){_3c0+=cell.relWidth;}else{if(cell.width){var w=cell.width;if(typeof w=="string"&&w.slice(-1)=="%"){_3c1+=window.parseInt(w,10);}else{if(w=="auto"){_3c2=false;}}}}}if(_3c0&&_3c2){dojo.forEach(_3bf,function(cell){if(cell.relWidth){cell.width=cell.unitWidth=((cell.relWidth/_3c0)*(100-_3c1))+"%";}});}return _3bf;},addRowsDef:function(_3c3){var _3c4=[];if(dojo.isArray(_3c3)){if(dojo.isArray(_3c3[0])){for(var i=0,row;_3c3&&(row=_3c3[i]);i++){_3c4.push(this.addRowDef(i,row));}}else{_3c4.push(this.addRowDef(0,_3c3));}}return _3c4;},addViewDef:function(_3c5){this._defaultCellProps=_3c5.defaultCell||{};if(_3c5.width&&_3c5.width=="auto"){delete _3c5.width;}return dojo.mixin({},_3c5,{cells:this.addRowsDef(_3c5.rows||_3c5.cells)});},setStructure:function(_3c6){this.fieldIndex=0;this.cells=[];var s=this.structure=[];if(this.grid.rowSelector){var sel={type:dojox._scopeName+".grid._RowSelector"};if(dojo.isString(this.grid.rowSelector)){var _3c7=this.grid.rowSelector;if(_3c7=="false"){sel=null;}else{if(_3c7!="true"){sel["width"]=_3c7;}}}else{if(!this.grid.rowSelector){sel=null;}}if(sel){s.push(this.addViewDef(sel));}}var _3c8=function(def){return ("name" in def||"field" in def||"get" in def);};var _3c9=function(def){if(dojo.isArray(def)){if(dojo.isArray(def[0])||_3c8(def[0])){return true;}}return false;};var _3ca=function(def){return (def!==null&&dojo.isObject(def)&&("cells" in def||"rows" in def||("type" in def&&!_3c8(def))));};if(dojo.isArray(_3c6)){var _3cb=false;for(var i=0,st;(st=_3c6[i]);i++){if(_3ca(st)){_3cb=true;break;}}if(!_3cb){s.push(this.addViewDef({cells:_3c6}));}else{for(i=0;(st=_3c6[i]);i++){if(_3c9(st)){s.push(this.addViewDef({cells:st}));}else{if(_3ca(st)){s.push(this.addViewDef(st));}}}}}else{if(_3ca(_3c6)){s.push(this.addViewDef(_3c6));}}this.cellCount=this.cells.length;this.grid.setupHeaderMenu();}});}if(!dojo._hasResource["dojox.grid._ViewManager"]){dojo._hasResource["dojox.grid._ViewManager"]=true;dojo.provide("dojox.grid._ViewManager");dojo.declare("dojox.grid._ViewManager",null,{constructor:function(_3cc){this.grid=_3cc;},defaultWidth:200,views:[],resize:function(){this.onEach("resize");},render:function(){this.onEach("render");},addView:function(_3cd){_3cd.idx=this.views.length;this.views.push(_3cd);},destroyViews:function(){for(var i=0,v;v=this.views[i];i++){v.destroy();}this.views=[];},getContentNodes:function(){var _3ce=[];for(var i=0,v;v=this.views[i];i++){_3ce.push(v.contentNode);}return _3ce;},forEach:function(_3cf){for(var i=0,v;v=this.views[i];i++){_3cf(v,i);}},onEach:function(_3d0,_3d1){_3d1=_3d1||[];for(var i=0,v;v=this.views[i];i++){if(_3d0 in v){v[_3d0].apply(v,_3d1);}}},normalizeHeaderNodeHeight:function(){var _3d2=[];for(var i=0,v;(v=this.views[i]);i++){if(v.headerContentNode.firstChild){_3d2.push(v.headerContentNode);}}this.normalizeRowNodeHeights(_3d2);},normalizeRowNodeHeights:function(_3d3){var h=0;var _3d4=[];if(this.grid.rowHeight){h=this.grid.rowHeight;}else{if(_3d3.length<=1){return;}for(var i=0,n;(n=_3d3[i]);i++){if(!dojo.hasClass(n,"dojoxGridNonNormalizedCell")){_3d4[i]=n.firstChild.offsetHeight;h=Math.max(h,_3d4[i]);}}h=(h>=0?h:0);if(dojo.isMoz&&h){h++;}}for(i=0;(n=_3d3[i]);i++){if(_3d4[i]!=h){n.firstChild.style.height=h+"px";}}},resetHeaderNodeHeight:function(){for(var i=0,v,n;(v=this.views[i]);i++){n=v.headerContentNode.firstChild;if(n){n.style.height="";}}},renormalizeRow:function(_3d5){var _3d6=[];for(var i=0,v,n;(v=this.views[i])&&(n=v.getRowNode(_3d5));i++){n.firstChild.style.height="";_3d6.push(n);}this.normalizeRowNodeHeights(_3d6);},getViewWidth:function(_3d7){return this.views[_3d7].getWidth()||this.defaultWidth;},measureHeader:function(){this.resetHeaderNodeHeight();this.forEach(function(_3d8){_3d8.headerContentNode.style.height="";});var h=0;this.forEach(function(_3d9){h=Math.max(_3d9.headerNode.offsetHeight,h);});return h;},measureContent:function(){var h=0;this.forEach(function(_3da){h=Math.max(_3da.domNode.offsetHeight,h);});return h;},findClient:function(_3db){var c=this.grid.elasticView||-1;if(c<0){for(var i=1,v;(v=this.views[i]);i++){if(v.viewWidth){for(i=1;(v=this.views[i]);i++){if(!v.viewWidth){c=i;break;}}break;}}}if(c<0){c=Math.floor(this.views.length/2);}return c;},arrange:function(l,w){var i,v,vw,len=this.views.length;var c=(w<=0?len:this.findClient());var _3dc=function(v,l){var ds=v.domNode.style;var hs=v.headerNode.style;if(!dojo._isBodyLtr()){ds.right=l+"px";if(dojo.isMoz){hs.right=l+v.getScrollbarWidth()+"px";hs.width=parseInt(hs.width,10)-v.getScrollbarWidth()+"px";}else{hs.right=l+"px";}}else{ds.left=l+"px";hs.left=l+"px";}ds.top=0+"px";hs.top=0;};for(i=0;(v=this.views[i])&&(i<c);i++){vw=this.getViewWidth(i);v.setSize(vw,0);_3dc(v,l);if(v.headerContentNode&&v.headerContentNode.firstChild){vw=v.getColumnsWidth()+v.getScrollbarWidth();}else{vw=v.domNode.offsetWidth;}l+=vw;}i++;var r=w;for(var j=len-1;(v=this.views[j])&&(i<=j);j--){vw=this.getViewWidth(j);v.setSize(vw,0);vw=v.domNode.offsetWidth;r-=vw;_3dc(v,r);}if(c<len){v=this.views[c];vw=Math.max(1,r-l);v.setSize(vw+"px",0);_3dc(v,l);}return l;},renderRow:function(_3dd,_3de,_3df){var _3e0=[];for(var i=0,v,n,_3e1;(v=this.views[i])&&(n=_3de[i]);i++){_3e1=v.renderRow(_3dd);n.appendChild(_3e1);_3e0.push(_3e1);}if(!_3df){this.normalizeRowNodeHeights(_3e0);}},rowRemoved:function(_3e2){this.onEach("rowRemoved",[_3e2]);},updateRow:function(_3e3,_3e4){for(var i=0,v;v=this.views[i];i++){v.updateRow(_3e3);}if(!_3e4){this.renormalizeRow(_3e3);}},updateRowStyles:function(_3e5){this.onEach("updateRowStyles",[_3e5]);},setScrollTop:function(_3e6){var top=_3e6;for(var i=0,v;v=this.views[i];i++){top=v.setScrollTop(_3e6);if(dojo.isIE&&v.headerNode&&v.scrollboxNode){v.headerNode.scrollLeft=v.scrollboxNode.scrollLeft;}}return top;},getFirstScrollingView:function(){for(var i=0,v;(v=this.views[i]);i++){if(v.hasHScrollbar()||v.hasVScrollbar()){return v;}}return null;}});}if(!dojo._hasResource["dojox.grid._RowManager"]){dojo._hasResource["dojox.grid._RowManager"]=true;dojo.provide("dojox.grid._RowManager");(function(){var _3e7=function(_3e8,_3e9){if(_3e8.style.cssText==undefined){_3e8.setAttribute("style",_3e9);}else{_3e8.style.cssText=_3e9;}};dojo.declare("dojox.grid._RowManager",null,{constructor:function(_3ea){this.grid=_3ea;},linesToEms:2,overRow:-2,prepareStylingRow:function(_3eb,_3ec){return {index:_3eb,node:_3ec,odd:Boolean(_3eb&1),selected:!!this.grid.selection.isSelected(_3eb),over:this.isOver(_3eb),customStyles:"",customClasses:"dojoxGridRow"};},styleRowNode:function(_3ed,_3ee){var row=this.prepareStylingRow(_3ed,_3ee);this.grid.onStyleRow(row);this.applyStyles(row);},applyStyles:function(_3ef){var i=_3ef;i.node.className=i.customClasses;var h=i.node.style.height;_3e7(i.node,i.customStyles+";"+(i.node._style||""));i.node.style.height=h;},updateStyles:function(_3f0){this.grid.updateRowStyles(_3f0);},setOverRow:function(_3f1){var last=this.overRow;this.overRow=_3f1;if((last!=this.overRow)&&(dojo.isString(last)||last>=0)){this.updateStyles(last);}this.updateStyles(this.overRow);},isOver:function(_3f2){return (this.overRow==_3f2&&!dojo.hasClass(this.grid.domNode,"dojoxGridColumnResizing"));}});})();}if(!dojo._hasResource["dojox.grid._FocusManager"]){dojo._hasResource["dojox.grid._FocusManager"]=true;dojo.provide("dojox.grid._FocusManager");dojo.declare("dojox.grid._FocusManager",null,{constructor:function(_3f3){this.grid=_3f3;this.cell=null;this.rowIndex=-1;this._connects=[];this._headerConnects=[];this.headerMenu=this.grid.headerMenu;this._connects.push(dojo.connect(this.grid.domNode,"onfocus",this,"doFocus"));this._connects.push(dojo.connect(this.grid.domNode,"onblur",this,"doBlur"));this._connects.push(dojo.connect(this.grid.domNode,"oncontextmenu",this,"doContextMenu"));this._connects.push(dojo.connect(this.grid.lastFocusNode,"onfocus",this,"doLastNodeFocus"));this._connects.push(dojo.connect(this.grid.lastFocusNode,"onblur",this,"doLastNodeBlur"));this._connects.push(dojo.connect(this.grid,"_onFetchComplete",this,"_delayedCellFocus"));this._connects.push(dojo.connect(this.grid,"postrender",this,"_delayedHeaderFocus"));},destroy:function(){dojo.forEach(this._connects,dojo.disconnect);dojo.forEach(this._headerConnects,dojo.disconnect);delete this.grid;delete this.cell;},_colHeadNode:null,_colHeadFocusIdx:null,_contextMenuBindNode:null,tabbingOut:false,focusClass:"dojoxGridCellFocus",focusView:null,initFocusView:function(){this.focusView=this.grid.views.getFirstScrollingView()||this.focusView||this.grid.views.views[0];this._initColumnHeaders();},isFocusCell:function(_3f4,_3f5){return (this.cell==_3f4)&&(this.rowIndex==_3f5);},isLastFocusCell:function(){if(this.cell){return (this.rowIndex==this.grid.rowCount-1)&&(this.cell.index==this.grid.layout.cellCount-1);}return false;},isFirstFocusCell:function(){if(this.cell){return (this.rowIndex===0)&&(this.cell.index===0);}return false;},isNoFocusCell:function(){return (this.rowIndex<0)||!this.cell;},isNavHeader:function(){return (!!this._colHeadNode);},getHeaderIndex:function(){if(this._colHeadNode){return dojo.indexOf(this._findHeaderCells(),this._colHeadNode);}else{return -1;}},_focusifyCellNode:function(_3f6){var n=this.cell&&this.cell.getNode(this.rowIndex);if(n){dojo.toggleClass(n,this.focusClass,_3f6);if(_3f6){var sl=this.scrollIntoView();try{if(!this.grid.edit.isEditing()){dojox.grid.util.fire(n,"focus");if(sl){this.cell.view.scrollboxNode.scrollLeft=sl;}}}catch(e){}}}},_delayedCellFocus:function(){if(this.isNavHeader()||!this.grid._focused){return;}var n=this.cell&&this.cell.getNode(this.rowIndex);if(n){try{if(!this.grid.edit.isEditing()){dojo.toggleClass(n,this.focusClass,true);this.blurHeader();dojox.grid.util.fire(n,"focus");}}catch(e){}}},_delayedHeaderFocus:function(){if(this.isNavHeader()){this.focusHeader();this.grid.domNode.focus();}},_initColumnHeaders:function(){dojo.forEach(this._headerConnects,dojo.disconnect);this._headerConnects=[];var _3f7=this._findHeaderCells();for(var i=0;i<_3f7.length;i++){this._headerConnects.push(dojo.connect(_3f7[i],"onfocus",this,"doColHeaderFocus"));this._headerConnects.push(dojo.connect(_3f7[i],"onblur",this,"doColHeaderBlur"));}},_findHeaderCells:function(){var _3f8=dojo.query("th",this.grid.viewsHeaderNode);var _3f9=[];for(var i=0;i<_3f8.length;i++){var _3fa=_3f8[i];var _3fb=dojo.hasAttr(_3fa,"tabIndex");var _3fc=dojo.attr(_3fa,"tabIndex");if(_3fb&&_3fc<0){_3f9.push(_3fa);}}return _3f9;},_setActiveColHeader:function(_3fd,_3fe,_3ff){dojo.attr(this.grid.domNode,"aria-activedescendant",_3fd.id);if(_3ff!=null&&_3ff>=0&&_3ff!=_3fe){dojo.toggleClass(this._findHeaderCells()[_3ff],this.focusClass,false);}dojo.toggleClass(_3fd,this.focusClass,true);this._colHeadNode=_3fd;this._colHeadFocusIdx=_3fe;this._scrollHeader(this._colHeadFocusIdx);},scrollIntoView:function(){var info=(this.cell?this._scrollInfo(this.cell):null);if(!info||!info.s){return null;}var rt=this.grid.scroller.findScrollTop(this.rowIndex);if(info.n&&info.sr){if(info.n.offsetLeft+info.n.offsetWidth>info.sr.l+info.sr.w){info.s.scrollLeft=info.n.offsetLeft+info.n.offsetWidth-info.sr.w;}else{if(info.n.offsetLeft<info.sr.l){info.s.scrollLeft=info.n.offsetLeft;}}}if(info.r&&info.sr){if(rt+info.r.offsetHeight>info.sr.t+info.sr.h){this.grid.setScrollTop(rt+info.r.offsetHeight-info.sr.h);}else{if(rt<info.sr.t){this.grid.setScrollTop(rt);}}}return info.s.scrollLeft;},_scrollInfo:function(cell,_400){if(cell){var cl=cell,sbn=cl.view.scrollboxNode,sbnr={w:sbn.clientWidth,l:sbn.scrollLeft,t:sbn.scrollTop,h:sbn.clientHeight},rn=cl.view.getRowNode(this.rowIndex);return {c:cl,s:sbn,sr:sbnr,n:(_400?_400:cell.getNode(this.rowIndex)),r:rn};}return null;},_scrollHeader:function(_401){var info=null;if(this._colHeadNode){var cell=this.grid.getCell(_401);info=this._scrollInfo(cell,cell.getNode(0));}if(info&&info.s&&info.sr&&info.n){var _402=info.sr.l+info.sr.w;if(info.n.offsetLeft+info.n.offsetWidth>_402){info.s.scrollLeft=info.n.offsetLeft+info.n.offsetWidth-info.sr.w;}else{if(info.n.offsetLeft<info.sr.l){info.s.scrollLeft=info.n.offsetLeft;}else{if(dojo.isIE<=7&&cell&&cell.view.headerNode){cell.view.headerNode.scrollLeft=info.s.scrollLeft;}}}}},_isHeaderHidden:function(){var _403=this.focusView;if(!_403){for(var i=0,_404;(_404=this.grid.views.views[i]);i++){if(_404.headerNode){_403=_404;break;}}}return (_403&&dojo.getComputedStyle(_403.headerNode).display=="none");},colSizeAdjust:function(e,_405,_406){var _407=this._findHeaderCells();var view=this.focusView;if(!view){for(var i=0,_408;(_408=this.grid.views.views[i]);i++){if(_408.header.tableMap.map){view=_408;break;}}}var _409=_407[_405];if(!view||(_405==_407.length-1&&_405===0)){return;}view.content.baseDecorateEvent(e);e.cellNode=_409;e.cellIndex=view.content.getCellNodeIndex(e.cellNode);e.cell=(e.cellIndex>=0?this.grid.getCell(e.cellIndex):null);if(view.header.canResize(e)){var _40a={l:_406};var drag=view.header.colResizeSetup(e,false);view.header.doResizeColumn(drag,null,_40a);view.update();}},styleRow:function(_40b){return;},setFocusIndex:function(_40c,_40d){this.setFocusCell(this.grid.getCell(_40d),_40c);},setFocusCell:function(_40e,_40f){if(_40e&&!this.isFocusCell(_40e,_40f)){this.tabbingOut=false;if(this._colHeadNode){this.blurHeader();}this._colHeadNode=this._colHeadFocusIdx=null;this.focusGridView();this._focusifyCellNode(false);this.cell=_40e;this.rowIndex=_40f;this._focusifyCellNode(true);}if(dojo.isOpera){setTimeout(dojo.hitch(this.grid,"onCellFocus",this.cell,this.rowIndex),1);}else{this.grid.onCellFocus(this.cell,this.rowIndex);}},next:function(){if(this.cell){var row=this.rowIndex,col=this.cell.index+1,cc=this.grid.layout.cellCount-1,rc=this.grid.rowCount-1;if(col>cc){col=0;row++;}if(row>rc){col=cc;row=rc;}if(this.grid.edit.isEditing()){var _410=this.grid.getCell(col);if(!this.isLastFocusCell()&&(!_410.editable||this.grid.canEdit&&!this.grid.canEdit(_410,row))){this.cell=_410;this.rowIndex=row;this.next();return;}}this.setFocusIndex(row,col);}},previous:function(){if(this.cell){var row=(this.rowIndex||0),col=(this.cell.index||0)-1;if(col<0){col=this.grid.layout.cellCount-1;row--;}if(row<0){row=0;col=0;}if(this.grid.edit.isEditing()){var _411=this.grid.getCell(col);if(!this.isFirstFocusCell()&&!_411.editable){this.cell=_411;this.rowIndex=row;this.previous();return;}}this.setFocusIndex(row,col);}},move:function(_412,_413){var _414=_413<0?-1:1;if(this.isNavHeader()){var _415=this._findHeaderCells();var _416=currentIdx=dojo.indexOf(_415,this._colHeadNode);currentIdx+=_413;while(currentIdx>=0&&currentIdx<_415.length&&_415[currentIdx].style.display=="none"){currentIdx+=_414;}if((currentIdx>=0)&&(currentIdx<_415.length)){this._setActiveColHeader(_415[currentIdx],currentIdx,_416);}}else{if(this.cell){var sc=this.grid.scroller,r=this.rowIndex,rc=this.grid.rowCount-1,row=Math.min(rc,Math.max(0,r+_412));if(_412){if(_412>0){if(row>sc.getLastPageRow(sc.page)){this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r));}}else{if(_412<0){if(row<=sc.getPageRow(sc.page)){this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row));}}}}var cc=this.grid.layout.cellCount-1,i=this.cell.index,col=Math.min(cc,Math.max(0,i+_413));var cell=this.grid.getCell(col);while(col>=0&&col<cc&&cell&&cell.hidden===true){col+=_414;cell=this.grid.getCell(col);}if(!cell||cell.hidden===true){col=i;}this.setFocusIndex(row,col);if(_412){this.grid.updateRow(r);}}}},previousKey:function(e){if(this.grid.edit.isEditing()){dojo.stopEvent(e);this.previous();}else{if(!this.isNavHeader()&&!this._isHeaderHidden()){this.grid.domNode.focus();dojo.stopEvent(e);}else{this.tabOut(this.grid.domNode);if(this._colHeadFocusIdx!=null){dojo.toggleClass(this._findHeaderCells()[this._colHeadFocusIdx],this.focusClass,false);this._colHeadFocusIdx=null;}this._focusifyCellNode(false);}}},nextKey:function(e){var _417=(this.grid.rowCount===0);if(e.target===this.grid.domNode&&this._colHeadFocusIdx==null){this.focusHeader();dojo.stopEvent(e);}else{if(this.isNavHeader()){this.blurHeader();if(!this.findAndFocusGridCell()){this.tabOut(this.grid.lastFocusNode);}this._colHeadNode=this._colHeadFocusIdx=null;}else{if(this.grid.edit.isEditing()){dojo.stopEvent(e);this.next();}else{this.tabOut(this.grid.lastFocusNode);}}}},tabOut:function(_418){this.tabbingOut=true;_418.focus();},focusGridView:function(){dojox.grid.util.fire(this.focusView,"focus");},focusGrid:function(_419){this.focusGridView();this._focusifyCellNode(true);},findAndFocusGridCell:function(){var _41a=true;var _41b=(this.grid.rowCount===0);if(this.isNoFocusCell()&&!_41b){var _41c=0;var cell=this.grid.getCell(_41c);if(cell.hidden){_41c=this.isNavHeader()?this._colHeadFocusIdx:0;}this.setFocusIndex(0,_41c);}else{if(this.cell&&!_41b){if(this.focusView&&!this.focusView.rowNodes[this.rowIndex]){this.grid.scrollToRow(this.rowIndex);}this.focusGrid();}else{_41a=false;}}this._colHeadNode=this._colHeadFocusIdx=null;return _41a;},focusHeader:function(){var _41d=this._findHeaderCells();var _41e=this._colHeadFocusIdx;if(this._isHeaderHidden()){this.findAndFocusGridCell();}else{if(!this._colHeadFocusIdx){if(this.isNoFocusCell()){this._colHeadFocusIdx=0;}else{this._colHeadFocusIdx=this.cell.index;}}}this._colHeadNode=_41d[this._colHeadFocusIdx];while(this._colHeadNode&&this._colHeadFocusIdx>=0&&this._colHeadFocusIdx<_41d.length&&this._colHeadNode.style.display=="none"){this._colHeadFocusIdx++;this._colHeadNode=_41d[this._colHeadFocusIdx];}if(this._colHeadNode&&this._colHeadNode.style.display!="none"){if(this.headerMenu&&this._contextMenuBindNode!=this.grid.domNode){this.headerMenu.unBindDomNode(this.grid.viewsHeaderNode);this.headerMenu.bindDomNode(this.grid.domNode);this._contextMenuBindNode=this.grid.domNode;}this._setActiveColHeader(this._colHeadNode,this._colHeadFocusIdx,_41e);this._scrollHeader(this._colHeadFocusIdx);this._focusifyCellNode(false);}else{this.findAndFocusGridCell();}},blurHeader:function(){dojo.removeClass(this._colHeadNode,this.focusClass);dojo.removeAttr(this.grid.domNode,"aria-activedescendant");if(this.headerMenu&&this._contextMenuBindNode==this.grid.domNode){var _41f=this.grid.viewsHeaderNode;this.headerMenu.unBindDomNode(this.grid.domNode);this.headerMenu.bindDomNode(_41f);this._contextMenuBindNode=_41f;}},doFocus:function(e){if(e&&e.target!=e.currentTarget){dojo.stopEvent(e);return;}if(!this.tabbingOut){this.focusHeader();}this.tabbingOut=false;dojo.stopEvent(e);},doBlur:function(e){dojo.stopEvent(e);},doContextMenu:function(e){if(!this.headerMenu){dojo.stopEvent(e);}},doLastNodeFocus:function(e){if(this.tabbingOut){this._focusifyCellNode(false);}else{if(this.grid.rowCount>0){if(this.isNoFocusCell()){this.setFocusIndex(0,0);}this._focusifyCellNode(true);}else{this.focusHeader();}}this.tabbingOut=false;dojo.stopEvent(e);},doLastNodeBlur:function(e){dojo.stopEvent(e);},doColHeaderFocus:function(e){this._setActiveColHeader(e.target,dojo.attr(e.target,"idx"),this._colHeadFocusIdx);this._scrollHeader(this.getHeaderIndex());dojo.stopEvent(e);},doColHeaderBlur:function(e){dojo.toggleClass(e.target,this.focusClass,false);}});}if(!dojo._hasResource["dojox.grid._EditManager"]){dojo._hasResource["dojox.grid._EditManager"]=true;dojo.provide("dojox.grid._EditManager");dojo.declare("dojox.grid._EditManager",null,{constructor:function(_420){this.grid=_420;if(dojo.isIE){this.connections=[dojo.connect(document.body,"onfocus",dojo.hitch(this,"_boomerangFocus"))];}else{this.connections=[dojo.connect(this.grid,"onBlur",this,"apply")];}},info:{},destroy:function(){dojo.forEach(this.connections,dojo.disconnect);},cellFocus:function(_421,_422){if(this.grid.singleClickEdit||this.isEditRow(_422)){this.setEditCell(_421,_422);}else{this.apply();}if(this.isEditing()||(_421&&_421.editable&&_421.alwaysEditing)){this._focusEditor(_421,_422);}},rowClick:function(e){if(this.isEditing()&&!this.isEditRow(e.rowIndex)){this.apply();}},styleRow:function(_423){if(_423.index==this.info.rowIndex){_423.customClasses+=" dojoxGridRowEditing";}},dispatchEvent:function(e){var c=e.cell,ed=(c&&c["editable"])?c:0;return ed&&ed.dispatchEvent(e.dispatch,e);},isEditing:function(){return this.info.rowIndex!==undefined;},isEditCell:function(_424,_425){return (this.info.rowIndex===_424)&&(this.info.cell.index==_425);},isEditRow:function(_426){return this.info.rowIndex===_426;},setEditCell:function(_427,_428){if(!this.isEditCell(_428,_427.index)&&this.grid.canEdit&&this.grid.canEdit(_427,_428)){this.start(_427,_428,this.isEditRow(_428)||_427.editable);}},_focusEditor:function(_429,_42a){dojox.grid.util.fire(_429,"focus",[_42a]);},focusEditor:function(){if(this.isEditing()){this._focusEditor(this.info.cell,this.info.rowIndex);}},_boomerangWindow:500,_shouldCatchBoomerang:function(){return this._catchBoomerang>new Date().getTime();},_boomerangFocus:function(){if(this._shouldCatchBoomerang()){this.grid.focus.focusGrid();this.focusEditor();this._catchBoomerang=0;}},_doCatchBoomerang:function(){if(dojo.isIE){this._catchBoomerang=new Date().getTime()+this._boomerangWindow;}},start:function(_42b,_42c,_42d){this.grid.beginUpdate();this.editorApply();if(this.isEditing()&&!this.isEditRow(_42c)){this.applyRowEdit();this.grid.updateRow(_42c);}if(_42d){this.info={cell:_42b,rowIndex:_42c};this.grid.doStartEdit(_42b,_42c);this.grid.updateRow(_42c);}else{this.info={};}this.grid.endUpdate();this.grid.focus.focusGrid();this._focusEditor(_42b,_42c);this._doCatchBoomerang();},_editorDo:function(_42e){var c=this.info.cell;if(c&&c.editable){c[_42e](this.info.rowIndex);}},editorApply:function(){this._editorDo("apply");},editorCancel:function(){this._editorDo("cancel");},applyCellEdit:function(_42f,_430,_431){if(this.grid.canEdit(_430,_431)){this.grid.doApplyCellEdit(_42f,_431,_430.field);}},applyRowEdit:function(){this.grid.doApplyEdit(this.info.rowIndex,this.info.cell.field);},apply:function(){if(this.isEditing()){this.grid.beginUpdate();this.editorApply();this.applyRowEdit();this.info={};this.grid.endUpdate();this.grid.focus.focusGrid();this._doCatchBoomerang();}},cancel:function(){if(this.isEditing()){this.grid.beginUpdate();this.editorCancel();this.info={};this.grid.endUpdate();this.grid.focus.focusGrid();this._doCatchBoomerang();}},save:function(_432,_433){var c=this.info.cell;if(this.isEditRow(_432)&&(!_433||c.view==_433)&&c.editable){c.save(c,this.info.rowIndex);}},restore:function(_434,_435){var c=this.info.cell;if(this.isEditRow(_435)&&c.view==_434&&c.editable){c.restore(c,this.info.rowIndex);}}});}if(!dojo._hasResource["dojox.grid.Selection"]){dojo._hasResource["dojox.grid.Selection"]=true;dojo.provide("dojox.grid.Selection");dojo.declare("dojox.grid.Selection",null,{constructor:function(_436){this.grid=_436;this.selected=[];this.setMode(_436.selectionMode);},mode:"extended",selected:null,updating:0,selectedIndex:-1,setMode:function(mode){if(this.selected.length){this.deselectAll();}if(mode!="extended"&&mode!="multiple"&&mode!="single"&&mode!="none"){this.mode="extended";}else{this.mode=mode;}},onCanSelect:function(_437){return this.grid.onCanSelect(_437);},onCanDeselect:function(_438){return this.grid.onCanDeselect(_438);},onSelected:function(_439){},onDeselected:function(_43a){},onChanging:function(){},onChanged:function(){},isSelected:function(_43b){if(this.mode=="none"){return false;}return this.selected[_43b];},getFirstSelected:function(){if(!this.selected.length||this.mode=="none"){return -1;}for(var i=0,l=this.selected.length;i<l;i++){if(this.selected[i]){return i;}}return -1;},getNextSelected:function(_43c){if(this.mode=="none"){return -1;}for(var i=_43c+1,l=this.selected.length;i<l;i++){if(this.selected[i]){return i;}}return -1;},getSelected:function(){var _43d=[];for(var i=0,l=this.selected.length;i<l;i++){if(this.selected[i]){_43d.push(i);}}return _43d;},getSelectedCount:function(){var c=0;for(var i=0;i<this.selected.length;i++){if(this.selected[i]){c++;}}return c;},_beginUpdate:function(){if(this.updating===0){this.onChanging();}this.updating++;},_endUpdate:function(){this.updating--;if(this.updating===0){this.onChanged();}},select:function(_43e){if(this.mode=="none"){return;}if(this.mode!="multiple"){this.deselectAll(_43e);this.addToSelection(_43e);}else{this.toggleSelect(_43e);}},addToSelection:function(_43f){if(this.mode=="none"){return;}if(dojo.isArray(_43f)){dojo.forEach(_43f,this.addToSelection,this);return;}_43f=Number(_43f);if(this.selected[_43f]){this.selectedIndex=_43f;}else{if(this.onCanSelect(_43f)!==false){this.selectedIndex=_43f;var _440=this.grid.getRowNode(_43f);if(_440){dojo.attr(_440,"aria-selected","true");}this._beginUpdate();this.selected[_43f]=true;this.onSelected(_43f);this._endUpdate();}}},deselect:function(_441){if(this.mode=="none"){return;}if(dojo.isArray(_441)){dojo.forEach(_441,this.deselect,this);return;}_441=Number(_441);if(this.selectedIndex==_441){this.selectedIndex=-1;}if(this.selected[_441]){if(this.onCanDeselect(_441)===false){return;}var _442=this.grid.getRowNode(_441);if(_442){dojo.attr(_442,"aria-selected","false");}this._beginUpdate();delete this.selected[_441];this.onDeselected(_441);this._endUpdate();}},setSelected:function(_443,_444){this[(_444?"addToSelection":"deselect")](_443);},toggleSelect:function(_445){if(dojo.isArray(_445)){dojo.forEach(_445,this.toggleSelect,this);return;}this.setSelected(_445,!this.selected[_445]);},_range:function(_446,inTo,func){var s=(_446>=0?_446:inTo),e=inTo;if(s>e){e=s;s=inTo;}for(var i=s;i<=e;i++){func(i);}},selectRange:function(_447,inTo){this._range(_447,inTo,dojo.hitch(this,"addToSelection"));},deselectRange:function(_448,inTo){this._range(_448,inTo,dojo.hitch(this,"deselect"));},insert:function(_449){this.selected.splice(_449,0,false);if(this.selectedIndex>=_449){this.selectedIndex++;}},remove:function(_44a){this.selected.splice(_44a,1);if(this.selectedIndex>=_44a){this.selectedIndex--;}},deselectAll:function(_44b){for(var i in this.selected){if((i!=_44b)&&(this.selected[i]===true)){this.deselect(i);}}},clickSelect:function(_44c,_44d,_44e){if(this.mode=="none"){return;}this._beginUpdate();if(this.mode!="extended"){this.select(_44c);}else{var _44f=this.selectedIndex;if(!_44d){this.deselectAll(_44c);}if(_44e){this.selectRange(_44f,_44c);}else{if(_44d){this.toggleSelect(_44c);}else{this.addToSelection(_44c);}}}this._endUpdate();},clickSelectEvent:function(e){this.clickSelect(e.rowIndex,dojo.isCopyKey(e),e.shiftKey);},clear:function(){this._beginUpdate();this.deselectAll();this._endUpdate();}});}if(!dojo._hasResource["dojox.grid._Events"]){dojo._hasResource["dojox.grid._Events"]=true;dojo.provide("dojox.grid._Events");dojo.declare("dojox.grid._Events",null,{cellOverClass:"dojoxGridCellOver",onKeyEvent:function(e){this.dispatchKeyEvent(e);},onContentEvent:function(e){this.dispatchContentEvent(e);},onHeaderEvent:function(e){this.dispatchHeaderEvent(e);},onStyleRow:function(_450){var i=_450;i.customClasses+=(i.odd?" dojoxGridRowOdd":"")+(i.selected?" dojoxGridRowSelected":"")+(i.over?" dojoxGridRowOver":"");this.focus.styleRow(_450);this.edit.styleRow(_450);},onKeyDown:function(e){if(e.altKey||e.metaKey){return;}var dk=dojo.keys;var _451;switch(e.keyCode){case dk.ESCAPE:this.edit.cancel();break;case dk.ENTER:if(!this.edit.isEditing()){_451=this.focus.getHeaderIndex();if(_451>=0){this.setSortIndex(_451);break;}else{this.selection.clickSelect(this.focus.rowIndex,dojo.isCopyKey(e),e.shiftKey);}dojo.stopEvent(e);}if(!e.shiftKey){var _452=this.edit.isEditing();this.edit.apply();if(!_452){this.edit.setEditCell(this.focus.cell,this.focus.rowIndex);}}if(!this.edit.isEditing()){var _453=this.focus.focusView||this.views.views[0];_453.content.decorateEvent(e);this.onRowClick(e);}break;case dk.SPACE:if(!this.edit.isEditing()){_451=this.focus.getHeaderIndex();if(_451>=0){this.setSortIndex(_451);break;}else{this.selection.clickSelect(this.focus.rowIndex,dojo.isCopyKey(e),e.shiftKey);}dojo.stopEvent(e);}break;case dk.TAB:this.focus[e.shiftKey?"previousKey":"nextKey"](e);break;case dk.LEFT_ARROW:case dk.RIGHT_ARROW:if(!this.edit.isEditing()){var _454=e.keyCode;dojo.stopEvent(e);_451=this.focus.getHeaderIndex();if(_451>=0&&(e.shiftKey&&e.ctrlKey)){this.focus.colSizeAdjust(e,_451,(_454==dk.LEFT_ARROW?-1:1)*5);}else{var _455=(_454==dk.LEFT_ARROW)?1:-1;if(dojo._isBodyLtr()){_455*=-1;}this.focus.move(0,_455);}}break;case dk.UP_ARROW:if(!this.edit.isEditing()&&this.focus.rowIndex!==0){dojo.stopEvent(e);this.focus.move(-1,0);}break;case dk.DOWN_ARROW:if(!this.edit.isEditing()&&this.focus.rowIndex+1!=this.rowCount){dojo.stopEvent(e);this.focus.move(1,0);}break;case dk.PAGE_UP:if(!this.edit.isEditing()&&this.focus.rowIndex!==0){dojo.stopEvent(e);if(this.focus.rowIndex!=this.scroller.firstVisibleRow+1){this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex,0);}else{this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1));this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1,0);}}break;case dk.PAGE_DOWN:if(!this.edit.isEditing()&&this.focus.rowIndex+1!=this.rowCount){dojo.stopEvent(e);if(this.focus.rowIndex!=this.scroller.lastVisibleRow-1){this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1,0);}else{this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1));this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1,0);}}break;default:break;}},onMouseOver:function(e){e.rowIndex==-1?this.onHeaderCellMouseOver(e):this.onCellMouseOver(e);},onMouseOut:function(e){e.rowIndex==-1?this.onHeaderCellMouseOut(e):this.onCellMouseOut(e);},onMouseDown:function(e){e.rowIndex==-1?this.onHeaderCellMouseDown(e):this.onCellMouseDown(e);},onMouseOverRow:function(e){if(!this.rows.isOver(e.rowIndex)){this.rows.setOverRow(e.rowIndex);e.rowIndex==-1?this.onHeaderMouseOver(e):this.onRowMouseOver(e);}},onMouseOutRow:function(e){if(this.rows.isOver(-1)){this.onHeaderMouseOut(e);}else{if(!this.rows.isOver(-2)){this.rows.setOverRow(-2);this.onRowMouseOut(e);}}},onMouseDownRow:function(e){if(e.rowIndex!=-1){this.onRowMouseDown(e);}},onCellMouseOver:function(e){if(e.cellNode){dojo.addClass(e.cellNode,this.cellOverClass);}},onCellMouseOut:function(e){if(e.cellNode){dojo.removeClass(e.cellNode,this.cellOverClass);}},onCellMouseDown:function(e){},onCellClick:function(e){this._click[0]=this._click[1];this._click[1]=e;if(!this.edit.isEditCell(e.rowIndex,e.cellIndex)){this.focus.setFocusCell(e.cell,e.rowIndex);}this.onRowClick(e);},onCellDblClick:function(e){if(this._click.length>1&&dojo.isIE){this.edit.setEditCell(this._click[1].cell,this._click[1].rowIndex);}else{if(this._click.length>1&&this._click[0].rowIndex!=this._click[1].rowIndex){this.edit.setEditCell(this._click[0].cell,this._click[0].rowIndex);}else{this.edit.setEditCell(e.cell,e.rowIndex);}}this.onRowDblClick(e);},onCellContextMenu:function(e){this.onRowContextMenu(e);},onCellFocus:function(_456,_457){this.edit.cellFocus(_456,_457);},onRowClick:function(e){this.edit.rowClick(e);this.selection.clickSelectEvent(e);},onRowDblClick:function(e){},onRowMouseOver:function(e){},onRowMouseOut:function(e){},onRowMouseDown:function(e){},onRowContextMenu:function(e){dojo.stopEvent(e);},onHeaderMouseOver:function(e){},onHeaderMouseOut:function(e){},onHeaderCellMouseOver:function(e){if(e.cellNode){dojo.addClass(e.cellNode,this.cellOverClass);}},onHeaderCellMouseOut:function(e){if(e.cellNode){dojo.removeClass(e.cellNode,this.cellOverClass);}},onHeaderCellMouseDown:function(e){},onHeaderClick:function(e){},onHeaderCellClick:function(e){this.setSortIndex(e.cell.index);this.onHeaderClick(e);},onHeaderDblClick:function(e){},onHeaderCellDblClick:function(e){this.onHeaderDblClick(e);},onHeaderCellContextMenu:function(e){this.onHeaderContextMenu(e);},onHeaderContextMenu:function(e){if(!this.headerMenu){dojo.stopEvent(e);}},onStartEdit:function(_458,_459){},onApplyCellEdit:function(_45a,_45b,_45c){},onCancelEdit:function(_45d){},onApplyEdit:function(_45e){},onCanSelect:function(_45f){return true;},onCanDeselect:function(_460){return true;},onSelected:function(_461){this.updateRowStyles(_461);},onDeselected:function(_462){this.updateRowStyles(_462);},onSelectionChanged:function(){}});}if(!dojo._hasResource["dojo.i18n"]){dojo._hasResource["dojo.i18n"]=true;dojo.provide("dojo.i18n");dojo.getObject("i18n",true,dojo);dojo.i18n.getLocalization=dojo.i18n.getLocalization||function(_463,_464,_465){_465=dojo.i18n.normalizeLocale(_465);var _466=_465.split("-");var _467=[_463,"nls",_464].join(".");var _468=dojo._loadedModules[_467];if(_468){var _469;for(var i=_466.length;i>0;i--){var loc=_466.slice(0,i).join("_");if(_468[loc]){_469=_468[loc];break;}}if(!_469){_469=_468.ROOT;}if(_469){var _46a=function(){};_46a.prototype=_469;return new _46a();}}throw new Error("Bundle not found: "+_464+" in "+_463+" , locale="+_465);};dojo.i18n.normalizeLocale=function(_46b){var _46c=_46b?_46b.toLowerCase():dojo.locale;if(_46c=="root"){_46c="ROOT";}return _46c;};dojo.i18n._requireLocalization=function(_46d,_46e,_46f,_470){var _471=dojo.i18n.normalizeLocale(_46f);var _472=[_46d,"nls",_46e].join(".");var _473="";if(_470){var _474=_470.split(",");for(var i=0;i<_474.length;i++){if(_471["indexOf"](_474[i])==0){if(_474[i].length>_473.length){_473=_474[i];}}}if(!_473){_473="ROOT";}}var _475=_470?_473:_471;var _476=dojo._loadedModules[_472];var _477=null;if(_476){if(dojo.config.localizationComplete&&_476._built){return;}var _478=_475.replace(/-/g,"_");var _479=_472+"."+_478;_477=dojo._loadedModules[_479];}if(!_477){_476=dojo["provide"](_472);var syms=dojo._getModuleSymbols(_46d);var _47a=syms.concat("nls").join("/");var _47b;dojo.i18n._searchLocalePath(_475,_470,function(loc){var _47c=loc.replace(/-/g,"_");var _47d=_472+"."+_47c;var _47e=false;if(!dojo._loadedModules[_47d]){dojo["provide"](_47d);var _47f=[_47a];if(loc!="ROOT"){_47f.push(loc);}_47f.push(_46e);var _480=_47f.join("/")+".js";_47e=dojo._loadPath(_480,null,function(hash){hash=hash.root||hash;var _481=function(){};_481.prototype=_47b;_476[_47c]=new _481();for(var j in hash){_476[_47c][j]=hash[j];}});}else{_47e=true;}if(_47e&&_476[_47c]){_47b=_476[_47c];}else{_476[_47c]=_47b;}if(_470){return true;}});}if(_470&&_471!=_473){_476[_471.replace(/-/g,"_")]=_476[_473.replace(/-/g,"_")];}};(function(){var _482=dojo.config.extraLocale;if(_482){if(!_482 instanceof Array){_482=[_482];}var req=dojo.i18n._requireLocalization;dojo.i18n._requireLocalization=function(m,b,_483,_484){req(m,b,_483,_484);if(_483){return;}for(var i=0;i<_482.length;i++){req(m,b,_482[i],_484);}};}})();dojo.i18n._searchLocalePath=function(_485,down,_486){_485=dojo.i18n.normalizeLocale(_485);var _487=_485.split("-");var _488=[];for(var i=_487.length;i>0;i--){_488.push(_487.slice(0,i).join("-"));}_488.push(false);if(down){_488.reverse();}for(var j=_488.length-1;j>=0;j--){var loc=_488[j]||"ROOT";var stop=_486(loc);if(stop){break;}}};dojo.i18n._preloadLocalizations=function(_489,_48a){function _48b(_48c){_48c=dojo.i18n.normalizeLocale(_48c);dojo.i18n._searchLocalePath(_48c,true,function(loc){for(var i=0;i<_48a.length;i++){if(_48a[i]==loc){dojo["require"](_489+"_"+loc);return true;}}return false;});};_48b();var _48d=dojo.config.extraLocale||[];for(var i=0;i<_48d.length;i++){_48b(_48d[i]);}};}if(!dojo._hasResource["dojox.grid._Grid"]){dojo._hasResource["dojox.grid._Grid"]=true;dojo.provide("dojox.grid._Grid");(function(){if(!dojo.isCopyKey){dojo.isCopyKey=dojo.dnd.getCopyKeyState;}dojo.declare("dojox.grid._Grid",[dijit._Widget,dijit._Templated,dojox.grid._Events],{templateString:"<div hidefocus=\"hidefocus\" role=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\r\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" role=\"presentation\"></div>\r\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" role=\"presentation\"></div>\r\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\r\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\r\n</div>\r\n",classTag:"dojoxGrid",rowCount:5,keepRows:75,rowsPerPage:25,autoWidth:false,initialWidth:"",autoHeight:"",rowHeight:0,autoRender:true,defaultHeight:"15em",height:"",structure:null,elasticView:-1,singleClickEdit:false,selectionMode:"extended",rowSelector:"",columnReordering:false,headerMenu:null,placeholderLabel:"GridColumns",selectable:false,_click:null,loadingMessage:"<span class='dojoxGridLoading'>${loadingState}</span>",errorMessage:"<span class='dojoxGridError'>${errorState}</span>",noDataMessage:"",escapeHTMLInData:true,formatterScope:null,editable:false,sortInfo:0,themeable:true,_placeholders:null,_layoutClass:dojox.grid._Layout,buildRendering:function(){this.inherited(arguments);if(!this.domNode.getAttribute("tabIndex")){this.domNode.tabIndex="0";}this.createScroller();this.createLayout();this.createViews();this.createManagers();this.createSelection();this.connect(this.selection,"onSelected","onSelected");this.connect(this.selection,"onDeselected","onDeselected");this.connect(this.selection,"onChanged","onSelectionChanged");dojox.html.metrics.initOnFontResize();this.connect(dojox.html.metrics,"onFontResize","textSizeChanged");dojox.grid.util.funnelEvents(this.domNode,this,"doKeyEvent",dojox.grid.util.keyEvents);if(this.selectionMode!="none"){dojo.attr(this.domNode,"aria-multiselectable",this.selectionMode=="single"?"false":"true");}dojo.addClass(this.domNode,this.classTag);if(!this.isLeftToRight()){dojo.addClass(this.domNode,this.classTag+"Rtl");}},postMixInProperties:function(){this.inherited(arguments);var _48e=dojo.i18n.getLocalization("dijit","loading",this.lang);this.loadingMessage=dojo.string.substitute(this.loadingMessage,_48e);this.errorMessage=dojo.string.substitute(this.errorMessage,_48e);if(this.srcNodeRef&&this.srcNodeRef.style.height){this.height=this.srcNodeRef.style.height;}this._setAutoHeightAttr(this.autoHeight,true);this.lastScrollTop=this.scrollTop=0;},postCreate:function(){this._placeholders=[];this._setHeaderMenuAttr(this.headerMenu);this._setStructureAttr(this.structure);this._click=[];this.inherited(arguments);if(this.domNode&&this.autoWidth&&this.initialWidth){this.domNode.style.width=this.initialWidth;}if(this.domNode&&!this.editable){dojo.attr(this.domNode,"aria-readonly","true");}},destroy:function(){this.domNode.onReveal=null;this.domNode.onSizeChange=null;delete this._click;this.edit.destroy();delete this.edit;this.views.destroyViews();if(this.scroller){this.scroller.destroy();delete this.scroller;}if(this.focus){this.focus.destroy();delete this.focus;}if(this.headerMenu&&this._placeholders.length){dojo.forEach(this._placeholders,function(p){p.unReplace(true);});this.headerMenu.unBindDomNode(this.viewsHeaderNode);}this.inherited(arguments);},_setAutoHeightAttr:function(ah,_48f){if(typeof ah=="string"){if(!ah||ah=="false"){ah=false;}else{if(ah=="true"){ah=true;}else{ah=window.parseInt(ah,10);}}}if(typeof ah=="number"){if(isNaN(ah)){ah=false;}if(ah<0){ah=true;}else{if(ah===0){ah=false;}}}this.autoHeight=ah;if(typeof ah=="boolean"){this._autoHeight=ah;}else{if(typeof ah=="number"){this._autoHeight=(ah>=this.get("rowCount"));}else{this._autoHeight=false;}}if(this._started&&!_48f){this.render();}},_getRowCountAttr:function(){return this.updating&&this.invalidated&&this.invalidated.rowCount!=undefined?this.invalidated.rowCount:this.rowCount;},textSizeChanged:function(){this.render();},sizeChange:function(){this.update();},createManagers:function(){this.rows=new dojox.grid._RowManager(this);this.focus=new dojox.grid._FocusManager(this);this.edit=new dojox.grid._EditManager(this);},createSelection:function(){this.selection=new dojox.grid.Selection(this);},createScroller:function(){this.scroller=new dojox.grid._Scroller();this.scroller.grid=this;this.scroller.renderRow=dojo.hitch(this,"renderRow");this.scroller.removeRow=dojo.hitch(this,"rowRemoved");},createLayout:function(){this.layout=new this._layoutClass(this);this.connect(this.layout,"moveColumn","onMoveColumn");},onMoveColumn:function(){this.render();},onResizeColumn:function(_490){},createViews:function(){this.views=new dojox.grid._ViewManager(this);this.views.createView=dojo.hitch(this,"createView");},createView:function(_491,idx){var c=dojo.getObject(_491);var view=new c({grid:this,index:idx});this.viewsNode.appendChild(view.domNode);this.viewsHeaderNode.appendChild(view.headerNode);this.views.addView(view);dojo.attr(this.domNode,"align",dojo._isBodyLtr()?"left":"right");return view;},buildViews:function(){for(var i=0,vs;(vs=this.layout.structure[i]);i++){this.createView(vs.type||dojox._scopeName+".grid._View",i).setStructure(vs);}this.scroller.setContentNodes(this.views.getContentNodes());},_setStructureAttr:function(_492){var s=_492;if(s&&dojo.isString(s)){dojo.deprecated("dojox.grid._Grid.set('structure', 'objVar')","use dojox.grid._Grid.set('structure', objVar) instead","2.0");s=dojo.getObject(s);}this.structure=s;if(!s){if(this.layout.structure){s=this.layout.structure;}else{return;}}this.views.destroyViews();if(s!==this.layout.structure){this.layout.setStructure(s);}this._structureChanged();},setStructure:function(_493){dojo.deprecated("dojox.grid._Grid.setStructure(obj)","use dojox.grid._Grid.set('structure', obj) instead.","2.0");this._setStructureAttr(_493);},getColumnTogglingItems:function(){return dojo.map(this.layout.cells,function(cell){if(!cell.menuItems){cell.menuItems=[];}var self=this;var item=new dijit.CheckedMenuItem({label:cell.name,checked:!cell.hidden,_gridCell:cell,onChange:function(_494){if(self.layout.setColumnVisibility(this._gridCell.index,_494)){var _495=this._gridCell.menuItems;if(_495.length>1){dojo.forEach(_495,function(item){if(item!==this){item.setAttribute("checked",_494);}},this);}_494=dojo.filter(self.layout.cells,function(c){if(c.menuItems.length>1){dojo.forEach(c.menuItems,"item.set('disabled', false);");}else{c.menuItems[0].set("disabled",false);}return !c.hidden;});if(_494.length==1){dojo.forEach(_494[0].menuItems,"item.set('disabled', true);");}}},destroy:function(){var _496=dojo.indexOf(this._gridCell.menuItems,this);this._gridCell.menuItems.splice(_496,1);delete this._gridCell;dijit.CheckedMenuItem.prototype.destroy.apply(this,arguments);}});cell.menuItems.push(item);return item;},this);},_setHeaderMenuAttr:function(menu){if(this._placeholders&&this._placeholders.length){dojo.forEach(this._placeholders,function(p){p.unReplace(true);});this._placeholders=[];}if(this.headerMenu){this.headerMenu.unBindDomNode(this.viewsHeaderNode);}this.headerMenu=menu;if(!menu){return;}this.headerMenu.bindDomNode(this.viewsHeaderNode);if(this.headerMenu.getPlaceholders){this._placeholders=this.headerMenu.getPlaceholders(this.placeholderLabel);}},setHeaderMenu:function(menu){dojo.deprecated("dojox.grid._Grid.setHeaderMenu(obj)","use dojox.grid._Grid.set('headerMenu', obj) instead.","2.0");this._setHeaderMenuAttr(menu);},setupHeaderMenu:function(){if(this._placeholders&&this._placeholders.length){dojo.forEach(this._placeholders,function(p){if(p._replaced){p.unReplace(true);}p.replace(this.getColumnTogglingItems());},this);}},_fetch:function(_497){this.setScrollTop(0);},getItem:function(_498){return null;},showMessage:function(_499){if(_499){this.messagesNode.innerHTML=_499;this.messagesNode.style.display="";}else{this.messagesNode.innerHTML="";this.messagesNode.style.display="none";}},_structureChanged:function(){this.buildViews();if(this.autoRender&&this._started){this.render();}},hasLayout:function(){return this.layout.cells.length;},resize:function(_49a,_49b){this._pendingChangeSize=_49a;this._pendingResultSize=_49b;this.sizeChange();},_getPadBorder:function(){this._padBorder=this._padBorder||dojo._getPadBorderExtents(this.domNode);return this._padBorder;},_getHeaderHeight:function(){var vns=this.viewsHeaderNode.style,t=vns.display=="none"?0:this.views.measureHeader();vns.height=t+"px";this.views.normalizeHeaderNodeHeight();return t;},_resize:function(_49c,_49d){_49c=_49c||this._pendingChangeSize;_49d=_49d||this._pendingResultSize;delete this._pendingChangeSize;delete this._pendingResultSize;if(!this.domNode){return;}var pn=this.domNode.parentNode;if(!pn||pn.nodeType!=1||!this.hasLayout()||pn.style.visibility=="hidden"||pn.style.display=="none"){return;}var _49e=this._getPadBorder();var hh=undefined;var h;if(this._autoHeight){this.domNode.style.height="auto";}else{if(typeof this.autoHeight=="number"){h=hh=this._getHeaderHeight();h+=(this.scroller.averageRowHeight*this.autoHeight);this.domNode.style.height=h+"px";}else{if(this.domNode.clientHeight<=_49e.h){if(pn==document.body){this.domNode.style.height=this.defaultHeight;}else{if(this.height){this.domNode.style.height=this.height;}else{this.fitTo="parent";}}}}}if(_49d){_49c=_49d;}if(_49c){dojo.marginBox(this.domNode,_49c);this.height=this.domNode.style.height;delete this.fitTo;}else{if(this.fitTo=="parent"){h=this._parentContentBoxHeight=this._parentContentBoxHeight||dojo._getContentBox(pn).h;this.domNode.style.height=Math.max(0,h)+"px";}}var _49f=dojo.some(this.views.views,function(v){return v.flexCells;});if(!this._autoHeight&&(h||dojo._getContentBox(this.domNode).h)===0){this.viewsHeaderNode.style.display="none";}else{this.viewsHeaderNode.style.display="block";if(!_49f&&hh===undefined){hh=this._getHeaderHeight();}}if(_49f){hh=undefined;}this.adaptWidth();this.adaptHeight(hh);this.postresize();},adaptWidth:function(){var _4a0=(!this.initialWidth&&this.autoWidth);var w=_4a0?0:this.domNode.clientWidth||(this.domNode.offsetWidth-this._getPadBorder().w),vw=this.views.arrange(1,w);this.views.onEach("adaptWidth");if(_4a0){this.domNode.style.width=vw+"px";}},adaptHeight:function(_4a1){var t=_4a1===undefined?this._getHeaderHeight():_4a1;var h=(this._autoHeight?-1:Math.max(this.domNode.clientHeight-t,0)||0);this.views.onEach("setSize",[0,h]);this.views.onEach("adaptHeight");if(!this._autoHeight){var _4a2=0,_4a3=0;var _4a4=dojo.filter(this.views.views,function(v){var has=v.hasHScrollbar();if(has){_4a2++;}else{_4a3++;}return (!has);});if(_4a2>0&&_4a3>0){dojo.forEach(_4a4,function(v){v.adaptHeight(true);});}}if(this.autoHeight===true||h!=-1||(typeof this.autoHeight=="number"&&this.autoHeight>=this.get("rowCount"))){this.scroller.windowHeight=h;}else{this.scroller.windowHeight=Math.max(this.domNode.clientHeight-t,0);}},startup:function(){if(this._started){return;}this.inherited(arguments);if(this.autoRender){this.render();}},render:function(){if(!this.domNode){return;}if(!this._started){return;}if(!this.hasLayout()){this.scroller.init(0,this.keepRows,this.rowsPerPage);return;}this.update=this.defaultUpdate;this._render();},_render:function(){this.scroller.init(this.get("rowCount"),this.keepRows,this.rowsPerPage);this.prerender();this.setScrollTop(0);this.postrender();},prerender:function(){this.keepRows=this._autoHeight?0:this.keepRows;this.scroller.setKeepInfo(this.keepRows);this.views.render();this._resize();},postrender:function(){this.postresize();this.focus.initFocusView();dojo.setSelectable(this.domNode,this.selectable);},postresize:function(){if(this._autoHeight){var size=Math.max(this.views.measureContent())+"px";this.viewsNode.style.height=size;}},renderRow:function(_4a5,_4a6){this.views.renderRow(_4a5,_4a6,this._skipRowRenormalize);},rowRemoved:function(_4a7){this.views.rowRemoved(_4a7);},invalidated:null,updating:false,beginUpdate:function(){this.invalidated=[];this.updating=true;},endUpdate:function(){this.updating=false;var i=this.invalidated,r;if(i.all){this.update();}else{if(i.rowCount!=undefined){this.updateRowCount(i.rowCount);}else{for(r in i){this.updateRow(Number(r));}}}this.invalidated=[];},defaultUpdate:function(){if(!this.domNode){return;}if(this.updating){this.invalidated.all=true;return;}this.lastScrollTop=this.scrollTop;this.prerender();this.scroller.invalidateNodes();this.setScrollTop(this.lastScrollTop);this.postrender();},update:function(){this.render();},updateRow:function(_4a8){_4a8=Number(_4a8);if(this.updating){this.invalidated[_4a8]=true;}else{this.views.updateRow(_4a8);this.scroller.rowHeightChanged(_4a8);}},updateRows:function(_4a9,_4aa){_4a9=Number(_4a9);_4aa=Number(_4aa);var i;if(this.updating){for(i=0;i<_4aa;i++){this.invalidated[i+_4a9]=true;}}else{for(i=0;i<_4aa;i++){this.views.updateRow(i+_4a9,this._skipRowRenormalize);}this.scroller.rowHeightChanged(_4a9);}},updateRowCount:function(_4ab){if(this.updating){this.invalidated.rowCount=_4ab;}else{this.rowCount=_4ab;this._setAutoHeightAttr(this.autoHeight,true);if(this.layout.cells.length){this.scroller.updateRowCount(_4ab);}this._resize();if(this.layout.cells.length){this.setScrollTop(this.scrollTop);}}},updateRowStyles:function(_4ac){this.views.updateRowStyles(_4ac);},getRowNode:function(_4ad){if(this.focus.focusView&&!(this.focus.focusView instanceof dojox.grid._RowSelector)){return this.focus.focusView.rowNodes[_4ad];}else{for(var i=0,_4ae;(_4ae=this.views.views[i]);i++){if(!(_4ae instanceof dojox.grid._RowSelector)){return _4ae.rowNodes[_4ad];}}}return null;},rowHeightChanged:function(_4af){this.views.renormalizeRow(_4af);this.scroller.rowHeightChanged(_4af);},fastScroll:true,delayScroll:false,scrollRedrawThreshold:(dojo.isIE?100:50),scrollTo:function(_4b0){if(!this.fastScroll){this.setScrollTop(_4b0);return;}var _4b1=Math.abs(this.lastScrollTop-_4b0);this.lastScrollTop=_4b0;if(_4b1>this.scrollRedrawThreshold||this.delayScroll){this.delayScroll=true;this.scrollTop=_4b0;this.views.setScrollTop(_4b0);if(this._pendingScroll){window.clearTimeout(this._pendingScroll);}var _4b2=this;this._pendingScroll=window.setTimeout(function(){delete _4b2._pendingScroll;_4b2.finishScrollJob();},200);}else{this.setScrollTop(_4b0);}},finishScrollJob:function(){this.delayScroll=false;this.setScrollTop(this.scrollTop);},setScrollTop:function(_4b3){this.scroller.scroll(this.views.setScrollTop(_4b3));},scrollToRow:function(_4b4){this.setScrollTop(this.scroller.findScrollTop(_4b4)+1);},styleRowNode:function(_4b5,_4b6){if(_4b6){this.rows.styleRowNode(_4b5,_4b6);}},_mouseOut:function(e){this.rows.setOverRow(-2);},getCell:function(_4b7){return this.layout.cells[_4b7];},setCellWidth:function(_4b8,_4b9){this.getCell(_4b8).unitWidth=_4b9;},getCellName:function(_4ba){return "Cell "+_4ba.index;},canSort:function(_4bb){},sort:function(){},getSortAsc:function(_4bc){_4bc=_4bc==undefined?this.sortInfo:_4bc;return Boolean(_4bc>0);},getSortIndex:function(_4bd){_4bd=_4bd==undefined?this.sortInfo:_4bd;return Math.abs(_4bd)-1;},setSortIndex:function(_4be,_4bf){var si=_4be+1;if(_4bf!=undefined){si*=(_4bf?1:-1);}else{if(this.getSortIndex()==_4be){si=-this.sortInfo;}}this.setSortInfo(si);},setSortInfo:function(_4c0){if(this.canSort(_4c0)){this.sortInfo=_4c0;this.sort();this.update();}},doKeyEvent:function(e){e.dispatch="do"+e.type;this.onKeyEvent(e);},_dispatch:function(m,e){if(m in this){return this[m](e);}return false;},dispatchKeyEvent:function(e){this._dispatch(e.dispatch,e);},dispatchContentEvent:function(e){this.edit.dispatchEvent(e)||e.sourceView.dispatchContentEvent(e)||this._dispatch(e.dispatch,e);},dispatchHeaderEvent:function(e){e.sourceView.dispatchHeaderEvent(e)||this._dispatch("doheader"+e.type,e);},dokeydown:function(e){this.onKeyDown(e);},doclick:function(e){if(e.cellNode){this.onCellClick(e);}else{this.onRowClick(e);}},dodblclick:function(e){if(e.cellNode){this.onCellDblClick(e);}else{this.onRowDblClick(e);}},docontextmenu:function(e){if(e.cellNode){this.onCellContextMenu(e);}else{this.onRowContextMenu(e);}},doheaderclick:function(e){if(e.cellNode){this.onHeaderCellClick(e);}else{this.onHeaderClick(e);}},doheaderdblclick:function(e){if(e.cellNode){this.onHeaderCellDblClick(e);}else{this.onHeaderDblClick(e);}},doheadercontextmenu:function(e){if(e.cellNode){this.onHeaderCellContextMenu(e);}else{this.onHeaderContextMenu(e);}},doStartEdit:function(_4c1,_4c2){this.onStartEdit(_4c1,_4c2);},doApplyCellEdit:function(_4c3,_4c4,_4c5){this.onApplyCellEdit(_4c3,_4c4,_4c5);},doCancelEdit:function(_4c6){this.onCancelEdit(_4c6);},doApplyEdit:function(_4c7){this.onApplyEdit(_4c7);},addRow:function(){this.updateRowCount(this.get("rowCount")+1);},removeSelectedRows:function(){if(this.allItemsSelected){this.updateRowCount(0);}else{this.updateRowCount(Math.max(0,this.get("rowCount")-this.selection.getSelected().length));}this.selection.clear();}});dojox.grid._Grid.markupFactory=function(_4c8,node,ctor,_4c9){var d=dojo;var _4ca=function(n){var w=d.attr(n,"width")||"auto";if((w!="auto")&&(w.slice(-2)!="em")&&(w.slice(-1)!="%")){w=parseInt(w,10)+"px";}return w;};if(!_4c8.structure&&node.nodeName.toLowerCase()=="table"){_4c8.structure=d.query("> colgroup",node).map(function(cg){var sv=d.attr(cg,"span");var v={noscroll:(d.attr(cg,"noscroll")=="true")?true:false,__span:(!!sv?parseInt(sv,10):1),cells:[]};if(d.hasAttr(cg,"width")){v.width=_4ca(cg);}return v;});if(!_4c8.structure.length){_4c8.structure.push({__span:Infinity,cells:[]});}d.query("thead > tr",node).forEach(function(tr,_4cb){var _4cc=0;var _4cd=0;var _4ce;var _4cf=null;d.query("> th",tr).map(function(th){if(!_4cf){_4ce=0;_4cf=_4c8.structure[0];}else{if(_4cc>=(_4ce+_4cf.__span)){_4cd++;_4ce+=_4cf.__span;var _4d0=_4cf;_4cf=_4c8.structure[_4cd];}}var cell={name:d.trim(d.attr(th,"name")||th.innerHTML),colSpan:parseInt(d.attr(th,"colspan")||1,10),type:d.trim(d.attr(th,"cellType")||""),id:d.trim(d.attr(th,"id")||"")};_4cc+=cell.colSpan;var _4d1=d.attr(th,"rowspan");if(_4d1){cell.rowSpan=_4d1;}if(d.hasAttr(th,"width")){cell.width=_4ca(th);}if(d.hasAttr(th,"relWidth")){cell.relWidth=window.parseInt(dojo.attr(th,"relWidth"),10);}if(d.hasAttr(th,"hidden")){cell.hidden=(d.attr(th,"hidden")=="true"||d.attr(th,"hidden")===true);}if(_4c9){_4c9(th,cell);}cell.type=cell.type?dojo.getObject(cell.type):dojox.grid.cells.Cell;if(cell.type&&cell.type.markupFactory){cell.type.markupFactory(th,cell);}if(!_4cf.cells[_4cb]){_4cf.cells[_4cb]=[];}_4cf.cells[_4cb].push(cell);});});}return new ctor(_4c8,node);};})();}if(!dojo._hasResource["dojox.grid.DataSelection"]){dojo._hasResource["dojox.grid.DataSelection"]=true;dojo.provide("dojox.grid.DataSelection");dojo.declare("dojox.grid.DataSelection",dojox.grid.Selection,{getFirstSelected:function(){var idx=dojox.grid.Selection.prototype.getFirstSelected.call(this);if(idx==-1){return null;}return this.grid.getItem(idx);},getNextSelected:function(_4d2){var _4d3=this.grid.getItemIndex(_4d2);var idx=dojox.grid.Selection.prototype.getNextSelected.call(this,_4d3);if(idx==-1){return null;}return this.grid.getItem(idx);},getSelected:function(){var _4d4=[];for(var i=0,l=this.selected.length;i<l;i++){if(this.selected[i]){_4d4.push(this.grid.getItem(i));}}return _4d4;},addToSelection:function(_4d5){if(this.mode=="none"){return;}var idx=null;if(typeof _4d5=="number"||typeof _4d5=="string"){idx=_4d5;}else{idx=this.grid.getItemIndex(_4d5);}dojox.grid.Selection.prototype.addToSelection.call(this,idx);},deselect:function(_4d6){if(this.mode=="none"){return;}var idx=null;if(typeof _4d6=="number"||typeof _4d6=="string"){idx=_4d6;}else{idx=this.grid.getItemIndex(_4d6);}dojox.grid.Selection.prototype.deselect.call(this,idx);},deselectAll:function(_4d7){var idx=null;if(_4d7||typeof _4d7=="number"){if(typeof _4d7=="number"||typeof _4d7=="string"){idx=_4d7;}else{idx=this.grid.getItemIndex(_4d7);}dojox.grid.Selection.prototype.deselectAll.call(this,idx);}else{this.inherited(arguments);}}});}if(!dojo._hasResource["dojox.grid.DataGrid"]){dojo._hasResource["dojox.grid.DataGrid"]=true;dojo.provide("dojox.grid.DataGrid");dojo.declare("dojox.grid.DataGrid",dojox.grid._Grid,{store:null,query:null,queryOptions:null,fetchText:"...",sortFields:null,updateDelay:1,items:null,_store_connects:null,_by_idty:null,_by_idx:null,_cache:null,_pages:null,_pending_requests:null,_bop:-1,_eop:-1,_requests:0,rowCount:0,_isLoaded:false,_isLoading:false,postCreate:function(){this._pages=[];this._store_connects=[];this._by_idty={};this._by_idx=[];this._cache=[];this._pending_requests={};this._setStore(this.store);this.inherited(arguments);},createSelection:function(){this.selection=new dojox.grid.DataSelection(this);},get:function(_4d8,_4d9){if(_4d9&&this.field=="_item"&&!this.fields){return _4d9;}else{if(_4d9&&this.fields){var ret=[];var s=this.grid.store;dojo.forEach(this.fields,function(f){ret=ret.concat(s.getValues(_4d9,f));});return ret;}else{if(!_4d9&&typeof _4d8==="string"){return this.inherited(arguments);}}}return (!_4d9?this.defaultValue:(!this.field?this.value:(this.field=="_item"?_4d9:this.grid.store.getValue(_4d9,this.field))));},_checkUpdateStatus:function(){if(this.updateDelay>0){var _4da=false;if(this._endUpdateDelay){clearTimeout(this._endUpdateDelay);delete this._endUpdateDelay;_4da=true;}if(!this.updating){this.beginUpdate();_4da=true;}if(_4da){var _4db=this;this._endUpdateDelay=setTimeout(function(){delete _4db._endUpdateDelay;_4db.endUpdate();},this.updateDelay);}}},_onSet:function(item,_4dc,_4dd,_4de){this._checkUpdateStatus();var idx=this.getItemIndex(item);if(idx>-1){this.updateRow(idx);}},_createItem:function(item,_4df){var idty=this._hasIdentity?this.store.getIdentity(item):dojo.toJson(this.query)+":idx:"+_4df+":sort:"+dojo.toJson(this.getSortProps());var o=this._by_idty[idty]={idty:idty,item:item};return o;},_addItem:function(item,_4e0,_4e1){this._by_idx[_4e0]=this._createItem(item,_4e0);if(!_4e1){this.updateRow(_4e0);}},_onNew:function(item,_4e2){this._checkUpdateStatus();var _4e3=this.get("rowCount");this._addingItem=true;this.updateRowCount(_4e3+1);this._addingItem=false;this._addItem(item,_4e3);this.showMessage();},_onDelete:function(item){this._checkUpdateStatus();var idx=this._getItemIndex(item,true);if(idx>=0){this._pages=[];this._bop=-1;this._eop=-1;var o=this._by_idx[idx];this._by_idx.splice(idx,1);delete this._by_idty[o.idty];this.updateRowCount(this.get("rowCount")-1);if(this.get("rowCount")===0){this.showMessage(this.noDataMessage);}}},_onRevert:function(){this._refresh();},setStore:function(_4e4,_4e5,_4e6){this._setQuery(_4e5,_4e6);this._setStore(_4e4);this._refresh(true);},setQuery:function(_4e7,_4e8){this._setQuery(_4e7,_4e8);this._refresh(true);},setItems:function(_4e9){this.items=_4e9;this._setStore(this.store);this._refresh(true);},_setQuery:function(_4ea,_4eb){this.query=_4ea;this.queryOptions=_4eb||this.queryOptions;},_setStore:function(_4ec){if(this.store&&this._store_connects){dojo.forEach(this._store_connects,this.disconnect,this);}this.store=_4ec;if(this.store){var f=this.store.getFeatures();var h=[];this._canEdit=!!f["dojo.data.api.Write"]&&!!f["dojo.data.api.Identity"];this._hasIdentity=!!f["dojo.data.api.Identity"];if(!!f["dojo.data.api.Notification"]&&!this.items){h.push(this.connect(this.store,"onSet","_onSet"));h.push(this.connect(this.store,"onNew","_onNew"));h.push(this.connect(this.store,"onDelete","_onDelete"));}if(this._canEdit){h.push(this.connect(this.store,"revert","_onRevert"));}this._store_connects=h;}},_onFetchBegin:function(size,req){if(!this.scroller){return;}if(this.rowCount!=size){if(req.isRender){this.scroller.init(size,this.keepRows,this.rowsPerPage);this.rowCount=size;this._setAutoHeightAttr(this.autoHeight,true);this._skipRowRenormalize=true;this.prerender();this._skipRowRenormalize=false;}else{this.updateRowCount(size);}}if(!size){this.views.render();this._resize();this.showMessage(this.noDataMessage);this.focus.initFocusView();}else{this.showMessage();}},_onFetchComplete:function(_4ed,req){if(!this.scroller){return;}if(_4ed&&_4ed.length>0){dojo.forEach(_4ed,function(item,idx){this._addItem(item,req.start+idx,true);},this);this.updateRows(req.start,_4ed.length);if(req.isRender){this.setScrollTop(0);this.postrender();}else{if(this._lastScrollTop){this.setScrollTop(this._lastScrollTop);}}}delete this._lastScrollTop;if(!this._isLoaded){this._isLoading=false;this._isLoaded=true;}this._pending_requests[req.start]=false;},_onFetchError:function(err,req){delete this._lastScrollTop;if(!this._isLoaded){this._isLoading=false;this._isLoaded=true;this.showMessage(this.errorMessage);}this._pending_requests[req.start]=false;this.onFetchError(err,req);},onFetchError:function(err,req){},_fetch:function(_4ee,_4ef){_4ee=_4ee||0;if(this.store&&!this._pending_requests[_4ee]){if(!this._isLoaded&&!this._isLoading){this._isLoading=true;this.showMessage(this.loadingMessage);}this._pending_requests[_4ee]=true;try{if(this.items){var _4f0=this.items;var _4f1=this.store;this.rowsPerPage=_4f0.length;var req={start:_4ee,count:this.rowsPerPage,isRender:_4ef};this._onFetchBegin(_4f0.length,req);var _4f2=0;dojo.forEach(_4f0,function(i){if(!_4f1.isItemLoaded(i)){_4f2++;}});if(_4f2===0){this._onFetchComplete(_4f0,req);}else{var _4f3=function(item){_4f2--;if(_4f2===0){this._onFetchComplete(_4f0,req);}};dojo.forEach(_4f0,function(i){if(!_4f1.isItemLoaded(i)){_4f1.loadItem({item:i,onItem:_4f3,scope:this});}},this);}}else{this.store.fetch({start:_4ee,count:this.rowsPerPage,query:this.query,sort:this.getSortProps(),queryOptions:this.queryOptions,isRender:_4ef,onBegin:dojo.hitch(this,"_onFetchBegin"),onComplete:dojo.hitch(this,"_onFetchComplete"),onError:dojo.hitch(this,"_onFetchError")});}}catch(e){this._onFetchError(e,{start:_4ee,count:this.rowsPerPage});}}},_clearData:function(){this.updateRowCount(0);this._by_idty={};this._by_idx=[];this._pages=[];this._bop=this._eop=-1;this._isLoaded=false;this._isLoading=false;},getItem:function(idx){var data=this._by_idx[idx];if(!data||(data&&!data.item)){this._preparePage(idx);return null;}return data.item;},getItemIndex:function(item){return this._getItemIndex(item,false);},_getItemIndex:function(item,_4f4){if(!_4f4&&!this.store.isItem(item)){return -1;}var idty=this._hasIdentity?this.store.getIdentity(item):null;for(var i=0,l=this._by_idx.length;i<l;i++){var d=this._by_idx[i];if(d&&((idty&&d.idty==idty)||(d.item===item))){return i;}}return -1;},filter:function(_4f5,_4f6){this.query=_4f5;if(_4f6){this._clearData();}this._fetch();},_getItemAttr:function(idx,attr){var item=this.getItem(idx);return (!item?this.fetchText:this.store.getValue(item,attr));},_render:function(){if(this.domNode.parentNode){this.scroller.init(this.get("rowCount"),this.keepRows,this.rowsPerPage);this.prerender();this._fetch(0,true);}},_requestsPending:function(_4f7){return this._pending_requests[_4f7];},_rowToPage:function(_4f8){return (this.rowsPerPage?Math.floor(_4f8/this.rowsPerPage):_4f8);},_pageToRow:function(_4f9){return (this.rowsPerPage?this.rowsPerPage*_4f9:_4f9);},_preparePage:function(_4fa){if((_4fa<this._bop||_4fa>=this._eop)&&!this._addingItem){var _4fb=this._rowToPage(_4fa);this._needPage(_4fb);this._bop=_4fb*this.rowsPerPage;this._eop=this._bop+(this.rowsPerPage||this.get("rowCount"));}},_needPage:function(_4fc){if(!this._pages[_4fc]){this._pages[_4fc]=true;this._requestPage(_4fc);}},_requestPage:function(_4fd){var row=this._pageToRow(_4fd);var _4fe=Math.min(this.rowsPerPage,this.get("rowCount")-row);if(_4fe>0){this._requests++;if(!this._requestsPending(row)){setTimeout(dojo.hitch(this,"_fetch",row,false),1);}}},getCellName:function(_4ff){return _4ff.field;},_refresh:function(_500){this._clearData();this._fetch(0,_500);},sort:function(){this.edit.apply();this._lastScrollTop=this.scrollTop;this._refresh();},canSort:function(){return (!this._isLoading);},getSortProps:function(){var c=this.getCell(this.getSortIndex());if(!c){if(this.sortFields){return this.sortFields;}return null;}else{var desc=c["sortDesc"];var si=!(this.sortInfo>0);if(typeof desc=="undefined"){desc=si;}else{desc=si?!desc:desc;}return [{attribute:c.field,descending:desc}];}},styleRowState:function(_501){if(this.store&&this.store.getState){var _502=this.store.getState(_501.index),c="";for(var i=0,ss=["inflight","error","inserting"],s;s=ss[i];i++){if(_502[s]){c=" dojoxGridRow-"+s;break;}}_501.customClasses+=c;}},onStyleRow:function(_503){this.styleRowState(_503);this.inherited(arguments);},canEdit:function(_504,_505){return this._canEdit;},_copyAttr:function(idx,attr){var row={};var _506={};var src=this.getItem(idx);return this.store.getValue(src,attr);},doStartEdit:function(_507,_508){if(!this._cache[_508]){this._cache[_508]=this._copyAttr(_508,_507.field);}this.onStartEdit(_507,_508);},doApplyCellEdit:function(_509,_50a,_50b){this.store.fetchItemByIdentity({identity:this._by_idx[_50a].idty,onItem:dojo.hitch(this,function(item){var _50c=this.store.getValue(item,_50b);if(typeof _50c=="number"){_509=isNaN(_509)?_509:parseFloat(_509);}else{if(typeof _50c=="boolean"){_509=_509=="true"?true:_509=="false"?false:_509;}else{if(_50c instanceof Date){var _50d=new Date(_509);_509=isNaN(_50d.getTime())?_509:_50d;}}}this.store.setValue(item,_50b,_509);this.onApplyCellEdit(_509,_50a,_50b);})});},doCancelEdit:function(_50e){var _50f=this._cache[_50e];if(_50f){this.updateRow(_50e);delete this._cache[_50e];}this.onCancelEdit.apply(this,arguments);},doApplyEdit:function(_510,_511){var _512=this._cache[_510];this.onApplyEdit(_510);},removeSelectedRows:function(){if(this._canEdit){this.edit.apply();var fx=dojo.hitch(this,function(_513){if(_513.length){dojo.forEach(_513,this.store.deleteItem,this.store);this.selection.clear();}});if(this.allItemsSelected){this.store.fetch({query:this.query,queryOptions:this.queryOptions,onComplete:fx});}else{fx(this.selection.getSelected());}}}});dojox.grid.DataGrid.cell_markupFactory=function(_514,node,_515){var _516=dojo.trim(dojo.attr(node,"field")||"");if(_516){_515.field=_516;}_515.field=_515.field||_515.name;var _517=dojo.trim(dojo.attr(node,"fields")||"");if(_517){_515.fields=_517.split(",");}if(_514){_514(node,_515);}};dojox.grid.DataGrid.markupFactory=function(_518,node,ctor,_519){return dojox.grid._Grid.markupFactory(_518,node,ctor,dojo.partial(dojox.grid.DataGrid.cell_markupFactory,_519));};}dojo.i18n._preloadLocalizations("dojox.grid.nls.DataGrid",["ROOT","ar","ca","cs","da","de","de-de","el","en","en-gb","en-us","es","es-es","fi","fi-fi","fr","fr-fr","he","he-il","hu","it","it-it","ja","ja-jp","ko","ko-kr","nb","nl","nl-nl","pl","pt","pt-br","pt-pt","ru","sk","sl","sv","th","tr","xx","zh","zh-cn","zh-tw"]);
diff --git a/js/dojo-1.6/dojox/grid/DataGrid.js.uncompressed.js b/js/dojo-1.6/dojox/grid/DataGrid.js.uncompressed.js
new file mode 100644
index 0000000..c21a4b1
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/DataGrid.js.uncompressed.js
@@ -0,0 +1,17283 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+/*
+ This is an optimized version of Dojo, built for deployment and not for
+ development. To get sources and documentation, please visit:
+
+ http://dojotoolkit.org
+*/
+
+if(!dojo._hasResource["dojo.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.window"] = true;
+dojo.provide("dojo.window");
+
+
+dojo.getObject("window", true, dojo);
+
+dojo.window.getBox = function(){
+ // summary:
+ // Returns the dimensions and scroll position of the viewable area of a browser window
+
+ var scrollRoot = (dojo.doc.compatMode == 'BackCompat') ? dojo.body() : dojo.doc.documentElement;
+
+ // get scroll position
+ var scroll = dojo._docScroll(); // scrollRoot.scrollTop/Left should work
+ return { w: scrollRoot.clientWidth, h: scrollRoot.clientHeight, l: scroll.x, t: scroll.y };
+};
+
+dojo.window.get = function(doc){
+ // summary:
+ // Get window object associated with document doc
+
+ // In some IE versions (at least 6.0), document.parentWindow does not return a
+ // reference to the real window object (maybe a copy), so we must fix it as well
+ // We use IE specific execScript to attach the real window reference to
+ // document._parentWindow for later use
+ if(dojo.isIE && window !== document.parentWindow){
+ /*
+ In IE 6, only the variable "window" can be used to connect events (others
+ may be only copies).
+ */
+ doc.parentWindow.execScript("document._parentWindow = window;", "Javascript");
+ //to prevent memory leak, unset it after use
+ //another possibility is to add an onUnload handler which seems overkill to me (liucougar)
+ var win = doc._parentWindow;
+ doc._parentWindow = null;
+ return win; // Window
+ }
+
+ return doc.parentWindow || doc.defaultView; // Window
+};
+
+dojo.window.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
+ // summary:
+ // Scroll the passed node into view, if it is not already.
+
+ // don't rely on node.scrollIntoView working just because the function is there
+
+ try{ // catch unexpected/unrecreatable errors (#7808) since we can recover using a semi-acceptable native method
+ node = dojo.byId(node);
+ var doc = node.ownerDocument || dojo.doc,
+ body = doc.body || dojo.body(),
+ html = doc.documentElement || body.parentNode,
+ isIE = dojo.isIE, isWK = dojo.isWebKit;
+ // if an untested browser, then use the native method
+ if((!(dojo.isMoz || isIE || isWK || dojo.isOpera) || node == body || node == html) && (typeof node.scrollIntoView != "undefined")){
+ node.scrollIntoView(false); // short-circuit to native if possible
+ return;
+ }
+ var backCompat = doc.compatMode == 'BackCompat',
+ clientAreaRoot = backCompat? body : html,
+ scrollRoot = isWK ? body : clientAreaRoot,
+ rootWidth = clientAreaRoot.clientWidth,
+ rootHeight = clientAreaRoot.clientHeight,
+ rtl = !dojo._isBodyLtr(),
+ nodePos = pos || dojo.position(node),
+ el = node.parentNode,
+ isFixed = function(el){
+ return ((isIE <= 6 || (isIE && backCompat))? false : (dojo.style(el, 'position').toLowerCase() == "fixed"));
+ };
+ if(isFixed(node)){ return; } // nothing to do
+
+ while(el){
+ if(el == body){ el = scrollRoot; }
+ var elPos = dojo.position(el),
+ fixedPos = isFixed(el);
+
+ if(el == scrollRoot){
+ elPos.w = rootWidth; elPos.h = rootHeight;
+ if(scrollRoot == html && isIE && rtl){ elPos.x += scrollRoot.offsetWidth-elPos.w; } // IE workaround where scrollbar causes negative x
+ if(elPos.x < 0 || !isIE){ elPos.x = 0; } // IE can have values > 0
+ if(elPos.y < 0 || !isIE){ elPos.y = 0; }
+ }else{
+ var pb = dojo._getPadBorderExtents(el);
+ elPos.w -= pb.w; elPos.h -= pb.h; elPos.x += pb.l; elPos.y += pb.t;
+ }
+
+ if(el != scrollRoot){ // body, html sizes already have the scrollbar removed
+ var clientSize = el.clientWidth,
+ scrollBarSize = elPos.w - clientSize;
+ if(clientSize > 0 && scrollBarSize > 0){
+ elPos.w = clientSize;
+ if(isIE && rtl){ elPos.x += scrollBarSize; }
+ }
+ clientSize = el.clientHeight;
+ scrollBarSize = elPos.h - clientSize;
+ if(clientSize > 0 && scrollBarSize > 0){
+ elPos.h = clientSize;
+ }
+ }
+ if(fixedPos){ // bounded by viewport, not parents
+ if(elPos.y < 0){
+ elPos.h += elPos.y; elPos.y = 0;
+ }
+ if(elPos.x < 0){
+ elPos.w += elPos.x; elPos.x = 0;
+ }
+ if(elPos.y + elPos.h > rootHeight){
+ elPos.h = rootHeight - elPos.y;
+ }
+ if(elPos.x + elPos.w > rootWidth){
+ elPos.w = rootWidth - elPos.x;
+ }
+ }
+ // calculate overflow in all 4 directions
+ var l = nodePos.x - elPos.x, // beyond left: < 0
+ t = nodePos.y - Math.max(elPos.y, 0), // beyond top: < 0
+ r = l + nodePos.w - elPos.w, // beyond right: > 0
+ bot = t + nodePos.h - elPos.h; // beyond bottom: > 0
+ if(r * l > 0){
+ var s = Math[l < 0? "max" : "min"](l, r);
+ nodePos.x += el.scrollLeft;
+ el.scrollLeft += (isIE >= 8 && !backCompat && rtl)? -s : s;
+ nodePos.x -= el.scrollLeft;
+ }
+ if(bot * t > 0){
+ nodePos.y += el.scrollTop;
+ el.scrollTop += Math[t < 0? "max" : "min"](t, bot);
+ nodePos.y -= el.scrollTop;
+ }
+ el = (el != scrollRoot) && !fixedPos && el.parentNode;
+ }
+ }catch(error){
+ console.error('scrollIntoView: ' + error);
+ node.scrollIntoView(false);
+ }
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.manager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.manager"] = true;
+dojo.provide("dijit._base.manager");
+
+
+
+dojo.declare("dijit.WidgetSet", null, {
+ // summary:
+ // A set of widgets indexed by id. A default instance of this class is
+ // available as `dijit.registry`
+ //
+ // example:
+ // Create a small list of widgets:
+ // | var ws = new dijit.WidgetSet();
+ // | ws.add(dijit.byId("one"));
+ // | ws.add(dijit.byId("two"));
+ // | // destroy both:
+ // | ws.forEach(function(w){ w.destroy(); });
+ //
+ // example:
+ // Using dijit.registry:
+ // | dijit.registry.forEach(function(w){ /* do something */ });
+
+ constructor: function(){
+ this._hash = {};
+ this.length = 0;
+ },
+
+ add: function(/*dijit._Widget*/ widget){
+ // summary:
+ // Add a widget to this list. If a duplicate ID is detected, a error is thrown.
+ //
+ // widget: dijit._Widget
+ // Any dijit._Widget subclass.
+ if(this._hash[widget.id]){
+ throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
+ }
+ this._hash[widget.id] = widget;
+ this.length++;
+ },
+
+ remove: function(/*String*/ id){
+ // summary:
+ // Remove a widget from this WidgetSet. Does not destroy the widget; simply
+ // removes the reference.
+ if(this._hash[id]){
+ delete this._hash[id];
+ this.length--;
+ }
+ },
+
+ forEach: function(/*Function*/ func, /* Object? */thisObj){
+ // summary:
+ // Call specified function for each widget in this set.
+ //
+ // func:
+ // A callback function to run for each item. Is passed the widget, the index
+ // in the iteration, and the full hash, similar to `dojo.forEach`.
+ //
+ // thisObj:
+ // An optional scope parameter
+ //
+ // example:
+ // Using the default `dijit.registry` instance:
+ // | dijit.registry.forEach(function(widget){
+ // | console.log(widget.declaredClass);
+ // | });
+ //
+ // returns:
+ // Returns self, in order to allow for further chaining.
+
+ thisObj = thisObj || dojo.global;
+ var i = 0, id;
+ for(id in this._hash){
+ func.call(thisObj, this._hash[id], i++, this._hash);
+ }
+ return this; // dijit.WidgetSet
+ },
+
+ filter: function(/*Function*/ filter, /* Object? */thisObj){
+ // summary:
+ // Filter down this WidgetSet to a smaller new WidgetSet
+ // Works the same as `dojo.filter` and `dojo.NodeList.filter`
+ //
+ // filter:
+ // Callback function to test truthiness. Is passed the widget
+ // reference and the pseudo-index in the object.
+ //
+ // thisObj: Object?
+ // Option scope to use for the filter function.
+ //
+ // example:
+ // Arbitrary: select the odd widgets in this list
+ // | dijit.registry.filter(function(w, i){
+ // | return i % 2 == 0;
+ // | }).forEach(function(w){ /* odd ones */ });
+
+ thisObj = thisObj || dojo.global;
+ var res = new dijit.WidgetSet(), i = 0, id;
+ for(id in this._hash){
+ var w = this._hash[id];
+ if(filter.call(thisObj, w, i++, this._hash)){
+ res.add(w);
+ }
+ }
+ return res; // dijit.WidgetSet
+ },
+
+ byId: function(/*String*/ id){
+ // summary:
+ // Find a widget in this list by it's id.
+ // example:
+ // Test if an id is in a particular WidgetSet
+ // | var ws = new dijit.WidgetSet();
+ // | ws.add(dijit.byId("bar"));
+ // | var t = ws.byId("bar") // returns a widget
+ // | var x = ws.byId("foo"); // returns undefined
+
+ return this._hash[id]; // dijit._Widget
+ },
+
+ byClass: function(/*String*/ cls){
+ // summary:
+ // Reduce this widgetset to a new WidgetSet of a particular `declaredClass`
+ //
+ // cls: String
+ // The Class to scan for. Full dot-notated string.
+ //
+ // example:
+ // Find all `dijit.TitlePane`s in a page:
+ // | dijit.registry.byClass("dijit.TitlePane").forEach(function(tp){ tp.close(); });
+
+ var res = new dijit.WidgetSet(), id, widget;
+ for(id in this._hash){
+ widget = this._hash[id];
+ if(widget.declaredClass == cls){
+ res.add(widget);
+ }
+ }
+ return res; // dijit.WidgetSet
+},
+
+ toArray: function(){
+ // summary:
+ // Convert this WidgetSet into a true Array
+ //
+ // example:
+ // Work with the widget .domNodes in a real Array
+ // | dojo.map(dijit.registry.toArray(), function(w){ return w.domNode; });
+
+ var ar = [];
+ for(var id in this._hash){
+ ar.push(this._hash[id]);
+ }
+ return ar; // dijit._Widget[]
+},
+
+ map: function(/* Function */func, /* Object? */thisObj){
+ // summary:
+ // Create a new Array from this WidgetSet, following the same rules as `dojo.map`
+ // example:
+ // | var nodes = dijit.registry.map(function(w){ return w.domNode; });
+ //
+ // returns:
+ // A new array of the returned values.
+ return dojo.map(this.toArray(), func, thisObj); // Array
+ },
+
+ every: function(func, thisObj){
+ // summary:
+ // A synthetic clone of `dojo.every` acting explicitly on this WidgetSet
+ //
+ // func: Function
+ // A callback function run for every widget in this list. Exits loop
+ // when the first false return is encountered.
+ //
+ // thisObj: Object?
+ // Optional scope parameter to use for the callback
+
+ thisObj = thisObj || dojo.global;
+ var x = 0, i;
+ for(i in this._hash){
+ if(!func.call(thisObj, this._hash[i], x++, this._hash)){
+ return false; // Boolean
+ }
+ }
+ return true; // Boolean
+ },
+
+ some: function(func, thisObj){
+ // summary:
+ // A synthetic clone of `dojo.some` acting explictly on this WidgetSet
+ //
+ // func: Function
+ // A callback function run for every widget in this list. Exits loop
+ // when the first true return is encountered.
+ //
+ // thisObj: Object?
+ // Optional scope parameter to use for the callback
+
+ thisObj = thisObj || dojo.global;
+ var x = 0, i;
+ for(i in this._hash){
+ if(func.call(thisObj, this._hash[i], x++, this._hash)){
+ return true; // Boolean
+ }
+ }
+ return false; // Boolean
+ }
+
+});
+
+(function(){
+
+ /*=====
+ dijit.registry = {
+ // summary:
+ // A list of widgets on a page.
+ // description:
+ // Is an instance of `dijit.WidgetSet`
+ };
+ =====*/
+ dijit.registry = new dijit.WidgetSet();
+
+ var hash = dijit.registry._hash,
+ attr = dojo.attr,
+ hasAttr = dojo.hasAttr,
+ style = dojo.style;
+
+ dijit.byId = function(/*String|dijit._Widget*/ id){
+ // summary:
+ // Returns a widget by it's id, or if passed a widget, no-op (like dojo.byId())
+ return typeof id == "string" ? hash[id] : id; // dijit._Widget
+ };
+
+ var _widgetTypeCtr = {};
+ dijit.getUniqueId = function(/*String*/widgetType){
+ // summary:
+ // Generates a unique id for a given widgetType
+
+ var id;
+ do{
+ id = widgetType + "_" +
+ (widgetType in _widgetTypeCtr ?
+ ++_widgetTypeCtr[widgetType] : _widgetTypeCtr[widgetType] = 0);
+ }while(hash[id]);
+ return dijit._scopeName == "dijit" ? id : dijit._scopeName + "_" + id; // String
+ };
+
+ dijit.findWidgets = function(/*DomNode*/ root){
+ // summary:
+ // Search subtree under root returning widgets found.
+ // Doesn't search for nested widgets (ie, widgets inside other widgets).
+
+ var outAry = [];
+
+ function getChildrenHelper(root){
+ for(var node = root.firstChild; node; node = node.nextSibling){
+ if(node.nodeType == 1){
+ var widgetId = node.getAttribute("widgetId");
+ if(widgetId){
+ var widget = hash[widgetId];
+ if(widget){ // may be null on page w/multiple dojo's loaded
+ outAry.push(widget);
+ }
+ }else{
+ getChildrenHelper(node);
+ }
+ }
+ }
+ }
+
+ getChildrenHelper(root);
+ return outAry;
+ };
+
+ dijit._destroyAll = function(){
+ // summary:
+ // Code to destroy all widgets and do other cleanup on page unload
+
+ // Clean up focus manager lingering references to widgets and nodes
+ dijit._curFocus = null;
+ dijit._prevFocus = null;
+ dijit._activeStack = [];
+
+ // Destroy all the widgets, top down
+ dojo.forEach(dijit.findWidgets(dojo.body()), function(widget){
+ // Avoid double destroy of widgets like Menu that are attached to <body>
+ // even though they are logically children of other widgets.
+ if(!widget._destroyed){
+ if(widget.destroyRecursive){
+ widget.destroyRecursive();
+ }else if(widget.destroy){
+ widget.destroy();
+ }
+ }
+ });
+ };
+
+ if(dojo.isIE){
+ // Only run _destroyAll() for IE because we think it's only necessary in that case,
+ // and because it causes problems on FF. See bug #3531 for details.
+ dojo.addOnWindowUnload(function(){
+ dijit._destroyAll();
+ });
+ }
+
+ dijit.byNode = function(/*DOMNode*/ node){
+ // summary:
+ // Returns the widget corresponding to the given DOMNode
+ return hash[node.getAttribute("widgetId")]; // dijit._Widget
+ };
+
+ dijit.getEnclosingWidget = function(/*DOMNode*/ node){
+ // summary:
+ // Returns the widget whose DOM tree contains the specified DOMNode, or null if
+ // the node is not contained within the DOM tree of any widget
+ while(node){
+ var id = node.getAttribute && node.getAttribute("widgetId");
+ if(id){
+ return hash[id];
+ }
+ node = node.parentNode;
+ }
+ return null;
+ };
+
+ var shown = (dijit._isElementShown = function(/*Element*/ elem){
+ var s = style(elem);
+ return (s.visibility != "hidden")
+ && (s.visibility != "collapsed")
+ && (s.display != "none")
+ && (attr(elem, "type") != "hidden");
+ });
+
+ dijit.hasDefaultTabStop = function(/*Element*/ elem){
+ // summary:
+ // Tests if element is tab-navigable even without an explicit tabIndex setting
+
+ // No explicit tabIndex setting, need to investigate node type
+ switch(elem.nodeName.toLowerCase()){
+ case "a":
+ // An <a> w/out a tabindex is only navigable if it has an href
+ return hasAttr(elem, "href");
+ case "area":
+ case "button":
+ case "input":
+ case "object":
+ case "select":
+ case "textarea":
+ // These are navigable by default
+ return true;
+ case "iframe":
+ // If it's an editor <iframe> then it's tab navigable.
+ var body;
+ try{
+ // non-IE
+ var contentDocument = elem.contentDocument;
+ if("designMode" in contentDocument && contentDocument.designMode == "on"){
+ return true;
+ }
+ body = contentDocument.body;
+ }catch(e1){
+ // contentWindow.document isn't accessible within IE7/8
+ // if the iframe.src points to a foreign url and this
+ // page contains an element, that could get focus
+ try{
+ body = elem.contentWindow.document.body;
+ }catch(e2){
+ return false;
+ }
+ }
+ return body.contentEditable == 'true' || (body.firstChild && body.firstChild.contentEditable == 'true');
+ default:
+ return elem.contentEditable == 'true';
+ }
+ };
+
+ var isTabNavigable = (dijit.isTabNavigable = function(/*Element*/ elem){
+ // summary:
+ // Tests if an element is tab-navigable
+
+ // TODO: convert (and rename method) to return effective tabIndex; will save time in _getTabNavigable()
+ if(attr(elem, "disabled")){
+ return false;
+ }else if(hasAttr(elem, "tabIndex")){
+ // Explicit tab index setting
+ return attr(elem, "tabIndex") >= 0; // boolean
+ }else{
+ // No explicit tabIndex setting, so depends on node type
+ return dijit.hasDefaultTabStop(elem);
+ }
+ });
+
+ dijit._getTabNavigable = function(/*DOMNode*/ root){
+ // summary:
+ // Finds descendants of the specified root node.
+ //
+ // description:
+ // Finds the following descendants of the specified root node:
+ // * the first tab-navigable element in document order
+ // without a tabIndex or with tabIndex="0"
+ // * the last tab-navigable element in document order
+ // without a tabIndex or with tabIndex="0"
+ // * the first element in document order with the lowest
+ // positive tabIndex value
+ // * the last element in document order with the highest
+ // positive tabIndex value
+ var first, last, lowest, lowestTabindex, highest, highestTabindex, radioSelected = {};
+ function radioName(node) {
+ // If this element is part of a radio button group, return the name for that group.
+ return node && node.tagName.toLowerCase() == "input" &&
+ node.type && node.type.toLowerCase() == "radio" &&
+ node.name && node.name.toLowerCase();
+ }
+ var walkTree = function(/*DOMNode*/parent){
+ dojo.query("> *", parent).forEach(function(child){
+ // Skip hidden elements, and also non-HTML elements (those in custom namespaces) in IE,
+ // since show() invokes getAttribute("type"), which crash on VML nodes in IE.
+ if((dojo.isIE && child.scopeName!=="HTML") || !shown(child)){
+ return;
+ }
+
+ if(isTabNavigable(child)){
+ var tabindex = attr(child, "tabIndex");
+ if(!hasAttr(child, "tabIndex") || tabindex == 0){
+ if(!first){ first = child; }
+ last = child;
+ }else if(tabindex > 0){
+ if(!lowest || tabindex < lowestTabindex){
+ lowestTabindex = tabindex;
+ lowest = child;
+ }
+ if(!highest || tabindex >= highestTabindex){
+ highestTabindex = tabindex;
+ highest = child;
+ }
+ }
+ var rn = radioName(child);
+ if(dojo.attr(child, "checked") && rn) {
+ radioSelected[rn] = child;
+ }
+ }
+ if(child.nodeName.toUpperCase() != 'SELECT'){
+ walkTree(child);
+ }
+ });
+ };
+ if(shown(root)){ walkTree(root) }
+ function rs(node) {
+ // substitute checked radio button for unchecked one, if there is a checked one with the same name.
+ return radioSelected[radioName(node)] || node;
+ }
+ return { first: rs(first), last: rs(last), lowest: rs(lowest), highest: rs(highest) };
+ }
+ dijit.getFirstInTabbingOrder = function(/*String|DOMNode*/ root){
+ // summary:
+ // Finds the descendant of the specified root node
+ // that is first in the tabbing order
+ var elems = dijit._getTabNavigable(dojo.byId(root));
+ return elems.lowest ? elems.lowest : elems.first; // DomNode
+ };
+
+ dijit.getLastInTabbingOrder = function(/*String|DOMNode*/ root){
+ // summary:
+ // Finds the descendant of the specified root node
+ // that is last in the tabbing order
+ var elems = dijit._getTabNavigable(dojo.byId(root));
+ return elems.last ? elems.last : elems.highest; // DomNode
+ };
+
+ /*=====
+ dojo.mixin(dijit, {
+ // defaultDuration: Integer
+ // The default animation speed (in ms) to use for all Dijit
+ // transitional animations, unless otherwise specified
+ // on a per-instance basis. Defaults to 200, overrided by
+ // `djConfig.defaultDuration`
+ defaultDuration: 200
+ });
+ =====*/
+
+ dijit.defaultDuration = dojo.config["defaultDuration"] || 200;
+
+})();
+
+}
+
+if(!dojo._hasResource["dijit._base.focus"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.focus"] = true;
+dojo.provide("dijit._base.focus");
+
+
+
+
+
+// summary:
+// These functions are used to query or set the focus and selection.
+//
+// Also, they trace when widgets become activated/deactivated,
+// so that the widget can fire _onFocus/_onBlur events.
+// "Active" here means something similar to "focused", but
+// "focus" isn't quite the right word because we keep track of
+// a whole stack of "active" widgets. Example: ComboButton --> Menu -->
+// MenuItem. The onBlur event for ComboButton doesn't fire due to focusing
+// on the Menu or a MenuItem, since they are considered part of the
+// ComboButton widget. It only happens when focus is shifted
+// somewhere completely different.
+
+dojo.mixin(dijit, {
+ // _curFocus: DomNode
+ // Currently focused item on screen
+ _curFocus: null,
+
+ // _prevFocus: DomNode
+ // Previously focused item on screen
+ _prevFocus: null,
+
+ isCollapsed: function(){
+ // summary:
+ // Returns true if there is no text selected
+ return dijit.getBookmark().isCollapsed;
+ },
+
+ getBookmark: function(){
+ // summary:
+ // Retrieves a bookmark that can be used with moveToBookmark to return to the same range
+ var bm, rg, tg, sel = dojo.doc.selection, cf = dijit._curFocus;
+
+ if(dojo.global.getSelection){
+ //W3C Range API for selections.
+ sel = dojo.global.getSelection();
+ if(sel){
+ if(sel.isCollapsed){
+ tg = cf? cf.tagName : "";
+ if(tg){
+ //Create a fake rangelike item to restore selections.
+ tg = tg.toLowerCase();
+ if(tg == "textarea" ||
+ (tg == "input" && (!cf.type || cf.type.toLowerCase() == "text"))){
+ sel = {
+ start: cf.selectionStart,
+ end: cf.selectionEnd,
+ node: cf,
+ pRange: true
+ };
+ return {isCollapsed: (sel.end <= sel.start), mark: sel}; //Object.
+ }
+ }
+ bm = {isCollapsed:true};
+ }else{
+ rg = sel.getRangeAt(0);
+ bm = {isCollapsed: false, mark: rg.cloneRange()};
+ }
+ }
+ }else if(sel){
+ // If the current focus was a input of some sort and no selection, don't bother saving
+ // a native bookmark. This is because it causes issues with dialog/page selection restore.
+ // So, we need to create psuedo bookmarks to work with.
+ tg = cf ? cf.tagName : "";
+ tg = tg.toLowerCase();
+ if(cf && tg && (tg == "button" || tg == "textarea" || tg == "input")){
+ if(sel.type && sel.type.toLowerCase() == "none"){
+ return {
+ isCollapsed: true,
+ mark: null
+ }
+ }else{
+ rg = sel.createRange();
+ return {
+ isCollapsed: rg.text && rg.text.length?false:true,
+ mark: {
+ range: rg,
+ pRange: true
+ }
+ };
+ }
+ }
+ bm = {};
+
+ //'IE' way for selections.
+ try{
+ // createRange() throws exception when dojo in iframe
+ //and nothing selected, see #9632
+ rg = sel.createRange();
+ bm.isCollapsed = !(sel.type == 'Text' ? rg.htmlText.length : rg.length);
+ }catch(e){
+ bm.isCollapsed = true;
+ return bm;
+ }
+ if(sel.type.toUpperCase() == 'CONTROL'){
+ if(rg.length){
+ bm.mark=[];
+ var i=0,len=rg.length;
+ while(i<len){
+ bm.mark.push(rg.item(i++));
+ }
+ }else{
+ bm.isCollapsed = true;
+ bm.mark = null;
+ }
+ }else{
+ bm.mark = rg.getBookmark();
+ }
+ }else{
+ console.warn("No idea how to store the current selection for this browser!");
+ }
+ return bm; // Object
+ },
+
+ moveToBookmark: function(/*Object*/bookmark){
+ // summary:
+ // Moves current selection to a bookmark
+ // bookmark:
+ // This should be a returned object from dijit.getBookmark()
+
+ var _doc = dojo.doc,
+ mark = bookmark.mark;
+ if(mark){
+ if(dojo.global.getSelection){
+ //W3C Rangi API (FF, WebKit, Opera, etc)
+ var sel = dojo.global.getSelection();
+ if(sel && sel.removeAllRanges){
+ if(mark.pRange){
+ var r = mark;
+ var n = r.node;
+ n.selectionStart = r.start;
+ n.selectionEnd = r.end;
+ }else{
+ sel.removeAllRanges();
+ sel.addRange(mark);
+ }
+ }else{
+ console.warn("No idea how to restore selection for this browser!");
+ }
+ }else if(_doc.selection && mark){
+ //'IE' way.
+ var rg;
+ if(mark.pRange){
+ rg = mark.range;
+ }else if(dojo.isArray(mark)){
+ rg = _doc.body.createControlRange();
+ //rg.addElement does not have call/apply method, so can not call it directly
+ //rg is not available in "range.addElement(item)", so can't use that either
+ dojo.forEach(mark, function(n){
+ rg.addElement(n);
+ });
+ }else{
+ rg = _doc.body.createTextRange();
+ rg.moveToBookmark(mark);
+ }
+ rg.select();
+ }
+ }
+ },
+
+ getFocus: function(/*Widget?*/ menu, /*Window?*/ openedForWindow){
+ // summary:
+ // Called as getFocus(), this returns an Object showing the current focus
+ // and selected text.
+ //
+ // Called as getFocus(widget), where widget is a (widget representing) a button
+ // that was just pressed, it returns where focus was before that button
+ // was pressed. (Pressing the button may have either shifted focus to the button,
+ // or removed focus altogether.) In this case the selected text is not returned,
+ // since it can't be accurately determined.
+ //
+ // menu: dijit._Widget or {domNode: DomNode} structure
+ // The button that was just pressed. If focus has disappeared or moved
+ // to this button, returns the previous focus. In this case the bookmark
+ // information is already lost, and null is returned.
+ //
+ // openedForWindow:
+ // iframe in which menu was opened
+ //
+ // returns:
+ // A handle to restore focus/selection, to be passed to `dijit.focus`
+ var node = !dijit._curFocus || (menu && dojo.isDescendant(dijit._curFocus, menu.domNode)) ? dijit._prevFocus : dijit._curFocus;
+ return {
+ node: node,
+ bookmark: (node == dijit._curFocus) && dojo.withGlobal(openedForWindow || dojo.global, dijit.getBookmark),
+ openedForWindow: openedForWindow
+ }; // Object
+ },
+
+ focus: function(/*Object || DomNode */ handle){
+ // summary:
+ // Sets the focused node and the selection according to argument.
+ // To set focus to an iframe's content, pass in the iframe itself.
+ // handle:
+ // object returned by get(), or a DomNode
+
+ if(!handle){ return; }
+
+ var node = "node" in handle ? handle.node : handle, // because handle is either DomNode or a composite object
+ bookmark = handle.bookmark,
+ openedForWindow = handle.openedForWindow,
+ collapsed = bookmark ? bookmark.isCollapsed : false;
+
+ // Set the focus
+ // Note that for iframe's we need to use the <iframe> to follow the parentNode chain,
+ // but we need to set focus to iframe.contentWindow
+ if(node){
+ var focusNode = (node.tagName.toLowerCase() == "iframe") ? node.contentWindow : node;
+ if(focusNode && focusNode.focus){
+ try{
+ // Gecko throws sometimes if setting focus is impossible,
+ // node not displayed or something like that
+ focusNode.focus();
+ }catch(e){/*quiet*/}
+ }
+ dijit._onFocusNode(node);
+ }
+
+ // set the selection
+ // do not need to restore if current selection is not empty
+ // (use keyboard to select a menu item) or if previous selection was collapsed
+ // as it may cause focus shift (Esp in IE).
+ if(bookmark && dojo.withGlobal(openedForWindow || dojo.global, dijit.isCollapsed) && !collapsed){
+ if(openedForWindow){
+ openedForWindow.focus();
+ }
+ try{
+ dojo.withGlobal(openedForWindow || dojo.global, dijit.moveToBookmark, null, [bookmark]);
+ }catch(e2){
+ /*squelch IE internal error, see http://trac.dojotoolkit.org/ticket/1984 */
+ }
+ }
+ },
+
+ // _activeStack: dijit._Widget[]
+ // List of currently active widgets (focused widget and it's ancestors)
+ _activeStack: [],
+
+ registerIframe: function(/*DomNode*/ iframe){
+ // summary:
+ // Registers listeners on the specified iframe so that any click
+ // or focus event on that iframe (or anything in it) is reported
+ // as a focus/click event on the <iframe> itself.
+ // description:
+ // Currently only used by editor.
+ // returns:
+ // Handle to pass to unregisterIframe()
+ return dijit.registerWin(iframe.contentWindow, iframe);
+ },
+
+ unregisterIframe: function(/*Object*/ handle){
+ // summary:
+ // Unregisters listeners on the specified iframe created by registerIframe.
+ // After calling be sure to delete or null out the handle itself.
+ // handle:
+ // Handle returned by registerIframe()
+
+ dijit.unregisterWin(handle);
+ },
+
+ registerWin: function(/*Window?*/targetWindow, /*DomNode?*/ effectiveNode){
+ // summary:
+ // Registers listeners on the specified window (either the main
+ // window or an iframe's window) to detect when the user has clicked somewhere
+ // or focused somewhere.
+ // description:
+ // Users should call registerIframe() instead of this method.
+ // targetWindow:
+ // If specified this is the window associated with the iframe,
+ // i.e. iframe.contentWindow.
+ // effectiveNode:
+ // If specified, report any focus events inside targetWindow as
+ // an event on effectiveNode, rather than on evt.target.
+ // returns:
+ // Handle to pass to unregisterWin()
+
+ // TODO: make this function private in 2.0; Editor/users should call registerIframe(),
+
+ var mousedownListener = function(evt){
+ dijit._justMouseDowned = true;
+ setTimeout(function(){ dijit._justMouseDowned = false; }, 0);
+
+ // workaround weird IE bug where the click is on an orphaned node
+ // (first time clicking a Select/DropDownButton inside a TooltipDialog)
+ if(dojo.isIE && evt && evt.srcElement && evt.srcElement.parentNode == null){
+ return;
+ }
+
+ dijit._onTouchNode(effectiveNode || evt.target || evt.srcElement, "mouse");
+ };
+ //dojo.connect(targetWindow, "onscroll", ???);
+
+ // Listen for blur and focus events on targetWindow's document.
+ // IIRC, I'm using attachEvent() rather than dojo.connect() because focus/blur events don't bubble
+ // through dojo.connect(), and also maybe to catch the focus events early, before onfocus handlers
+ // fire.
+ // Connect to <html> (rather than document) on IE to avoid memory leaks, but document on other browsers because
+ // (at least for FF) the focus event doesn't fire on <html> or <body>.
+ var doc = dojo.isIE ? targetWindow.document.documentElement : targetWindow.document;
+ if(doc){
+ if(dojo.isIE){
+ targetWindow.document.body.attachEvent('onmousedown', mousedownListener);
+ var activateListener = function(evt){
+ // IE reports that nodes like <body> have gotten focus, even though they have tabIndex=-1,
+ // Should consider those more like a mouse-click than a focus....
+ if(evt.srcElement.tagName.toLowerCase() != "#document" &&
+ dijit.isTabNavigable(evt.srcElement)){
+ dijit._onFocusNode(effectiveNode || evt.srcElement);
+ }else{
+ dijit._onTouchNode(effectiveNode || evt.srcElement);
+ }
+ };
+ doc.attachEvent('onactivate', activateListener);
+ var deactivateListener = function(evt){
+ dijit._onBlurNode(effectiveNode || evt.srcElement);
+ };
+ doc.attachEvent('ondeactivate', deactivateListener);
+
+ return function(){
+ targetWindow.document.detachEvent('onmousedown', mousedownListener);
+ doc.detachEvent('onactivate', activateListener);
+ doc.detachEvent('ondeactivate', deactivateListener);
+ doc = null; // prevent memory leak (apparent circular reference via closure)
+ };
+ }else{
+ doc.body.addEventListener('mousedown', mousedownListener, true);
+ var focusListener = function(evt){
+ dijit._onFocusNode(effectiveNode || evt.target);
+ };
+ doc.addEventListener('focus', focusListener, true);
+ var blurListener = function(evt){
+ dijit._onBlurNode(effectiveNode || evt.target);
+ };
+ doc.addEventListener('blur', blurListener, true);
+
+ return function(){
+ doc.body.removeEventListener('mousedown', mousedownListener, true);
+ doc.removeEventListener('focus', focusListener, true);
+ doc.removeEventListener('blur', blurListener, true);
+ doc = null; // prevent memory leak (apparent circular reference via closure)
+ };
+ }
+ }
+ },
+
+ unregisterWin: function(/*Handle*/ handle){
+ // summary:
+ // Unregisters listeners on the specified window (either the main
+ // window or an iframe's window) according to handle returned from registerWin().
+ // After calling be sure to delete or null out the handle itself.
+
+ // Currently our handle is actually a function
+ handle && handle();
+ },
+
+ _onBlurNode: function(/*DomNode*/ node){
+ // summary:
+ // Called when focus leaves a node.
+ // Usually ignored, _unless_ it *isn't* follwed by touching another node,
+ // which indicates that we tabbed off the last field on the page,
+ // in which case every widget is marked inactive
+ dijit._prevFocus = dijit._curFocus;
+ dijit._curFocus = null;
+
+ if(dijit._justMouseDowned){
+ // the mouse down caused a new widget to be marked as active; this blur event
+ // is coming late, so ignore it.
+ return;
+ }
+
+ // if the blur event isn't followed by a focus event then mark all widgets as inactive.
+ if(dijit._clearActiveWidgetsTimer){
+ clearTimeout(dijit._clearActiveWidgetsTimer);
+ }
+ dijit._clearActiveWidgetsTimer = setTimeout(function(){
+ delete dijit._clearActiveWidgetsTimer;
+ dijit._setStack([]);
+ dijit._prevFocus = null;
+ }, 100);
+ },
+
+ _onTouchNode: function(/*DomNode*/ node, /*String*/ by){
+ // summary:
+ // Callback when node is focused or mouse-downed
+ // node:
+ // The node that was touched.
+ // by:
+ // "mouse" if the focus/touch was caused by a mouse down event
+
+ // ignore the recent blurNode event
+ if(dijit._clearActiveWidgetsTimer){
+ clearTimeout(dijit._clearActiveWidgetsTimer);
+ delete dijit._clearActiveWidgetsTimer;
+ }
+
+ // compute stack of active widgets (ex: ComboButton --> Menu --> MenuItem)
+ var newStack=[];
+ try{
+ while(node){
+ var popupParent = dojo.attr(node, "dijitPopupParent");
+ if(popupParent){
+ node=dijit.byId(popupParent).domNode;
+ }else if(node.tagName && node.tagName.toLowerCase() == "body"){
+ // is this the root of the document or just the root of an iframe?
+ if(node === dojo.body()){
+ // node is the root of the main document
+ break;
+ }
+ // otherwise, find the iframe this node refers to (can't access it via parentNode,
+ // need to do this trick instead). window.frameElement is supported in IE/FF/Webkit
+ node=dojo.window.get(node.ownerDocument).frameElement;
+ }else{
+ // if this node is the root node of a widget, then add widget id to stack,
+ // except ignore clicks on disabled widgets (actually focusing a disabled widget still works,
+ // to support MenuItem)
+ var id = node.getAttribute && node.getAttribute("widgetId"),
+ widget = id && dijit.byId(id);
+ if(widget && !(by == "mouse" && widget.get("disabled"))){
+ newStack.unshift(id);
+ }
+ node=node.parentNode;
+ }
+ }
+ }catch(e){ /* squelch */ }
+
+ dijit._setStack(newStack, by);
+ },
+
+ _onFocusNode: function(/*DomNode*/ node){
+ // summary:
+ // Callback when node is focused
+
+ if(!node){
+ return;
+ }
+
+ if(node.nodeType == 9){
+ // Ignore focus events on the document itself. This is here so that
+ // (for example) clicking the up/down arrows of a spinner
+ // (which don't get focus) won't cause that widget to blur. (FF issue)
+ return;
+ }
+
+ dijit._onTouchNode(node);
+
+ if(node == dijit._curFocus){ return; }
+ if(dijit._curFocus){
+ dijit._prevFocus = dijit._curFocus;
+ }
+ dijit._curFocus = node;
+ dojo.publish("focusNode", [node]);
+ },
+
+ _setStack: function(/*String[]*/ newStack, /*String*/ by){
+ // summary:
+ // The stack of active widgets has changed. Send out appropriate events and records new stack.
+ // newStack:
+ // array of widget id's, starting from the top (outermost) widget
+ // by:
+ // "mouse" if the focus/touch was caused by a mouse down event
+
+ var oldStack = dijit._activeStack;
+ dijit._activeStack = newStack;
+
+ // compare old stack to new stack to see how many elements they have in common
+ for(var nCommon=0; nCommon<Math.min(oldStack.length, newStack.length); nCommon++){
+ if(oldStack[nCommon] != newStack[nCommon]){
+ break;
+ }
+ }
+
+ var widget;
+ // for all elements that have gone out of focus, send blur event
+ for(var i=oldStack.length-1; i>=nCommon; i--){
+ widget = dijit.byId(oldStack[i]);
+ if(widget){
+ widget._focused = false;
+ widget.set("focused", false);
+ widget._hasBeenBlurred = true;
+ if(widget._onBlur){
+ widget._onBlur(by);
+ }
+ dojo.publish("widgetBlur", [widget, by]);
+ }
+ }
+
+ // for all element that have come into focus, send focus event
+ for(i=nCommon; i<newStack.length; i++){
+ widget = dijit.byId(newStack[i]);
+ if(widget){
+ widget._focused = true;
+ widget.set("focused", true);
+ if(widget._onFocus){
+ widget._onFocus(by);
+ }
+ dojo.publish("widgetFocus", [widget, by]);
+ }
+ }
+ }
+});
+
+// register top window and all the iframes it contains
+dojo.addOnLoad(function(){
+ var handle = dijit.registerWin(window);
+ if(dojo.isIE){
+ dojo.addOnWindowUnload(function(){
+ dijit.unregisterWin(handle);
+ handle = null;
+ })
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojo.AdapterRegistry"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.AdapterRegistry"] = true;
+dojo.provide("dojo.AdapterRegistry");
+
+
+
+dojo.AdapterRegistry = function(/*Boolean?*/ returnWrappers){
+ // summary:
+ // A registry to make contextual calling/searching easier.
+ // description:
+ // Objects of this class keep list of arrays in the form [name, check,
+ // wrap, directReturn] that are used to determine what the contextual
+ // result of a set of checked arguments is. All check/wrap functions
+ // in this registry should be of the same arity.
+ // example:
+ // | // create a new registry
+ // | var reg = new dojo.AdapterRegistry();
+ // | reg.register("handleString",
+ // | dojo.isString,
+ // | function(str){
+ // | // do something with the string here
+ // | }
+ // | );
+ // | reg.register("handleArr",
+ // | dojo.isArray,
+ // | function(arr){
+ // | // do something with the array here
+ // | }
+ // | );
+ // |
+ // | // now we can pass reg.match() *either* an array or a string and
+ // | // the value we pass will get handled by the right function
+ // | reg.match("someValue"); // will call the first function
+ // | reg.match(["someValue"]); // will call the second
+
+ this.pairs = [];
+ this.returnWrappers = returnWrappers || false; // Boolean
+};
+
+dojo.extend(dojo.AdapterRegistry, {
+ register: function(/*String*/ name, /*Function*/ check, /*Function*/ wrap, /*Boolean?*/ directReturn, /*Boolean?*/ override){
+ // summary:
+ // register a check function to determine if the wrap function or
+ // object gets selected
+ // name:
+ // a way to identify this matcher.
+ // check:
+ // a function that arguments are passed to from the adapter's
+ // match() function. The check function should return true if the
+ // given arguments are appropriate for the wrap function.
+ // directReturn:
+ // If directReturn is true, the value passed in for wrap will be
+ // returned instead of being called. Alternately, the
+ // AdapterRegistry can be set globally to "return not call" using
+ // the returnWrappers property. Either way, this behavior allows
+ // the registry to act as a "search" function instead of a
+ // function interception library.
+ // override:
+ // If override is given and true, the check function will be given
+ // highest priority. Otherwise, it will be the lowest priority
+ // adapter.
+ this.pairs[((override) ? "unshift" : "push")]([name, check, wrap, directReturn]);
+ },
+
+ match: function(/* ... */){
+ // summary:
+ // Find an adapter for the given arguments. If no suitable adapter
+ // is found, throws an exception. match() accepts any number of
+ // arguments, all of which are passed to all matching functions
+ // from the registered pairs.
+ for(var i = 0; i < this.pairs.length; i++){
+ var pair = this.pairs[i];
+ if(pair[1].apply(this, arguments)){
+ if((pair[3])||(this.returnWrappers)){
+ return pair[2];
+ }else{
+ return pair[2].apply(this, arguments);
+ }
+ }
+ }
+ throw new Error("No match found");
+ },
+
+ unregister: function(name){
+ // summary: Remove a named adapter from the registry
+
+ // FIXME: this is kind of a dumb way to handle this. On a large
+ // registry this will be slow-ish and we can use the name as a lookup
+ // should we choose to trade memory for speed.
+ for(var i = 0; i < this.pairs.length; i++){
+ var pair = this.pairs[i];
+ if(pair[0] == name){
+ this.pairs.splice(i, 1);
+ return true;
+ }
+ }
+ return false;
+ }
+});
+
+}
+
+if(!dojo._hasResource["dijit._base.place"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.place"] = true;
+dojo.provide("dijit._base.place");
+
+
+
+
+
+dijit.getViewport = function(){
+ // summary:
+ // Returns the dimensions and scroll position of the viewable area of a browser window
+
+ return dojo.window.getBox();
+};
+
+/*=====
+dijit.__Position = function(){
+ // x: Integer
+ // horizontal coordinate in pixels, relative to document body
+ // y: Integer
+ // vertical coordinate in pixels, relative to document body
+
+ thix.x = x;
+ this.y = y;
+}
+=====*/
+
+
+dijit.placeOnScreen = function(
+ /* DomNode */ node,
+ /* dijit.__Position */ pos,
+ /* String[] */ corners,
+ /* dijit.__Position? */ padding){
+ // summary:
+ // Positions one of the node's corners at specified position
+ // such that node is fully visible in viewport.
+ // description:
+ // NOTE: node is assumed to be absolutely or relatively positioned.
+ // pos:
+ // Object like {x: 10, y: 20}
+ // corners:
+ // Array of Strings representing order to try corners in, like ["TR", "BL"].
+ // Possible values are:
+ // * "BL" - bottom left
+ // * "BR" - bottom right
+ // * "TL" - top left
+ // * "TR" - top right
+ // padding:
+ // set padding to put some buffer around the element you want to position.
+ // example:
+ // Try to place node's top right corner at (10,20).
+ // If that makes node go (partially) off screen, then try placing
+ // bottom left corner at (10,20).
+ // | placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])
+
+ var choices = dojo.map(corners, function(corner){
+ var c = { corner: corner, pos: {x:pos.x,y:pos.y} };
+ if(padding){
+ c.pos.x += corner.charAt(1) == 'L' ? padding.x : -padding.x;
+ c.pos.y += corner.charAt(0) == 'T' ? padding.y : -padding.y;
+ }
+ return c;
+ });
+
+ return dijit._place(node, choices);
+}
+
+dijit._place = function(/*DomNode*/ node, choices, layoutNode, /*Object*/ aroundNodeCoords){
+ // summary:
+ // Given a list of spots to put node, put it at the first spot where it fits,
+ // of if it doesn't fit anywhere then the place with the least overflow
+ // choices: Array
+ // Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} }
+ // Above example says to put the top-left corner of the node at (10,20)
+ // layoutNode: Function(node, aroundNodeCorner, nodeCorner, size)
+ // for things like tooltip, they are displayed differently (and have different dimensions)
+ // based on their orientation relative to the parent. This adjusts the popup based on orientation.
+ // It also passes in the available size for the popup, which is useful for tooltips to
+ // tell them that their width is limited to a certain amount. layoutNode() may return a value expressing
+ // how much the popup had to be modified to fit into the available space. This is used to determine
+ // what the best placement is.
+ // aroundNodeCoords: Object
+ // Size of aroundNode, ex: {w: 200, h: 50}
+
+ // get {x: 10, y: 10, w: 100, h:100} type obj representing position of
+ // viewport over document
+ var view = dojo.window.getBox();
+
+ // This won't work if the node is inside a <div style="position: relative">,
+ // so reattach it to dojo.doc.body. (Otherwise, the positioning will be wrong
+ // and also it might get cutoff)
+ if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){
+ dojo.body().appendChild(node);
+ }
+
+ var best = null;
+ dojo.some(choices, function(choice){
+ var corner = choice.corner;
+ var pos = choice.pos;
+ var overflow = 0;
+
+ // calculate amount of space available given specified position of node
+ var spaceAvailable = {
+ w: corner.charAt(1) == 'L' ? (view.l + view.w) - pos.x : pos.x - view.l,
+ h: corner.charAt(1) == 'T' ? (view.t + view.h) - pos.y : pos.y - view.t
+ };
+
+ // configure node to be displayed in given position relative to button
+ // (need to do this in order to get an accurate size for the node, because
+ // a tooltip's size changes based on position, due to triangle)
+ if(layoutNode){
+ var res = layoutNode(node, choice.aroundCorner, corner, spaceAvailable, aroundNodeCoords);
+ overflow = typeof res == "undefined" ? 0 : res;
+ }
+
+ // get node's size
+ var style = node.style;
+ var oldDisplay = style.display;
+ var oldVis = style.visibility;
+ style.visibility = "hidden";
+ style.display = "";
+ var mb = dojo.marginBox(node);
+ style.display = oldDisplay;
+ style.visibility = oldVis;
+
+ // coordinates and size of node with specified corner placed at pos,
+ // and clipped by viewport
+ var startX = Math.max(view.l, corner.charAt(1) == 'L' ? pos.x : (pos.x - mb.w)),
+ startY = Math.max(view.t, corner.charAt(0) == 'T' ? pos.y : (pos.y - mb.h)),
+ endX = Math.min(view.l + view.w, corner.charAt(1) == 'L' ? (startX + mb.w) : pos.x),
+ endY = Math.min(view.t + view.h, corner.charAt(0) == 'T' ? (startY + mb.h) : pos.y),
+ width = endX - startX,
+ height = endY - startY;
+
+ overflow += (mb.w - width) + (mb.h - height);
+
+ if(best == null || overflow < best.overflow){
+ best = {
+ corner: corner,
+ aroundCorner: choice.aroundCorner,
+ x: startX,
+ y: startY,
+ w: width,
+ h: height,
+ overflow: overflow,
+ spaceAvailable: spaceAvailable
+ };
+ }
+
+ return !overflow;
+ });
+
+ // In case the best position is not the last one we checked, need to call
+ // layoutNode() again.
+ if(best.overflow && layoutNode){
+ layoutNode(node, best.aroundCorner, best.corner, best.spaceAvailable, aroundNodeCoords);
+ }
+
+ // And then position the node. Do this last, after the layoutNode() above
+ // has sized the node, due to browser quirks when the viewport is scrolled
+ // (specifically that a Tooltip will shrink to fit as though the window was
+ // scrolled to the left).
+ //
+ // In RTL mode, set style.right rather than style.left so in the common case,
+ // window resizes move the popup along with the aroundNode.
+ var l = dojo._isBodyLtr(),
+ s = node.style;
+ s.top = best.y + "px";
+ s[l ? "left" : "right"] = (l ? best.x : view.w - best.x - best.w) + "px";
+
+ return best;
+}
+
+dijit.placeOnScreenAroundNode = function(
+ /* DomNode */ node,
+ /* DomNode */ aroundNode,
+ /* Object */ aroundCorners,
+ /* Function? */ layoutNode){
+
+ // summary:
+ // Position node adjacent or kitty-corner to aroundNode
+ // such that it's fully visible in viewport.
+ //
+ // description:
+ // Place node such that corner of node touches a corner of
+ // aroundNode, and that node is fully visible.
+ //
+ // aroundCorners:
+ // Ordered list of pairs of corners to try matching up.
+ // Each pair of corners is represented as a key/value in the hash,
+ // where the key corresponds to the aroundNode's corner, and
+ // the value corresponds to the node's corner:
+ //
+ // | { aroundNodeCorner1: nodeCorner1, aroundNodeCorner2: nodeCorner2, ...}
+ //
+ // The following strings are used to represent the four corners:
+ // * "BL" - bottom left
+ // * "BR" - bottom right
+ // * "TL" - top left
+ // * "TR" - top right
+ //
+ // layoutNode: Function(node, aroundNodeCorner, nodeCorner)
+ // For things like tooltip, they are displayed differently (and have different dimensions)
+ // based on their orientation relative to the parent. This adjusts the popup based on orientation.
+ //
+ // example:
+ // | dijit.placeOnScreenAroundNode(node, aroundNode, {'BL':'TL', 'TR':'BR'});
+ // This will try to position node such that node's top-left corner is at the same position
+ // as the bottom left corner of the aroundNode (ie, put node below
+ // aroundNode, with left edges aligned). If that fails it will try to put
+ // the bottom-right corner of node where the top right corner of aroundNode is
+ // (ie, put node above aroundNode, with right edges aligned)
+ //
+
+ // get coordinates of aroundNode
+ aroundNode = dojo.byId(aroundNode);
+ var aroundNodePos = dojo.position(aroundNode, true);
+
+ // place the node around the calculated rectangle
+ return dijit._placeOnScreenAroundRect(node,
+ aroundNodePos.x, aroundNodePos.y, aroundNodePos.w, aroundNodePos.h, // rectangle
+ aroundCorners, layoutNode);
+};
+
+/*=====
+dijit.__Rectangle = function(){
+ // x: Integer
+ // horizontal offset in pixels, relative to document body
+ // y: Integer
+ // vertical offset in pixels, relative to document body
+ // width: Integer
+ // width in pixels
+ // height: Integer
+ // height in pixels
+
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+}
+=====*/
+
+
+dijit.placeOnScreenAroundRectangle = function(
+ /* DomNode */ node,
+ /* dijit.__Rectangle */ aroundRect,
+ /* Object */ aroundCorners,
+ /* Function */ layoutNode){
+
+ // summary:
+ // Like dijit.placeOnScreenAroundNode(), except that the "around"
+ // parameter is an arbitrary rectangle on the screen (x, y, width, height)
+ // instead of a dom node.
+
+ return dijit._placeOnScreenAroundRect(node,
+ aroundRect.x, aroundRect.y, aroundRect.width, aroundRect.height, // rectangle
+ aroundCorners, layoutNode);
+};
+
+dijit._placeOnScreenAroundRect = function(
+ /* DomNode */ node,
+ /* Number */ x,
+ /* Number */ y,
+ /* Number */ width,
+ /* Number */ height,
+ /* Object */ aroundCorners,
+ /* Function */ layoutNode){
+
+ // summary:
+ // Like dijit.placeOnScreenAroundNode(), except it accepts coordinates
+ // of a rectangle to place node adjacent to.
+
+ // TODO: combine with placeOnScreenAroundRectangle()
+
+ // Generate list of possible positions for node
+ var choices = [];
+ for(var nodeCorner in aroundCorners){
+ choices.push( {
+ aroundCorner: nodeCorner,
+ corner: aroundCorners[nodeCorner],
+ pos: {
+ x: x + (nodeCorner.charAt(1) == 'L' ? 0 : width),
+ y: y + (nodeCorner.charAt(0) == 'T' ? 0 : height)
+ }
+ });
+ }
+
+ return dijit._place(node, choices, layoutNode, {w: width, h: height});
+};
+
+dijit.placementRegistry= new dojo.AdapterRegistry();
+dijit.placementRegistry.register("node",
+ function(n, x){
+ return typeof x == "object" &&
+ typeof x.offsetWidth != "undefined" && typeof x.offsetHeight != "undefined";
+ },
+ dijit.placeOnScreenAroundNode);
+dijit.placementRegistry.register("rect",
+ function(n, x){
+ return typeof x == "object" &&
+ "x" in x && "y" in x && "width" in x && "height" in x;
+ },
+ dijit.placeOnScreenAroundRectangle);
+
+dijit.placeOnScreenAroundElement = function(
+ /* DomNode */ node,
+ /* Object */ aroundElement,
+ /* Object */ aroundCorners,
+ /* Function */ layoutNode){
+
+ // summary:
+ // Like dijit.placeOnScreenAroundNode(), except it accepts an arbitrary object
+ // for the "around" argument and finds a proper processor to place a node.
+
+ return dijit.placementRegistry.match.apply(dijit.placementRegistry, arguments);
+};
+
+dijit.getPopupAroundAlignment = function(/*Array*/ position, /*Boolean*/ leftToRight){
+ // summary:
+ // Transforms the passed array of preferred positions into a format suitable for passing as the aroundCorners argument to dijit.placeOnScreenAroundElement.
+ //
+ // position: String[]
+ // This variable controls the position of the drop down.
+ // It's an array of strings with the following values:
+ //
+ // * before: places drop down to the left of the target node/widget, or to the right in
+ // the case of RTL scripts like Hebrew and Arabic
+ // * after: places drop down to the right of the target node/widget, or to the left in
+ // the case of RTL scripts like Hebrew and Arabic
+ // * above: drop down goes above target node
+ // * below: drop down goes below target node
+ //
+ // The list is positions is tried, in order, until a position is found where the drop down fits
+ // within the viewport.
+ //
+ // leftToRight: Boolean
+ // Whether the popup will be displaying in leftToRight mode.
+ //
+ var align = {};
+ dojo.forEach(position, function(pos){
+ switch(pos){
+ case "after":
+ align[leftToRight ? "BR" : "BL"] = leftToRight ? "BL" : "BR";
+ break;
+ case "before":
+ align[leftToRight ? "BL" : "BR"] = leftToRight ? "BR" : "BL";
+ break;
+ case "below-alt":
+ leftToRight = !leftToRight;
+ // fall through
+ case "below":
+ // first try to align left borders, next try to align right borders (or reverse for RTL mode)
+ align[leftToRight ? "BL" : "BR"] = leftToRight ? "TL" : "TR";
+ align[leftToRight ? "BR" : "BL"] = leftToRight ? "TR" : "TL";
+ break;
+ case "above-alt":
+ leftToRight = !leftToRight;
+ // fall through
+ case "above":
+ default:
+ // first try to align left borders, next try to align right borders (or reverse for RTL mode)
+ align[leftToRight ? "TL" : "TR"] = leftToRight ? "BL" : "BR";
+ align[leftToRight ? "TR" : "TL"] = leftToRight ? "BR" : "BL";
+ break;
+ }
+ });
+ return align;
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.window"] = true;
+dojo.provide("dijit._base.window");
+
+
+
+
+dijit.getDocumentWindow = function(doc){
+ return dojo.window.get(doc);
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.popup"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.popup"] = true;
+dojo.provide("dijit._base.popup");
+
+
+
+
+
+
+/*=====
+dijit.popup.__OpenArgs = function(){
+ // popup: Widget
+ // widget to display
+ // parent: Widget
+ // the button etc. that is displaying this popup
+ // around: DomNode
+ // DOM node (typically a button); place popup relative to this node. (Specify this *or* "x" and "y" parameters.)
+ // x: Integer
+ // Absolute horizontal position (in pixels) to place node at. (Specify this *or* "around" parameter.)
+ // y: Integer
+ // Absolute vertical position (in pixels) to place node at. (Specify this *or* "around" parameter.)
+ // orient: Object|String
+ // When the around parameter is specified, orient should be an
+ // ordered list of tuples of the form (around-node-corner, popup-node-corner).
+ // dijit.popup.open() tries to position the popup according to each tuple in the list, in order,
+ // until the popup appears fully within the viewport.
+ //
+ // The default value is {BL:'TL', TL:'BL'}, which represents a list of two tuples:
+ // 1. (BL, TL)
+ // 2. (TL, BL)
+ // where BL means "bottom left" and "TL" means "top left".
+ // So by default, it first tries putting the popup below the around node, left-aligning them,
+ // and then tries to put it above the around node, still left-aligning them. Note that the
+ // default is horizontally reversed when in RTL mode.
+ //
+ // When an (x,y) position is specified rather than an around node, orient is either
+ // "R" or "L". R (for right) means that it tries to put the popup to the right of the mouse,
+ // specifically positioning the popup's top-right corner at the mouse position, and if that doesn't
+ // fit in the viewport, then it tries, in order, the bottom-right corner, the top left corner,
+ // and the top-right corner.
+ // onCancel: Function
+ // callback when user has canceled the popup by
+ // 1. hitting ESC or
+ // 2. by using the popup widget's proprietary cancel mechanism (like a cancel button in a dialog);
+ // i.e. whenever popupWidget.onCancel() is called, args.onCancel is called
+ // onClose: Function
+ // callback whenever this popup is closed
+ // onExecute: Function
+ // callback when user "executed" on the popup/sub-popup by selecting a menu choice, etc. (top menu only)
+ // padding: dijit.__Position
+ // adding a buffer around the opening position. This is only useful when around is not set.
+ this.popup = popup;
+ this.parent = parent;
+ this.around = around;
+ this.x = x;
+ this.y = y;
+ this.orient = orient;
+ this.onCancel = onCancel;
+ this.onClose = onClose;
+ this.onExecute = onExecute;
+ this.padding = padding;
+}
+=====*/
+
+dijit.popup = {
+ // summary:
+ // This singleton is used to show/hide widgets as popups.
+
+ // _stack: dijit._Widget[]
+ // Stack of currently popped up widgets.
+ // (someone opened _stack[0], and then it opened _stack[1], etc.)
+ _stack: [],
+
+ // _beginZIndex: Number
+ // Z-index of the first popup. (If first popup opens other
+ // popups they get a higher z-index.)
+ _beginZIndex: 1000,
+
+ _idGen: 1,
+
+ _createWrapper: function(/*Widget || DomNode*/ widget){
+ // summary:
+ // Initialization for widgets that will be used as popups.
+ // Puts widget inside a wrapper DIV (if not already in one),
+ // and returns pointer to that wrapper DIV.
+
+ var wrapper = widget.declaredClass ? widget._popupWrapper : (dojo.hasClass(widget.parentNode, "dijitPopup") && widget.parentNode),
+ node = widget.domNode || widget;
+
+ if(!wrapper){
+ // Create wrapper <div> for when this widget [in the future] will be used as a popup.
+ // This is done early because of IE bugs where creating/moving DOM nodes causes focus
+ // to go wonky, see tests/robot/Toolbar.html to reproduce
+ wrapper = dojo.create("div",{
+ "class":"dijitPopup",
+ style:{ display: "none"},
+ role: "presentation"
+ }, dojo.body());
+ wrapper.appendChild(node);
+
+ var s = node.style;
+ s.display = "";
+ s.visibility = "";
+ s.position = "";
+ s.top = "0px";
+
+ if(widget.declaredClass){ // TODO: in 2.0 change signature to always take widget, then remove if()
+ widget._popupWrapper = wrapper;
+ dojo.connect(widget, "destroy", function(){
+ dojo.destroy(wrapper);
+ delete widget._popupWrapper;
+ });
+ }
+ }
+
+ return wrapper;
+ },
+
+ moveOffScreen: function(/*Widget || DomNode*/ widget){
+ // summary:
+ // Moves the popup widget off-screen.
+ // Do not use this method to hide popups when not in use, because
+ // that will create an accessibility issue: the offscreen popup is
+ // still in the tabbing order.
+
+ // Create wrapper if not already there
+ var wrapper = this._createWrapper(widget);
+
+ dojo.style(wrapper, {
+ visibility: "hidden",
+ top: "-9999px", // prevent transient scrollbar causing misalign (#5776), and initial flash in upper left (#10111)
+ display: ""
+ });
+ },
+
+ hide: function(/*dijit._Widget*/ widget){
+ // summary:
+ // Hide this popup widget (until it is ready to be shown).
+ // Initialization for widgets that will be used as popups
+ //
+ // Also puts widget inside a wrapper DIV (if not already in one)
+ //
+ // If popup widget needs to layout it should
+ // do so when it is made visible, and popup._onShow() is called.
+
+ // Create wrapper if not already there
+ var wrapper = this._createWrapper(widget);
+
+ dojo.style(wrapper, "display", "none");
+ },
+
+ getTopPopup: function(){
+ // summary:
+ // Compute the closest ancestor popup that's *not* a child of another popup.
+ // Ex: For a TooltipDialog with a button that spawns a tree of menus, find the popup of the button.
+ var stack = this._stack;
+ for(var pi=stack.length-1; pi > 0 && stack[pi].parent === stack[pi-1].widget; pi--){
+ /* do nothing, just trying to get right value for pi */
+ }
+ return stack[pi];
+ },
+
+ open: function(/*dijit.popup.__OpenArgs*/ args){
+ // summary:
+ // Popup the widget at the specified position
+ //
+ // example:
+ // opening at the mouse position
+ // | dijit.popup.open({popup: menuWidget, x: evt.pageX, y: evt.pageY});
+ //
+ // example:
+ // opening the widget as a dropdown
+ // | dijit.popup.open({parent: this, popup: menuWidget, around: this.domNode, onClose: function(){...}});
+ //
+ // Note that whatever widget called dijit.popup.open() should also listen to its own _onBlur callback
+ // (fired from _base/focus.js) to know that focus has moved somewhere else and thus the popup should be closed.
+
+ var stack = this._stack,
+ widget = args.popup,
+ orient = args.orient || (
+ (args.parent ? args.parent.isLeftToRight() : dojo._isBodyLtr()) ?
+ {'BL':'TL', 'BR':'TR', 'TL':'BL', 'TR':'BR'} :
+ {'BR':'TR', 'BL':'TL', 'TR':'BR', 'TL':'BL'}
+ ),
+ around = args.around,
+ id = (args.around && args.around.id) ? (args.around.id+"_dropdown") : ("popup_"+this._idGen++);
+
+ // If we are opening a new popup that isn't a child of a currently opened popup, then
+ // close currently opened popup(s). This should happen automatically when the old popups
+ // gets the _onBlur() event, except that the _onBlur() event isn't reliable on IE, see [22198].
+ while(stack.length && (!args.parent || !dojo.isDescendant(args.parent.domNode, stack[stack.length-1].widget.domNode))){
+ dijit.popup.close(stack[stack.length-1].widget);
+ }
+
+ // Get pointer to popup wrapper, and create wrapper if it doesn't exist
+ var wrapper = this._createWrapper(widget);
+
+
+ dojo.attr(wrapper, {
+ id: id,
+ style: {
+ zIndex: this._beginZIndex + stack.length
+ },
+ "class": "dijitPopup " + (widget.baseClass || widget["class"] || "").split(" ")[0] +"Popup",
+ dijitPopupParent: args.parent ? args.parent.id : ""
+ });
+
+ if(dojo.isIE || dojo.isMoz){
+ if(!widget.bgIframe){
+ // setting widget.bgIframe triggers cleanup in _Widget.destroy()
+ widget.bgIframe = new dijit.BackgroundIframe(wrapper);
+ }
+ }
+
+ // position the wrapper node and make it visible
+ var best = around ?
+ dijit.placeOnScreenAroundElement(wrapper, around, orient, widget.orient ? dojo.hitch(widget, "orient") : null) :
+ dijit.placeOnScreen(wrapper, args, orient == 'R' ? ['TR','BR','TL','BL'] : ['TL','BL','TR','BR'], args.padding);
+
+ wrapper.style.display = "";
+ wrapper.style.visibility = "visible";
+ widget.domNode.style.visibility = "visible"; // counteract effects from _HasDropDown
+
+ var handlers = [];
+
+ // provide default escape and tab key handling
+ // (this will work for any widget, not just menu)
+ handlers.push(dojo.connect(wrapper, "onkeypress", this, function(evt){
+ if(evt.charOrCode == dojo.keys.ESCAPE && args.onCancel){
+ dojo.stopEvent(evt);
+ args.onCancel();
+ }else if(evt.charOrCode === dojo.keys.TAB){
+ dojo.stopEvent(evt);
+ var topPopup = this.getTopPopup();
+ if(topPopup && topPopup.onCancel){
+ topPopup.onCancel();
+ }
+ }
+ }));
+
+ // watch for cancel/execute events on the popup and notify the caller
+ // (for a menu, "execute" means clicking an item)
+ if(widget.onCancel){
+ handlers.push(dojo.connect(widget, "onCancel", args.onCancel));
+ }
+
+ handlers.push(dojo.connect(widget, widget.onExecute ? "onExecute" : "onChange", this, function(){
+ var topPopup = this.getTopPopup();
+ if(topPopup && topPopup.onExecute){
+ topPopup.onExecute();
+ }
+ }));
+
+ stack.push({
+ widget: widget,
+ parent: args.parent,
+ onExecute: args.onExecute,
+ onCancel: args.onCancel,
+ onClose: args.onClose,
+ handlers: handlers
+ });
+
+ if(widget.onOpen){
+ // TODO: in 2.0 standardize onShow() (used by StackContainer) and onOpen() (used here)
+ widget.onOpen(best);
+ }
+
+ return best;
+ },
+
+ close: function(/*dijit._Widget?*/ popup){
+ // summary:
+ // Close specified popup and any popups that it parented.
+ // If no popup is specified, closes all popups.
+
+ var stack = this._stack;
+
+ // Basically work backwards from the top of the stack closing popups
+ // until we hit the specified popup, but IIRC there was some issue where closing
+ // a popup would cause others to close too. Thus if we are trying to close B in [A,B,C]
+ // closing C might close B indirectly and then the while() condition will run where stack==[A]...
+ // so the while condition is constructed defensively.
+ while((popup && dojo.some(stack, function(elem){return elem.widget == popup;})) ||
+ (!popup && stack.length)){
+ var top = stack.pop(),
+ widget = top.widget,
+ onClose = top.onClose;
+
+ if(widget.onClose){
+ // TODO: in 2.0 standardize onHide() (used by StackContainer) and onClose() (used here)
+ widget.onClose();
+ }
+ dojo.forEach(top.handlers, dojo.disconnect);
+
+ // Hide the widget and it's wrapper unless it has already been destroyed in above onClose() etc.
+ if(widget && widget.domNode){
+ this.hide(widget);
+ }
+
+ if(onClose){
+ onClose();
+ }
+ }
+ }
+};
+
+// TODO: remove dijit._frames, it isn't being used much, since popups never release their
+// iframes (see [22236])
+dijit._frames = new function(){
+ // summary:
+ // cache of iframes
+
+ var queue = [];
+
+ this.pop = function(){
+ var iframe;
+ if(queue.length){
+ iframe = queue.pop();
+ iframe.style.display="";
+ }else{
+ if(dojo.isIE < 9){
+ var burl = dojo.config["dojoBlankHtmlUrl"] || (dojo.moduleUrl("dojo", "resources/blank.html")+"") || "javascript:\"\"";
+ var html="<iframe src='" + burl + "'"
+ + " style='position: absolute; left: 0px; top: 0px;"
+ + "z-index: -1; filter:Alpha(Opacity=\"0\");'>";
+ iframe = dojo.doc.createElement(html);
+ }else{
+ iframe = dojo.create("iframe");
+ iframe.src = 'javascript:""';
+ iframe.className = "dijitBackgroundIframe";
+ dojo.style(iframe, "opacity", 0.1);
+ }
+ iframe.tabIndex = -1; // Magic to prevent iframe from getting focus on tab keypress - as style didn't work.
+ dijit.setWaiRole(iframe,"presentation");
+ }
+ return iframe;
+ };
+
+ this.push = function(iframe){
+ iframe.style.display="none";
+ queue.push(iframe);
+ }
+}();
+
+
+dijit.BackgroundIframe = function(/*DomNode*/ node){
+ // summary:
+ // For IE/FF z-index schenanigans. id attribute is required.
+ //
+ // description:
+ // new dijit.BackgroundIframe(node)
+ // Makes a background iframe as a child of node, that fills
+ // area (and position) of node
+
+ if(!node.id){ throw new Error("no id"); }
+ if(dojo.isIE || dojo.isMoz){
+ var iframe = (this.iframe = dijit._frames.pop());
+ node.appendChild(iframe);
+ if(dojo.isIE<7 || dojo.isQuirks){
+ this.resize(node);
+ this._conn = dojo.connect(node, 'onresize', this, function(){
+ this.resize(node);
+ });
+ }else{
+ dojo.style(iframe, {
+ width: '100%',
+ height: '100%'
+ });
+ }
+ }
+};
+
+dojo.extend(dijit.BackgroundIframe, {
+ resize: function(node){
+ // summary:
+ // Resize the iframe so it's the same size as node.
+ // Needed on IE6 and IE/quirks because height:100% doesn't work right.
+ if(this.iframe){
+ dojo.style(this.iframe, {
+ width: node.offsetWidth + 'px',
+ height: node.offsetHeight + 'px'
+ });
+ }
+ },
+ destroy: function(){
+ // summary:
+ // destroy the iframe
+ if(this._conn){
+ dojo.disconnect(this._conn);
+ this._conn = null;
+ }
+ if(this.iframe){
+ dijit._frames.push(this.iframe);
+ delete this.iframe;
+ }
+ }
+});
+
+}
+
+if(!dojo._hasResource["dijit._base.scroll"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.scroll"] = true;
+dojo.provide("dijit._base.scroll");
+
+
+
+
+dijit.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
+ // summary:
+ // Scroll the passed node into view, if it is not already.
+ // Deprecated, use `dojo.window.scrollIntoView` instead.
+
+ dojo.window.scrollIntoView(node, pos);
+};
+
+}
+
+if(!dojo._hasResource["dojo.uacss"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.uacss"] = true;
+dojo.provide("dojo.uacss");
+
+
+
+(function(){
+ // summary:
+ // Applies pre-set CSS classes to the top-level HTML node, based on:
+ // - browser (ex: dj_ie)
+ // - browser version (ex: dj_ie6)
+ // - box model (ex: dj_contentBox)
+ // - text direction (ex: dijitRtl)
+ //
+ // In addition, browser, browser version, and box model are
+ // combined with an RTL flag when browser text is RTL. ex: dj_ie-rtl.
+
+ var d = dojo,
+ html = d.doc.documentElement,
+ ie = d.isIE,
+ opera = d.isOpera,
+ maj = Math.floor,
+ ff = d.isFF,
+ boxModel = d.boxModel.replace(/-/,''),
+
+ classes = {
+ dj_ie: ie,
+ dj_ie6: maj(ie) == 6,
+ dj_ie7: maj(ie) == 7,
+ dj_ie8: maj(ie) == 8,
+ dj_ie9: maj(ie) == 9,
+ dj_quirks: d.isQuirks,
+ dj_iequirks: ie && d.isQuirks,
+
+ // NOTE: Opera not supported by dijit
+ dj_opera: opera,
+
+ dj_khtml: d.isKhtml,
+
+ dj_webkit: d.isWebKit,
+ dj_safari: d.isSafari,
+ dj_chrome: d.isChrome,
+
+ dj_gecko: d.isMozilla,
+ dj_ff3: maj(ff) == 3
+ }; // no dojo unsupported browsers
+
+ classes["dj_" + boxModel] = true;
+
+ // apply browser, browser version, and box model class names
+ var classStr = "";
+ for(var clz in classes){
+ if(classes[clz]){
+ classStr += clz + " ";
+ }
+ }
+ html.className = d.trim(html.className + " " + classStr);
+
+ // If RTL mode, then add dj_rtl flag plus repeat existing classes with -rtl extension.
+ // We can't run the code below until the <body> tag has loaded (so we can check for dir=rtl).
+ // Unshift() is to run sniff code before the parser.
+ dojo._loaders.unshift(function(){
+ if(!dojo._isBodyLtr()){
+ var rtlClassStr = "dj_rtl dijitRtl " + classStr.replace(/ /g, "-rtl ")
+ html.className = d.trim(html.className + " " + rtlClassStr);
+ }
+ });
+})();
+
+}
+
+if(!dojo._hasResource["dijit._base.sniff"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.sniff"] = true;
+dojo.provide("dijit._base.sniff");
+
+
+
+
+// summary:
+// Applies pre-set CSS classes to the top-level HTML node, see
+// `dojo.uacss` for details.
+//
+// Simply doing a require on this module will
+// establish this CSS. Modified version of Morris' CSS hack.
+
+}
+
+if(!dojo._hasResource["dijit._base.typematic"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.typematic"] = true;
+dojo.provide("dijit._base.typematic");
+
+
+
+dijit.typematic = {
+ // summary:
+ // These functions are used to repetitively call a user specified callback
+ // method when a specific key or mouse click over a specific DOM node is
+ // held down for a specific amount of time.
+ // Only 1 such event is allowed to occur on the browser page at 1 time.
+
+ _fireEventAndReload: function(){
+ this._timer = null;
+ this._callback(++this._count, this._node, this._evt);
+
+ // Schedule next event, timer is at most minDelay (default 10ms) to avoid
+ // browser overload (particularly avoiding starving DOH robot so it never gets to send a mouseup)
+ this._currentTimeout = Math.max(
+ this._currentTimeout < 0 ? this._initialDelay :
+ (this._subsequentDelay > 1 ? this._subsequentDelay : Math.round(this._currentTimeout * this._subsequentDelay)),
+ this._minDelay);
+ this._timer = setTimeout(dojo.hitch(this, "_fireEventAndReload"), this._currentTimeout);
+ },
+
+ trigger: function(/*Event*/ evt, /*Object*/ _this, /*DOMNode*/ node, /*Function*/ callback, /*Object*/ obj, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
+ // summary:
+ // Start a timed, repeating callback sequence.
+ // If already started, the function call is ignored.
+ // This method is not normally called by the user but can be
+ // when the normal listener code is insufficient.
+ // evt:
+ // key or mouse event object to pass to the user callback
+ // _this:
+ // pointer to the user's widget space.
+ // node:
+ // the DOM node object to pass the the callback function
+ // callback:
+ // function to call until the sequence is stopped called with 3 parameters:
+ // count:
+ // integer representing number of repeated calls (0..n) with -1 indicating the iteration has stopped
+ // node:
+ // the DOM node object passed in
+ // evt:
+ // key or mouse event object
+ // obj:
+ // user space object used to uniquely identify each typematic sequence
+ // subsequentDelay (optional):
+ // if > 1, the number of milliseconds until the 3->n events occur
+ // or else the fractional time multiplier for the next event's delay, default=0.9
+ // initialDelay (optional):
+ // the number of milliseconds until the 2nd event occurs, default=500ms
+ // minDelay (optional):
+ // the maximum delay in milliseconds for event to fire, default=10ms
+ if(obj != this._obj){
+ this.stop();
+ this._initialDelay = initialDelay || 500;
+ this._subsequentDelay = subsequentDelay || 0.90;
+ this._minDelay = minDelay || 10;
+ this._obj = obj;
+ this._evt = evt;
+ this._node = node;
+ this._currentTimeout = -1;
+ this._count = -1;
+ this._callback = dojo.hitch(_this, callback);
+ this._fireEventAndReload();
+ this._evt = dojo.mixin({faux: true}, evt);
+ }
+ },
+
+ stop: function(){
+ // summary:
+ // Stop an ongoing timed, repeating callback sequence.
+ if(this._timer){
+ clearTimeout(this._timer);
+ this._timer = null;
+ }
+ if(this._obj){
+ this._callback(-1, this._node, this._evt);
+ this._obj = null;
+ }
+ },
+
+ addKeyListener: function(/*DOMNode*/ node, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
+ // summary:
+ // Start listening for a specific typematic key.
+ // See also the trigger method for other parameters.
+ // keyObject:
+ // an object defining the key to listen for:
+ // charOrCode:
+ // the printable character (string) or keyCode (number) to listen for.
+ // keyCode:
+ // (deprecated - use charOrCode) the keyCode (number) to listen for (implies charCode = 0).
+ // charCode:
+ // (deprecated - use charOrCode) the charCode (number) to listen for.
+ // ctrlKey:
+ // desired ctrl key state to initiate the callback sequence:
+ // - pressed (true)
+ // - released (false)
+ // - either (unspecified)
+ // altKey:
+ // same as ctrlKey but for the alt key
+ // shiftKey:
+ // same as ctrlKey but for the shift key
+ // returns:
+ // an array of dojo.connect handles
+ if(keyObject.keyCode){
+ keyObject.charOrCode = keyObject.keyCode;
+ dojo.deprecated("keyCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.", "", "2.0");
+ }else if(keyObject.charCode){
+ keyObject.charOrCode = String.fromCharCode(keyObject.charCode);
+ dojo.deprecated("charCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.", "", "2.0");
+ }
+ return [
+ dojo.connect(node, "onkeypress", this, function(evt){
+ if(evt.charOrCode == keyObject.charOrCode &&
+ (keyObject.ctrlKey === undefined || keyObject.ctrlKey == evt.ctrlKey) &&
+ (keyObject.altKey === undefined || keyObject.altKey == evt.altKey) &&
+ (keyObject.metaKey === undefined || keyObject.metaKey == (evt.metaKey || false)) && // IE doesn't even set metaKey
+ (keyObject.shiftKey === undefined || keyObject.shiftKey == evt.shiftKey)){
+ dojo.stopEvent(evt);
+ dijit.typematic.trigger(evt, _this, node, callback, keyObject, subsequentDelay, initialDelay, minDelay);
+ }else if(dijit.typematic._obj == keyObject){
+ dijit.typematic.stop();
+ }
+ }),
+ dojo.connect(node, "onkeyup", this, function(evt){
+ if(dijit.typematic._obj == keyObject){
+ dijit.typematic.stop();
+ }
+ })
+ ];
+ },
+
+ addMouseListener: function(/*DOMNode*/ node, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
+ // summary:
+ // Start listening for a typematic mouse click.
+ // See the trigger method for other parameters.
+ // returns:
+ // an array of dojo.connect handles
+ var dc = dojo.connect;
+ return [
+ dc(node, "mousedown", this, function(evt){
+ dojo.stopEvent(evt);
+ dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay, minDelay);
+ }),
+ dc(node, "mouseup", this, function(evt){
+ dojo.stopEvent(evt);
+ dijit.typematic.stop();
+ }),
+ dc(node, "mouseout", this, function(evt){
+ dojo.stopEvent(evt);
+ dijit.typematic.stop();
+ }),
+ dc(node, "mousemove", this, function(evt){
+ evt.preventDefault();
+ }),
+ dc(node, "dblclick", this, function(evt){
+ dojo.stopEvent(evt);
+ if(dojo.isIE){
+ dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay, minDelay);
+ setTimeout(dojo.hitch(this, dijit.typematic.stop), 50);
+ }
+ })
+ ];
+ },
+
+ addListener: function(/*Node*/ mouseNode, /*Node*/ keyNode, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
+ // summary:
+ // Start listening for a specific typematic key and mouseclick.
+ // This is a thin wrapper to addKeyListener and addMouseListener.
+ // See the addMouseListener and addKeyListener methods for other parameters.
+ // mouseNode:
+ // the DOM node object to listen on for mouse events.
+ // keyNode:
+ // the DOM node object to listen on for key events.
+ // returns:
+ // an array of dojo.connect handles
+ return this.addKeyListener(keyNode, keyObject, _this, callback, subsequentDelay, initialDelay, minDelay).concat(
+ this.addMouseListener(mouseNode, _this, callback, subsequentDelay, initialDelay, minDelay));
+ }
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.wai"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.wai"] = true;
+dojo.provide("dijit._base.wai");
+
+
+
+dijit.wai = {
+ onload: function(){
+ // summary:
+ // Detects if we are in high-contrast mode or not
+
+ // This must be a named function and not an anonymous
+ // function, so that the widget parsing code can make sure it
+ // registers its onload function after this function.
+ // DO NOT USE "this" within this function.
+
+ // create div for testing if high contrast mode is on or images are turned off
+ var div = dojo.create("div",{
+ id: "a11yTestNode",
+ style:{
+ cssText:'border: 1px solid;'
+ + 'border-color:red green;'
+ + 'position: absolute;'
+ + 'height: 5px;'
+ + 'top: -999px;'
+ + 'background-image: url("' + (dojo.config.blankGif || dojo.moduleUrl("dojo", "resources/blank.gif")) + '");'
+ }
+ }, dojo.body());
+
+ // test it
+ var cs = dojo.getComputedStyle(div);
+ if(cs){
+ var bkImg = cs.backgroundImage;
+ var needsA11y = (cs.borderTopColor == cs.borderRightColor) || (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" ));
+ dojo[needsA11y ? "addClass" : "removeClass"](dojo.body(), "dijit_a11y");
+ if(dojo.isIE){
+ div.outerHTML = ""; // prevent mixed-content warning, see http://support.microsoft.com/kb/925014
+ }else{
+ dojo.body().removeChild(div);
+ }
+ }
+ }
+};
+
+// Test if computer is in high contrast mode.
+// Make sure the a11y test runs first, before widgets are instantiated.
+if(dojo.isIE || dojo.isMoz){ // NOTE: checking in Safari messes things up
+ dojo._loaders.unshift(dijit.wai.onload);
+}
+
+dojo.mixin(dijit, {
+ hasWaiRole: function(/*Element*/ elem, /*String?*/ role){
+ // summary:
+ // Determines if an element has a particular role.
+ // returns:
+ // True if elem has the specific role attribute and false if not.
+ // For backwards compatibility if role parameter not provided,
+ // returns true if has a role
+ var waiRole = this.getWaiRole(elem);
+ return role ? (waiRole.indexOf(role) > -1) : (waiRole.length > 0);
+ },
+
+ getWaiRole: function(/*Element*/ elem){
+ // summary:
+ // Gets the role for an element (which should be a wai role).
+ // returns:
+ // The role of elem or an empty string if elem
+ // does not have a role.
+ return dojo.trim((dojo.attr(elem, "role") || "").replace("wairole:",""));
+ },
+
+ setWaiRole: function(/*Element*/ elem, /*String*/ role){
+ // summary:
+ // Sets the role on an element.
+ // description:
+ // Replace existing role attribute with new role.
+
+ dojo.attr(elem, "role", role);
+ },
+
+ removeWaiRole: function(/*Element*/ elem, /*String*/ role){
+ // summary:
+ // Removes the specified role from an element.
+ // Removes role attribute if no specific role provided (for backwards compat.)
+
+ var roleValue = dojo.attr(elem, "role");
+ if(!roleValue){ return; }
+ if(role){
+ var t = dojo.trim((" " + roleValue + " ").replace(" " + role + " ", " "));
+ dojo.attr(elem, "role", t);
+ }else{
+ elem.removeAttribute("role");
+ }
+ },
+
+ hasWaiState: function(/*Element*/ elem, /*String*/ state){
+ // summary:
+ // Determines if an element has a given state.
+ // description:
+ // Checks for an attribute called "aria-"+state.
+ // returns:
+ // true if elem has a value for the given state and
+ // false if it does not.
+
+ return elem.hasAttribute ? elem.hasAttribute("aria-"+state) : !!elem.getAttribute("aria-"+state);
+ },
+
+ getWaiState: function(/*Element*/ elem, /*String*/ state){
+ // summary:
+ // Gets the value of a state on an element.
+ // description:
+ // Checks for an attribute called "aria-"+state.
+ // returns:
+ // The value of the requested state on elem
+ // or an empty string if elem has no value for state.
+
+ return elem.getAttribute("aria-"+state) || "";
+ },
+
+ setWaiState: function(/*Element*/ elem, /*String*/ state, /*String*/ value){
+ // summary:
+ // Sets a state on an element.
+ // description:
+ // Sets an attribute called "aria-"+state.
+
+ elem.setAttribute("aria-"+state, value);
+ },
+
+ removeWaiState: function(/*Element*/ elem, /*String*/ state){
+ // summary:
+ // Removes a state from an element.
+ // description:
+ // Sets an attribute called "aria-"+state.
+
+ elem.removeAttribute("aria-"+state);
+ }
+});
+
+}
+
+if(!dojo._hasResource["dijit._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base"] = true;
+dojo.provide("dijit._base");
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+if(!dojo._hasResource["dojo.date.stamp"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.date.stamp"] = true;
+dojo.provide("dojo.date.stamp");
+
+
+dojo.getObject("date.stamp", true, dojo);
+
+// Methods to convert dates to or from a wire (string) format using well-known conventions
+
+dojo.date.stamp.fromISOString = function(/*String*/formattedString, /*Number?*/defaultTime){
+ // summary:
+ // Returns a Date object given a string formatted according to a subset of the ISO-8601 standard.
+ //
+ // description:
+ // Accepts a string formatted according to a profile of ISO8601 as defined by
+ // [RFC3339](http://www.ietf.org/rfc/rfc3339.txt), except that partial input is allowed.
+ // Can also process dates as specified [by the W3C](http://www.w3.org/TR/NOTE-datetime)
+ // The following combinations are valid:
+ //
+ // * dates only
+ // | * yyyy
+ // | * yyyy-MM
+ // | * yyyy-MM-dd
+ // * times only, with an optional time zone appended
+ // | * THH:mm
+ // | * THH:mm:ss
+ // | * THH:mm:ss.SSS
+ // * and "datetimes" which could be any combination of the above
+ //
+ // timezones may be specified as Z (for UTC) or +/- followed by a time expression HH:mm
+ // Assumes the local time zone if not specified. Does not validate. Improperly formatted
+ // input may return null. Arguments which are out of bounds will be handled
+ // by the Date constructor (e.g. January 32nd typically gets resolved to February 1st)
+ // Only years between 100 and 9999 are supported.
+ //
+ // formattedString:
+ // A string such as 2005-06-30T08:05:00-07:00 or 2005-06-30 or T08:05:00
+ //
+ // defaultTime:
+ // Used for defaults for fields omitted in the formattedString.
+ // Uses 1970-01-01T00:00:00.0Z by default.
+
+ if(!dojo.date.stamp._isoRegExp){
+ dojo.date.stamp._isoRegExp =
+//TODO: could be more restrictive and check for 00-59, etc.
+ /^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(.\d+)?)?((?:[+-](\d{2}):(\d{2}))|Z)?)?$/;
+ }
+
+ var match = dojo.date.stamp._isoRegExp.exec(formattedString),
+ result = null;
+
+ if(match){
+ match.shift();
+ if(match[1]){match[1]--;} // Javascript Date months are 0-based
+ if(match[6]){match[6] *= 1000;} // Javascript Date expects fractional seconds as milliseconds
+
+ if(defaultTime){
+ // mix in defaultTime. Relatively expensive, so use || operators for the fast path of defaultTime === 0
+ defaultTime = new Date(defaultTime);
+ dojo.forEach(dojo.map(["FullYear", "Month", "Date", "Hours", "Minutes", "Seconds", "Milliseconds"], function(prop){
+ return defaultTime["get" + prop]();
+ }), function(value, index){
+ match[index] = match[index] || value;
+ });
+ }
+ result = new Date(match[0]||1970, match[1]||0, match[2]||1, match[3]||0, match[4]||0, match[5]||0, match[6]||0); //TODO: UTC defaults
+ if(match[0] < 100){
+ result.setFullYear(match[0] || 1970);
+ }
+
+ var offset = 0,
+ zoneSign = match[7] && match[7].charAt(0);
+ if(zoneSign != 'Z'){
+ offset = ((match[8] || 0) * 60) + (Number(match[9]) || 0);
+ if(zoneSign != '-'){ offset *= -1; }
+ }
+ if(zoneSign){
+ offset -= result.getTimezoneOffset();
+ }
+ if(offset){
+ result.setTime(result.getTime() + offset * 60000);
+ }
+ }
+
+ return result; // Date or null
+};
+
+/*=====
+ dojo.date.stamp.__Options = function(){
+ // selector: String
+ // "date" or "time" for partial formatting of the Date object.
+ // Both date and time will be formatted by default.
+ // zulu: Boolean
+ // if true, UTC/GMT is used for a timezone
+ // milliseconds: Boolean
+ // if true, output milliseconds
+ this.selector = selector;
+ this.zulu = zulu;
+ this.milliseconds = milliseconds;
+ }
+=====*/
+
+dojo.date.stamp.toISOString = function(/*Date*/dateObject, /*dojo.date.stamp.__Options?*/options){
+ // summary:
+ // Format a Date object as a string according a subset of the ISO-8601 standard
+ //
+ // description:
+ // When options.selector is omitted, output follows [RFC3339](http://www.ietf.org/rfc/rfc3339.txt)
+ // The local time zone is included as an offset from GMT, except when selector=='time' (time without a date)
+ // Does not check bounds. Only years between 100 and 9999 are supported.
+ //
+ // dateObject:
+ // A Date object
+
+ var _ = function(n){ return (n < 10) ? "0" + n : n; };
+ options = options || {};
+ var formattedDate = [],
+ getter = options.zulu ? "getUTC" : "get",
+ date = "";
+ if(options.selector != "time"){
+ var year = dateObject[getter+"FullYear"]();
+ date = ["0000".substr((year+"").length)+year, _(dateObject[getter+"Month"]()+1), _(dateObject[getter+"Date"]())].join('-');
+ }
+ formattedDate.push(date);
+ if(options.selector != "date"){
+ var time = [_(dateObject[getter+"Hours"]()), _(dateObject[getter+"Minutes"]()), _(dateObject[getter+"Seconds"]())].join(':');
+ var millis = dateObject[getter+"Milliseconds"]();
+ if(options.milliseconds){
+ time += "."+ (millis < 100 ? "0" : "") + _(millis);
+ }
+ if(options.zulu){
+ time += "Z";
+ }else if(options.selector != "time"){
+ var timezoneOffset = dateObject.getTimezoneOffset();
+ var absOffset = Math.abs(timezoneOffset);
+ time += (timezoneOffset > 0 ? "-" : "+") +
+ _(Math.floor(absOffset/60)) + ":" + _(absOffset%60);
+ }
+ formattedDate.push(time);
+ }
+ return formattedDate.join('T'); // String
+};
+
+}
+
+if(!dojo._hasResource["dojo.parser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.parser"] = true;
+dojo.provide("dojo.parser");
+
+
+
+
+new Date("X"); // workaround for #11279, new Date("") == NaN
+
+dojo.parser = new function(){
+ // summary:
+ // The Dom/Widget parsing package
+
+ var d = dojo;
+
+ function val2type(/*Object*/ value){
+ // summary:
+ // Returns name of type of given value.
+
+ if(d.isString(value)){ return "string"; }
+ if(typeof value == "number"){ return "number"; }
+ if(typeof value == "boolean"){ return "boolean"; }
+ if(d.isFunction(value)){ return "function"; }
+ if(d.isArray(value)){ return "array"; } // typeof [] == "object"
+ if(value instanceof Date) { return "date"; } // assume timestamp
+ if(value instanceof d._Url){ return "url"; }
+ return "object";
+ }
+
+ function str2obj(/*String*/ value, /*String*/ type){
+ // summary:
+ // Convert given string value to given type
+ switch(type){
+ case "string":
+ return value;
+ case "number":
+ return value.length ? Number(value) : NaN;
+ case "boolean":
+ // for checked/disabled value might be "" or "checked". interpret as true.
+ return typeof value == "boolean" ? value : !(value.toLowerCase()=="false");
+ case "function":
+ if(d.isFunction(value)){
+ // IE gives us a function, even when we say something like onClick="foo"
+ // (in which case it gives us an invalid function "function(){ foo }").
+ // Therefore, convert to string
+ value=value.toString();
+ value=d.trim(value.substring(value.indexOf('{')+1, value.length-1));
+ }
+ try{
+ if(value === "" || value.search(/[^\w\.]+/i) != -1){
+ // The user has specified some text for a function like "return x+5"
+ return new Function(value);
+ }else{
+ // The user has specified the name of a function like "myOnClick"
+ // or a single word function "return"
+ return d.getObject(value, false) || new Function(value);
+ }
+ }catch(e){ return new Function(); }
+ case "array":
+ return value ? value.split(/\s*,\s*/) : [];
+ case "date":
+ switch(value){
+ case "": return new Date(""); // the NaN of dates
+ case "now": return new Date(); // current date
+ default: return d.date.stamp.fromISOString(value);
+ }
+ case "url":
+ return d.baseUrl + value;
+ default:
+ return d.fromJson(value);
+ }
+ }
+
+ var dummyClass = {}, instanceClasses = {
+ // map from fully qualified name (like "dijit.Button") to structure like
+ // { cls: dijit.Button, params: {label: "string", disabled: "boolean"} }
+ };
+
+ // Widgets like BorderContainer add properties to _Widget via dojo.extend().
+ // If BorderContainer is loaded after _Widget's parameter list has been cached,
+ // we need to refresh that parameter list (for _Widget and all widgets that extend _Widget).
+ // TODO: remove this in 2.0, when we stop caching parameters.
+ d.connect(d, "extend", function(){
+ instanceClasses = {};
+ });
+
+ function getProtoInfo(cls, params){
+ // cls: A prototype
+ // The prototype of the class to check props on
+ // params: Object
+ // The parameters object to mix found parameters onto.
+ for(var name in cls){
+ if(name.charAt(0)=="_"){ continue; } // skip internal properties
+ if(name in dummyClass){ continue; } // skip "constructor" and "toString"
+ params[name] = val2type(cls[name]);
+ }
+ return params;
+ }
+
+ function getClassInfo(/*String*/ className, /*Boolean*/ skipParamsLookup){
+ // summary:
+ // Maps a widget name string like "dijit.form.Button" to the widget constructor itself,
+ // and a list of that widget's parameters and their types
+ // className:
+ // fully qualified name (like "dijit.form.Button")
+ // returns:
+ // structure like
+ // {
+ // cls: dijit.Button,
+ // params: { label: "string", disabled: "boolean"}
+ // }
+
+ var c = instanceClasses[className];
+ if(!c){
+ // get pointer to widget class
+ var cls = d.getObject(className), params = null;
+ if(!cls){ return null; } // class not defined [yet]
+ if(!skipParamsLookup){ // from fastpath, we don't need to lookup the attrs on the proto because they are explicit
+ params = getProtoInfo(cls.prototype, {})
+ }
+ c = { cls: cls, params: params };
+
+ }else if(!skipParamsLookup && !c.params){
+ // if we're calling getClassInfo and have a cls proto, but no params info, scan that cls for params now
+ // and update the pointer in instanceClasses[className]. This happens when a widget appears in another
+ // widget's template which still uses dojoType, but an instance of the widget appears prior with a data-dojo-type,
+ // skipping this lookup the first time.
+ c.params = getProtoInfo(c.cls.prototype, {});
+ }
+
+ return c;
+ }
+
+ this._functionFromScript = function(script, attrData){
+ // summary:
+ // Convert a <script type="dojo/method" args="a, b, c"> ... </script>
+ // into a function
+ // script: DOMNode
+ // The <script> DOMNode
+ // attrData: String
+ // For HTML5 compliance, searches for attrData + "args" (typically
+ // "data-dojo-args") instead of "args"
+ var preamble = "";
+ var suffix = "";
+ var argsStr = (script.getAttribute(attrData + "args") || script.getAttribute("args"));
+ if(argsStr){
+ d.forEach(argsStr.split(/\s*,\s*/), function(part, idx){
+ preamble += "var "+part+" = arguments["+idx+"]; ";
+ });
+ }
+ var withStr = script.getAttribute("with");
+ if(withStr && withStr.length){
+ d.forEach(withStr.split(/\s*,\s*/), function(part){
+ preamble += "with("+part+"){";
+ suffix += "}";
+ });
+ }
+ return new Function(preamble+script.innerHTML+suffix);
+ };
+
+ this.instantiate = function(/* Array */nodes, /* Object? */mixin, /* Object? */args){
+ // summary:
+ // Takes array of nodes, and turns them into class instances and
+ // potentially calls a startup method to allow them to connect with
+ // any children.
+ // nodes: Array
+ // Array of nodes or objects like
+ // | {
+ // | type: "dijit.form.Button",
+ // | node: DOMNode,
+ // | scripts: [ ... ], // array of <script type="dojo/..."> children of node
+ // | inherited: { ... } // settings inherited from ancestors like dir, theme, etc.
+ // | }
+ // mixin: Object?
+ // An object that will be mixed in with each node in the array.
+ // Values in the mixin will override values in the node, if they
+ // exist.
+ // args: Object?
+ // An object used to hold kwArgs for instantiation.
+ // See parse.args argument for details.
+
+ var thelist = [],
+ mixin = mixin||{};
+ args = args||{};
+
+ // TODO: for 2.0 default to data-dojo- regardless of scopeName (or maybe scopeName won't exist in 2.0)
+ var attrName = (args.scope || d._scopeName) + "Type", // typically "dojoType"
+ attrData = "data-" + (args.scope || d._scopeName) + "-"; // typically "data-dojo-"
+
+ d.forEach(nodes, function(obj){
+ if(!obj){ return; }
+
+ // Get pointers to DOMNode, dojoType string, and clsInfo (metadata about the dojoType), etc.
+ var node, type, clsInfo, clazz, scripts, fastpath;
+ if(obj.node){
+ // new format of nodes[] array, object w/lots of properties pre-computed for me
+ node = obj.node;
+ type = obj.type;
+ fastpath = obj.fastpath;
+ clsInfo = obj.clsInfo || (type && getClassInfo(type, fastpath));
+ clazz = clsInfo && clsInfo.cls;
+ scripts = obj.scripts;
+ }else{
+ // old (backwards compatible) format of nodes[] array, simple array of DOMNodes. no fastpath/data-dojo-type support here.
+ node = obj;
+ type = attrName in mixin ? mixin[attrName] : node.getAttribute(attrName);
+ clsInfo = type && getClassInfo(type);
+ clazz = clsInfo && clsInfo.cls;
+ scripts = (clazz && (clazz._noScript || clazz.prototype._noScript) ? [] :
+ d.query("> script[type^='dojo/']", node));
+ }
+ if(!clsInfo){
+ throw new Error("Could not load class '" + type);
+ }
+
+ // Setup hash to hold parameter settings for this widget. Start with the parameter
+ // settings inherited from ancestors ("dir" and "lang").
+ // Inherited setting may later be overridden by explicit settings on node itself.
+ var params = {};
+
+ if(args.defaults){
+ // settings for the document itself (or whatever subtree is being parsed)
+ d._mixin(params, args.defaults);
+ }
+ if(obj.inherited){
+ // settings from dir=rtl or lang=... on a node above this node
+ d._mixin(params, obj.inherited);
+ }
+
+ // mix things found in data-dojo-props into the params
+ if(fastpath){
+ var extra = node.getAttribute(attrData + "props");
+ if(extra && extra.length){
+ try{
+ extra = d.fromJson.call(args.propsThis, "{" + extra + "}");
+ d._mixin(params, extra);
+ }catch(e){
+ // give the user a pointer to their invalid parameters. FIXME: can we kill this in production?
+ throw new Error(e.toString() + " in data-dojo-props='" + extra + "'");
+ }
+ }
+
+ // For the benefit of _Templated, check if node has data-dojo-attach-point/data-dojo-attach-event
+ // and mix those in as though they were parameters
+ var attachPoint = node.getAttribute(attrData + "attach-point");
+ if(attachPoint){
+ params.dojoAttachPoint = attachPoint;
+ }
+ var attachEvent = node.getAttribute(attrData + "attach-event");
+ if(attachEvent){
+ params.dojoAttachEvent = attachEvent;
+ }
+ dojo.mixin(params, mixin);
+ }else{
+ // FIXME: we need something like "deprecateOnce()" to throw dojo.deprecation for something.
+ // remove this logic in 2.0
+ // read parameters (ie, attributes) specified on DOMNode
+
+ var attributes = node.attributes;
+
+ // clsInfo.params lists expected params like {"checked": "boolean", "n": "number"}
+ for(var name in clsInfo.params){
+ var item = name in mixin ? { value:mixin[name], specified:true } : attributes.getNamedItem(name);
+ if(!item || (!item.specified && (!dojo.isIE || name.toLowerCase()!="value"))){ continue; }
+ var value = item.value;
+ // Deal with IE quirks for 'class' and 'style'
+ switch(name){
+ case "class":
+ value = "className" in mixin ? mixin.className : node.className;
+ break;
+ case "style":
+ value = "style" in mixin ? mixin.style : (node.style && node.style.cssText); // FIXME: Opera?
+ }
+ var _type = clsInfo.params[name];
+ if(typeof value == "string"){
+ params[name] = str2obj(value, _type);
+ }else{
+ params[name] = value;
+ }
+ }
+ }
+
+ // Process <script type="dojo/*"> script tags
+ // <script type="dojo/method" event="foo"> tags are added to params, and passed to
+ // the widget on instantiation.
+ // <script type="dojo/method"> tags (with no event) are executed after instantiation
+ // <script type="dojo/connect" event="foo"> tags are dojo.connected after instantiation
+ // note: dojo/* script tags cannot exist in self closing widgets, like <input />
+ var connects = [], // functions to connect after instantiation
+ calls = []; // functions to call after instantiation
+
+ d.forEach(scripts, function(script){
+ node.removeChild(script);
+ // FIXME: drop event="" support in 2.0. use data-dojo-event="" instead
+ var event = (script.getAttribute(attrData + "event") || script.getAttribute("event")),
+ type = script.getAttribute("type"),
+ nf = d.parser._functionFromScript(script, attrData);
+ if(event){
+ if(type == "dojo/connect"){
+ connects.push({event: event, func: nf});
+ }else{
+ params[event] = nf;
+ }
+ }else{
+ calls.push(nf);
+ }
+ });
+
+ var markupFactory = clazz.markupFactory || clazz.prototype && clazz.prototype.markupFactory;
+ // create the instance
+ var instance = markupFactory ? markupFactory(params, node, clazz) : new clazz(params, node);
+ thelist.push(instance);
+
+ // map it to the JS namespace if that makes sense
+ // FIXME: in 2.0, drop jsId support. use data-dojo-id instead
+ var jsname = (node.getAttribute(attrData + "id") || node.getAttribute("jsId"));
+ if(jsname){
+ d.setObject(jsname, instance);
+ }
+
+ // process connections and startup functions
+ d.forEach(connects, function(connect){
+ d.connect(instance, connect.event, null, connect.func);
+ });
+ d.forEach(calls, function(func){
+ func.call(instance);
+ });
+ });
+
+ // Call startup on each top level instance if it makes sense (as for
+ // widgets). Parent widgets will recursively call startup on their
+ // (non-top level) children
+ if(!mixin._started){
+ // TODO: for 2.0, when old instantiate() API is desupported, store parent-child
+ // relationships in the nodes[] array so that no getParent() call is needed.
+ // Note that will require a parse() call from ContentPane setting a param that the
+ // ContentPane is the parent widget (so that the parse doesn't call startup() on the
+ // ContentPane's children)
+ d.forEach(thelist, function(instance){
+ if( !args.noStart && instance &&
+ dojo.isFunction(instance.startup) &&
+ !instance._started &&
+ (!instance.getParent || !instance.getParent())
+ ){
+ instance.startup();
+ }
+ });
+ }
+ return thelist;
+ };
+
+ this.parse = function(rootNode, args){
+ // summary:
+ // Scan the DOM for class instances, and instantiate them.
+ //
+ // description:
+ // Search specified node (or root node) recursively for class instances,
+ // and instantiate them. Searches for either data-dojo-type="Class" or
+ // dojoType="Class" where "Class" is a a fully qualified class name,
+ // like `dijit.form.Button`
+ //
+ // Using `data-dojo-type`:
+ // Attributes using can be mixed into the parameters used to instantitate the
+ // Class by using a `data-dojo-props` attribute on the node being converted.
+ // `data-dojo-props` should be a string attribute to be converted from JSON.
+ //
+ // Using `dojoType`:
+ // Attributes are read from the original domNode and converted to appropriate
+ // types by looking up the Class prototype values. This is the default behavior
+ // from Dojo 1.0 to Dojo 1.5. `dojoType` support is deprecated, and will
+ // go away in Dojo 2.0.
+ //
+ // rootNode: DomNode?
+ // A default starting root node from which to start the parsing. Can be
+ // omitted, defaulting to the entire document. If omitted, the `args`
+ // object can be passed in this place. If the `args` object has a
+ // `rootNode` member, that is used.
+ //
+ // args: Object
+ // a kwArgs object passed along to instantiate()
+ //
+ // * noStart: Boolean?
+ // when set will prevent the parser from calling .startup()
+ // when locating the nodes.
+ // * rootNode: DomNode?
+ // identical to the function's `rootNode` argument, though
+ // allowed to be passed in via this `args object.
+ // * template: Boolean
+ // If true, ignores ContentPane's stopParser flag and parses contents inside of
+ // a ContentPane inside of a template. This allows dojoAttachPoint on widgets/nodes
+ // nested inside the ContentPane to work.
+ // * inherited: Object
+ // Hash possibly containing dir and lang settings to be applied to
+ // parsed widgets, unless there's another setting on a sub-node that overrides
+ // * scope: String
+ // Root for attribute names to search for. If scopeName is dojo,
+ // will search for data-dojo-type (or dojoType). For backwards compatibility
+ // reasons defaults to dojo._scopeName (which is "dojo" except when
+ // multi-version support is used, when it will be something like dojo16, dojo20, etc.)
+ // * propsThis: Object
+ // If specified, "this" referenced from data-dojo-props will refer to propsThis.
+ // Intended for use from the widgets-in-template feature of `dijit._Templated`
+ //
+ // example:
+ // Parse all widgets on a page:
+ // | dojo.parser.parse();
+ //
+ // example:
+ // Parse all classes within the node with id="foo"
+ // | dojo.parser.parse(dojo.byId('foo'));
+ //
+ // example:
+ // Parse all classes in a page, but do not call .startup() on any
+ // child
+ // | dojo.parser.parse({ noStart: true })
+ //
+ // example:
+ // Parse all classes in a node, but do not call .startup()
+ // | dojo.parser.parse(someNode, { noStart:true });
+ // | // or
+ // | dojo.parser.parse({ noStart:true, rootNode: someNode });
+
+ // determine the root node based on the passed arguments.
+ var root;
+ if(!args && rootNode && rootNode.rootNode){
+ args = rootNode;
+ root = args.rootNode;
+ }else{
+ root = rootNode;
+ }
+ args = args || {};
+
+ var attrName = (args.scope || d._scopeName) + "Type", // typically "dojoType"
+ attrData = "data-" + (args.scope || d._scopeName) + "-"; // typically "data-dojo-"
+
+ function scan(parent, list){
+ // summary:
+ // Parent is an Object representing a DOMNode, with or without a dojoType specified.
+ // Scan parent's children looking for nodes with dojoType specified, storing in list[].
+ // If parent has a dojoType, also collects <script type=dojo/*> children and stores in parent.scripts[].
+ // parent: Object
+ // Object representing the parent node, like
+ // | {
+ // | node: DomNode, // scan children of this node
+ // | inherited: {dir: "rtl"}, // dir/lang setting inherited from above node
+ // |
+ // | // attributes only set if node has dojoType specified
+ // | scripts: [], // empty array, put <script type=dojo/*> in here
+ // | clsInfo: { cls: dijit.form.Button, ...}
+ // | }
+ // list: DomNode[]
+ // Output array of objects (same format as parent) representing nodes to be turned into widgets
+
+ // Effective dir and lang settings on parent node, either set directly or inherited from grandparent
+ var inherited = dojo.clone(parent.inherited);
+ dojo.forEach(["dir", "lang"], function(name){
+ // TODO: what if this is a widget and dir/lang are declared in data-dojo-props?
+ var val = parent.node.getAttribute(name);
+ if(val){
+ inherited[name] = val;
+ }
+ });
+
+ // if parent is a widget, then search for <script type=dojo/*> tags and put them in scripts[].
+ var scripts = parent.clsInfo && !parent.clsInfo.cls.prototype._noScript ? parent.scripts : null;
+
+ // unless parent is a widget with the stopParser flag set, continue search for dojoType, recursively
+ var recurse = (!parent.clsInfo || !parent.clsInfo.cls.prototype.stopParser) || (args && args.template);
+
+ // scan parent's children looking for dojoType and <script type=dojo/*>
+ for(var child = parent.node.firstChild; child; child = child.nextSibling){
+ if(child.nodeType == 1){
+ // FIXME: desupport dojoType in 2.0. use data-dojo-type instead
+ var type, html5 = recurse && child.getAttribute(attrData + "type");
+ if(html5){
+ type = html5;
+ }else{
+ // fallback to backward compatible mode, using dojoType. remove in 2.0
+ type = recurse && child.getAttribute(attrName);
+ }
+
+ var fastpath = html5 == type;
+
+ if(type){
+ // if dojoType/data-dojo-type specified, add to output array of nodes to instantiate
+ var params = {
+ "type": type,
+ fastpath: fastpath,
+ clsInfo: getClassInfo(type, fastpath), // note: won't find classes declared via dojo.Declaration
+ node: child,
+ scripts: [], // <script> nodes that are parent's children
+ inherited: inherited // dir & lang attributes inherited from parent
+ };
+ list.push(params);
+
+ // Recurse, collecting <script type="dojo/..."> children, and also looking for
+ // descendant nodes with dojoType specified (unless the widget has the stopParser flag),
+ scan(params, list);
+ }else if(scripts && child.nodeName.toLowerCase() == "script"){
+ // if <script type="dojo/...">, save in scripts[]
+ type = child.getAttribute("type");
+ if (type && /^dojo\/\w/i.test(type)) {
+ scripts.push(child);
+ }
+ }else if(recurse){
+ // Recurse, looking for grandchild nodes with dojoType specified
+ scan({
+ node: child,
+ inherited: inherited
+ }, list);
+ }
+ }
+ }
+ }
+
+ // Make list of all nodes on page w/dojoType specified
+ var list = [];
+ scan({
+ node: root ? dojo.byId(root) : dojo.body(),
+ inherited: (args && args.inherited) || {
+ dir: dojo._isBodyLtr() ? "ltr" : "rtl"
+ }
+ }, list);
+
+ // go build the object instances
+ var mixin = args && args.template ? {template: true} : null;
+ return this.instantiate(list, mixin, args); // Array
+ };
+}();
+
+//Register the parser callback. It should be the first callback
+//after the a11y test.
+
+(function(){
+ var parseRunner = function(){
+ if(dojo.config.parseOnLoad){
+ dojo.parser.parse();
+ }
+ };
+
+ // FIXME: need to clobber cross-dependency!!
+ if(dojo.getObject("dijit.wai.onload") === dojo._loaders[0]){
+ dojo._loaders.splice(1, 0, parseRunner);
+ }else{
+ dojo._loaders.unshift(parseRunner);
+ }
+})();
+
+}
+
+if(!dojo._hasResource["dojo.Stateful"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.Stateful"] = true;
+dojo.provide("dojo.Stateful");
+
+
+
+dojo.declare("dojo.Stateful", null, {
+ // summary:
+ // Base class for objects that provide named properties with optional getter/setter
+ // control and the ability to watch for property changes
+ // example:
+ // | var obj = new dojo.Stateful();
+ // | obj.watch("foo", function(){
+ // | console.log("foo changed to " + this.get("foo"));
+ // | });
+ // | obj.set("foo","bar");
+ postscript: function(mixin){
+ if(mixin){
+ dojo.mixin(this, mixin);
+ }
+ },
+
+ get: function(/*String*/name){
+ // summary:
+ // Get a property on a Stateful instance.
+ // name:
+ // The property to get.
+ // description:
+ // Get a named property on a Stateful object. The property may
+ // potentially be retrieved via a getter method in subclasses. In the base class
+ // this just retrieves the object's property.
+ // For example:
+ // | stateful = new dojo.Stateful({foo: 3});
+ // | stateful.get("foo") // returns 3
+ // | stateful.foo // returns 3
+
+ return this[name];
+ },
+ set: function(/*String*/name, /*Object*/value){
+ // summary:
+ // Set a property on a Stateful instance
+ // name:
+ // The property to set.
+ // value:
+ // The value to set in the property.
+ // description:
+ // Sets named properties on a stateful object and notifies any watchers of
+ // the property. A programmatic setter may be defined in subclasses.
+ // For example:
+ // | stateful = new dojo.Stateful();
+ // | stateful.watch(function(name, oldValue, value){
+ // | // this will be called on the set below
+ // | }
+ // | stateful.set(foo, 5);
+ //
+ // 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 x in name){
+ this.set(x, name[x]);
+ }
+ return this;
+ }
+ var oldValue = this[name];
+ this[name] = value;
+ if(this._watchCallbacks){
+ this._watchCallbacks(name, oldValue, value);
+ }
+ return this;
+ },
+ watch: function(/*String?*/name, /*Function*/callback){
+ // summary:
+ // Watches a property for changes
+ // name:
+ // Indicates the property to watch. This is optional (the callback may be the
+ // only parameter), and if omitted, all the properties will be watched
+ // returns:
+ // An object handle for the watch. The unwatch method of this object
+ // can be used to discontinue watching this property:
+ // | var watchHandle = obj.watch("foo", callback);
+ // | watchHandle.unwatch(); // callback won't be called now
+ // callback:
+ // The function to execute when the property changes. This will be called after
+ // the property has been changed. The callback will be called with the |this|
+ // set to the instance, the first argument as the name of the property, the
+ // second argument as the old value and the third argument as the new value.
+
+ var callbacks = this._watchCallbacks;
+ if(!callbacks){
+ var self = this;
+ callbacks = this._watchCallbacks = function(name, oldValue, value, ignoreCatchall){
+ var notify = function(propertyCallbacks){
+ if(propertyCallbacks){
+ propertyCallbacks = propertyCallbacks.slice();
+ for(var i = 0, l = propertyCallbacks.length; i < l; i++){
+ try{
+ propertyCallbacks[i].call(self, name, oldValue, value);
+ }catch(e){
+ console.error(e);
+ }
+ }
+ }
+ };
+ notify(callbacks['_' + name]);
+ if(!ignoreCatchall){
+ notify(callbacks["*"]); // the catch-all
+ }
+ }; // we use a function instead of an object so it will be ignored by JSON conversion
+ }
+ if(!callback && typeof name === "function"){
+ callback = name;
+ name = "*";
+ }else{
+ // prepend with dash to prevent name conflicts with function (like "name" property)
+ name = '_' + name;
+ }
+ var propertyCallbacks = callbacks[name];
+ if(typeof propertyCallbacks !== "object"){
+ propertyCallbacks = callbacks[name] = [];
+ }
+ propertyCallbacks.push(callback);
+ return {
+ unwatch: function(){
+ propertyCallbacks.splice(dojo.indexOf(propertyCallbacks, callback), 1);
+ }
+ };
+ }
+
+});
+
+}
+
+if(!dojo._hasResource["dijit._WidgetBase"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._WidgetBase"] = true;
+dojo.provide("dijit._WidgetBase");
+
+
+
+
+
+(function(){
+
+dojo.declare("dijit._WidgetBase", dojo.Stateful, {
+ // summary:
+ // Future base class for all Dijit widgets.
+ // _Widget extends this class adding support for various features needed by desktop.
+
+ // id: [const] String
+ // A unique, opaque ID string that can be assigned by users or by the
+ // system. If the developer passes an ID which is known not to be
+ // unique, the specified ID is ignored and the system-generated ID is
+ // used instead.
+ id: "",
+
+ // lang: [const] String
+ // Rarely used. Overrides the default Dojo locale used to render this widget,
+ // as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute.
+ // Value must be among the list of locales specified during by the Dojo bootstrap,
+ // formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us).
+ lang: "",
+
+ // dir: [const] String
+ // Bi-directional support, as defined by the [HTML DIR](http://www.w3.org/TR/html401/struct/dirlang.html#adef-dir)
+ // attribute. Either left-to-right "ltr" or right-to-left "rtl". If undefined, widgets renders in page's
+ // default direction.
+ dir: "",
+
+ // class: String
+ // HTML class attribute
+ "class": "",
+
+ // style: String||Object
+ // HTML style attributes as cssText string or name/value hash
+ style: "",
+
+ // title: String
+ // HTML title attribute.
+ //
+ // For form widgets this specifies a tooltip to display when hovering over
+ // the widget (just like the native HTML title attribute).
+ //
+ // For TitlePane or for when this widget is a child of a TabContainer, AccordionContainer,
+ // etc., it's used to specify the tab label, accordion pane title, etc.
+ title: "",
+
+ // tooltip: String
+ // When this widget's title attribute is used to for a tab label, accordion pane title, etc.,
+ // this specifies the tooltip to appear when the mouse is hovered over that text.
+ tooltip: "",
+
+ // baseClass: [protected] String
+ // Root CSS class of the widget (ex: dijitTextBox), used to construct CSS classes to indicate
+ // widget state.
+ baseClass: "",
+
+ // srcNodeRef: [readonly] DomNode
+ // pointer to original DOM node
+ srcNodeRef: null,
+
+ // domNode: [readonly] DomNode
+ // This is our visible representation of the widget! Other DOM
+ // Nodes may by assigned to other properties, usually through the
+ // template system's dojoAttachPoint syntax, but the domNode
+ // property is the canonical "top level" node in widget UI.
+ domNode: null,
+
+ // containerNode: [readonly] DomNode
+ // Designates where children of the source DOM node will be placed.
+ // "Children" in this case refers to both DOM nodes and widgets.
+ // For example, for myWidget:
+ //
+ // | <div dojoType=myWidget>
+ // | <b> here's a plain DOM node
+ // | <span dojoType=subWidget>and a widget</span>
+ // | <i> and another plain DOM node </i>
+ // | </div>
+ //
+ // containerNode would point to:
+ //
+ // | <b> here's a plain DOM node
+ // | <span dojoType=subWidget>and a widget</span>
+ // | <i> and another plain DOM node </i>
+ //
+ // In templated widgets, "containerNode" is set via a
+ // dojoAttachPoint assignment.
+ //
+ // containerNode must be defined for any widget that accepts innerHTML
+ // (like ContentPane or BorderContainer or even Button), and conversely
+ // is null for widgets that don't, like TextBox.
+ containerNode: null,
+
+/*=====
+ // _started: Boolean
+ // startup() has completed.
+ _started: false,
+=====*/
+
+ // attributeMap: [protected] Object
+ // attributeMap sets up a "binding" between attributes (aka properties)
+ // of the widget and the widget's DOM.
+ // Changes to widget attributes listed in attributeMap will be
+ // reflected into the DOM.
+ //
+ // For example, calling set('title', 'hello')
+ // on a TitlePane will automatically cause the TitlePane's DOM to update
+ // with the new title.
+ //
+ // attributeMap is a hash where the key is an attribute of the widget,
+ // and the value reflects a binding to a:
+ //
+ // - DOM node attribute
+ // | focus: {node: "focusNode", type: "attribute"}
+ // Maps this.focus to this.focusNode.focus
+ //
+ // - DOM node innerHTML
+ // | title: { node: "titleNode", type: "innerHTML" }
+ // Maps this.title to this.titleNode.innerHTML
+ //
+ // - DOM node innerText
+ // | title: { node: "titleNode", type: "innerText" }
+ // Maps this.title to this.titleNode.innerText
+ //
+ // - DOM node CSS class
+ // | myClass: { node: "domNode", type: "class" }
+ // Maps this.myClass to this.domNode.className
+ //
+ // If the value is an array, then each element in the array matches one of the
+ // formats of the above list.
+ //
+ // There are also some shorthands for backwards compatibility:
+ // - string --> { node: string, type: "attribute" }, for example:
+ // | "focusNode" ---> { node: "focusNode", type: "attribute" }
+ // - "" --> { node: "domNode", type: "attribute" }
+ attributeMap: {id:"", dir:"", lang:"", "class":"", style:"", title:""},
+
+ // _blankGif: [protected] String
+ // Path to a blank 1x1 image.
+ // Used by <img> nodes in templates that really get their image via CSS background-image.
+ _blankGif: (dojo.config.blankGif || dojo.moduleUrl("dojo", "resources/blank.gif")).toString(),
+
+ //////////// INITIALIZATION METHODS ///////////////////////////////////////
+
+ postscript: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){
+ // summary:
+ // Kicks off widget instantiation. See create() for details.
+ // tags:
+ // private
+ this.create(params, srcNodeRef);
+ },
+
+ create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
+ // summary:
+ // Kick off the life-cycle of a widget
+ // params:
+ // Hash of initialization parameters for widget, including
+ // scalar values (like title, duration etc.) and functions,
+ // typically callbacks like onClick.
+ // srcNodeRef:
+ // If a srcNodeRef (DOM node) is specified:
+ // - use srcNodeRef.innerHTML as my contents
+ // - if this is a behavioral widget then apply behavior
+ // to that srcNodeRef
+ // - otherwise, replace srcNodeRef with my generated DOM
+ // tree
+ // description:
+ // Create calls a number of widget methods (postMixInProperties, buildRendering, postCreate,
+ // etc.), some of which of you'll want to override. See http://docs.dojocampus.org/dijit/_Widget
+ // for a discussion of the widget creation lifecycle.
+ //
+ // Of course, adventurous developers could override create entirely, but this should
+ // only be done as a last resort.
+ // tags:
+ // private
+
+ // store pointer to original DOM tree
+ this.srcNodeRef = dojo.byId(srcNodeRef);
+
+ // For garbage collection. An array of handles returned by Widget.connect()
+ // Each handle returned from Widget.connect() is an array of handles from dojo.connect()
+ this._connects = [];
+
+ // For garbage collection. An array of handles returned by Widget.subscribe()
+ // The handle returned from Widget.subscribe() is the handle returned from dojo.subscribe()
+ this._subscribes = [];
+
+ // mix in our passed parameters
+ if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){ this.id = this.srcNodeRef.id; }
+ if(params){
+ this.params = params;
+ dojo._mixin(this, params);
+ }
+ this.postMixInProperties();
+
+ // generate an id for the widget if one wasn't specified
+ // (be sure to do this before buildRendering() because that function might
+ // expect the id to be there.)
+ if(!this.id){
+ this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
+ }
+ dijit.registry.add(this);
+
+ this.buildRendering();
+
+ if(this.domNode){
+ // Copy attributes listed in attributeMap into the [newly created] DOM for the widget.
+ // Also calls custom setters for all attributes with custom setters.
+ this._applyAttributes();
+
+ // If srcNodeRef was specified, then swap out original srcNode for this widget's DOM tree.
+ // For 2.0, move this after postCreate(). postCreate() shouldn't depend on the
+ // widget being attached to the DOM since it isn't when a widget is created programmatically like
+ // new MyWidget({}). See #11635.
+ var source = this.srcNodeRef;
+ if(source && source.parentNode && this.domNode !== source){
+ source.parentNode.replaceChild(this.domNode, source);
+ }
+ }
+
+ if(this.domNode){
+ // Note: for 2.0 may want to rename widgetId to dojo._scopeName + "_widgetId",
+ // assuming that dojo._scopeName even exists in 2.0
+ this.domNode.setAttribute("widgetId", this.id);
+ }
+ this.postCreate();
+
+ // If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC.
+ if(this.srcNodeRef && !this.srcNodeRef.parentNode){
+ delete this.srcNodeRef;
+ }
+
+ this._created = true;
+ },
+
+ _applyAttributes: function(){
+ // summary:
+ // Step during widget creation to copy all widget attributes to the
+ // DOM as per attributeMap and _setXXXAttr functions.
+ // description:
+ // Skips over blank/false attribute values, unless they were explicitly specified
+ // as parameters to the widget, since those are the default anyway,
+ // and setting tabIndex="" is different than not setting tabIndex at all.
+ //
+ // It processes the attributes in the attribute map first, and then
+ // it goes through and processes the attributes for the _setXXXAttr
+ // functions that have been specified
+ // tags:
+ // private
+ var condAttrApply = function(attr, scope){
+ if((scope.params && attr in scope.params) || scope[attr]){
+ scope.set(attr, scope[attr]);
+ }
+ };
+
+ // Do the attributes in attributeMap
+ for(var attr in this.attributeMap){
+ condAttrApply(attr, this);
+ }
+
+ // And also any attributes with custom setters
+ dojo.forEach(this._getSetterAttributes(), function(a){
+ if(!(a in this.attributeMap)){
+ condAttrApply(a, this);
+ }
+ }, this);
+ },
+
+ _getSetterAttributes: function(){
+ // summary:
+ // Returns list of attributes with custom setters for this widget
+ var ctor = this.constructor;
+ if(!ctor._setterAttrs){
+ var r = (ctor._setterAttrs = []),
+ attrs,
+ proto = ctor.prototype;
+ for(var fxName in proto){
+ if(dojo.isFunction(proto[fxName]) && (attrs = fxName.match(/^_set([a-zA-Z]*)Attr$/)) && attrs[1]){
+ r.push(attrs[1].charAt(0).toLowerCase() + attrs[1].substr(1));
+ }
+ }
+ }
+ return ctor._setterAttrs; // String[]
+ },
+
+ postMixInProperties: function(){
+ // summary:
+ // Called after the parameters to the widget have been read-in,
+ // but before the widget template is instantiated. Especially
+ // useful to set properties that are referenced in the widget
+ // template.
+ // tags:
+ // protected
+ },
+
+ buildRendering: function(){
+ // summary:
+ // Construct the UI for this widget, setting this.domNode
+ // description:
+ // Most widgets will mixin `dijit._Templated`, which implements this
+ // method.
+ // tags:
+ // protected
+
+ if(!this.domNode){
+ // Create root node if it wasn't created by _Templated
+ this.domNode = this.srcNodeRef || dojo.create('div');
+ }
+
+ // baseClass is a single class name or occasionally a space-separated list of names.
+ // Add those classes to the DOMNode. If RTL mode then also add with Rtl suffix.
+ // TODO: make baseClass custom setter
+ if(this.baseClass){
+ var classes = this.baseClass.split(" ");
+ if(!this.isLeftToRight()){
+ classes = classes.concat( dojo.map(classes, function(name){ return name+"Rtl"; }));
+ }
+ dojo.addClass(this.domNode, classes);
+ }
+ },
+
+ postCreate: function(){
+ // summary:
+ // Processing after the DOM fragment is created
+ // description:
+ // Called after the DOM fragment has been created, but not necessarily
+ // added to the document. Do not include any operations which rely on
+ // node dimensions or placement.
+ // tags:
+ // protected
+ },
+
+ startup: function(){
+ // summary:
+ // Processing after the DOM fragment is added to the document
+ // description:
+ // Called after a widget and its children have been created and added to the page,
+ // and all related widgets have finished their create() cycle, up through postCreate().
+ // This is useful for composite widgets that need to control or layout sub-widgets.
+ // Many layout widgets can use this as a wiring phase.
+ this._started = true;
+ },
+
+ //////////// DESTROY FUNCTIONS ////////////////////////////////
+
+ destroyRecursive: function(/*Boolean?*/ preserveDom){
+ // summary:
+ // Destroy this widget and its descendants
+ // description:
+ // This is the generic "destructor" function that all widget users
+ // should call to cleanly discard with a widget. Once a widget is
+ // destroyed, it is removed from the manager object.
+ // preserveDom:
+ // If true, this method will leave the original DOM structure
+ // alone of descendant Widgets. Note: This will NOT work with
+ // dijit._Templated widgets.
+
+ this._beingDestroyed = true;
+ this.destroyDescendants(preserveDom);
+ this.destroy(preserveDom);
+ },
+
+ destroy: function(/*Boolean*/ preserveDom){
+ // summary:
+ // Destroy this widget, but not its descendants.
+ // This method will, however, destroy internal widgets such as those used within a template.
+ // preserveDom: Boolean
+ // If true, this method will leave the original DOM structure alone.
+ // Note: This will not yet work with _Templated widgets
+
+ this._beingDestroyed = true;
+ this.uninitialize();
+ var d = dojo,
+ dfe = d.forEach,
+ dun = d.unsubscribe;
+ dfe(this._connects, function(array){
+ dfe(array, d.disconnect);
+ });
+ dfe(this._subscribes, function(handle){
+ dun(handle);
+ });
+
+ // destroy widgets created as part of template, etc.
+ dfe(this._supportingWidgets || [], function(w){
+ if(w.destroyRecursive){
+ w.destroyRecursive();
+ }else if(w.destroy){
+ w.destroy();
+ }
+ });
+
+ this.destroyRendering(preserveDom);
+ dijit.registry.remove(this.id);
+ this._destroyed = true;
+ },
+
+ destroyRendering: function(/*Boolean?*/ preserveDom){
+ // summary:
+ // Destroys the DOM nodes associated with this widget
+ // preserveDom:
+ // If true, this method will leave the original DOM structure alone
+ // during tear-down. Note: this will not work with _Templated
+ // widgets yet.
+ // tags:
+ // protected
+
+ if(this.bgIframe){
+ this.bgIframe.destroy(preserveDom);
+ delete this.bgIframe;
+ }
+
+ if(this.domNode){
+ if(preserveDom){
+ dojo.removeAttr(this.domNode, "widgetId");
+ }else{
+ dojo.destroy(this.domNode);
+ }
+ delete this.domNode;
+ }
+
+ if(this.srcNodeRef){
+ if(!preserveDom){
+ dojo.destroy(this.srcNodeRef);
+ }
+ delete this.srcNodeRef;
+ }
+ },
+
+ destroyDescendants: function(/*Boolean?*/ preserveDom){
+ // summary:
+ // Recursively destroy the children of this widget and their
+ // descendants.
+ // preserveDom:
+ // If true, the preserveDom attribute is passed to all descendant
+ // widget's .destroy() method. Not for use with _Templated
+ // widgets.
+
+ // get all direct descendants and destroy them recursively
+ dojo.forEach(this.getChildren(), function(widget){
+ if(widget.destroyRecursive){
+ widget.destroyRecursive(preserveDom);
+ }
+ });
+ },
+
+ uninitialize: function(){
+ // summary:
+ // Stub function. Override to implement custom widget tear-down
+ // behavior.
+ // tags:
+ // protected
+ return false;
+ },
+
+ ////////////////// GET/SET, CUSTOM SETTERS, ETC. ///////////////////
+
+ _setClassAttr: function(/*String*/ value){
+ // summary:
+ // Custom setter for the CSS "class" attribute
+ // tags:
+ // protected
+ var mapNode = this[this.attributeMap["class"] || 'domNode'];
+ dojo.replaceClass(mapNode, value, this["class"]);
+ this._set("class", value);
+ },
+
+ _setStyleAttr: function(/*String||Object*/ value){
+ // summary:
+ // Sets the style attribute of the widget according to value,
+ // which is either a hash like {height: "5px", width: "3px"}
+ // or a plain string
+ // description:
+ // Determines which node to set the style on based on style setting
+ // in attributeMap.
+ // tags:
+ // protected
+
+ var mapNode = this[this.attributeMap.style || 'domNode'];
+
+ // Note: technically we should revert any style setting made in a previous call
+ // to his method, but that's difficult to keep track of.
+
+ if(dojo.isObject(value)){
+ dojo.style(mapNode, value);
+ }else{
+ if(mapNode.style.cssText){
+ mapNode.style.cssText += "; " + value;
+ }else{
+ mapNode.style.cssText = value;
+ }
+ }
+
+ this._set("style", value);
+ },
+
+ _attrToDom: function(/*String*/ attr, /*String*/ value){
+ // summary:
+ // Reflect a widget attribute (title, tabIndex, duration etc.) to
+ // the widget DOM, as specified in attributeMap.
+ // Note some attributes like "type"
+ // cannot be processed this way as they are not mutable.
+ //
+ // tags:
+ // private
+
+ var commands = this.attributeMap[attr];
+ dojo.forEach(dojo.isArray(commands) ? commands : [commands], function(command){
+
+ // Get target node and what we are doing to that node
+ var mapNode = this[command.node || command || "domNode"]; // DOM node
+ var type = command.type || "attribute"; // class, innerHTML, innerText, or attribute
+
+ switch(type){
+ case "attribute":
+ if(dojo.isFunction(value)){ // functions execute in the context of the widget
+ value = dojo.hitch(this, value);
+ }
+
+ // Get the name of the DOM node attribute; usually it's the same
+ // as the name of the attribute in the widget (attr), but can be overridden.
+ // Also maps handler names to lowercase, like onSubmit --> onsubmit
+ var attrName = command.attribute ? command.attribute :
+ (/^on[A-Z][a-zA-Z]*$/.test(attr) ? attr.toLowerCase() : attr);
+
+ dojo.attr(mapNode, attrName, value);
+ break;
+ case "innerText":
+ mapNode.innerHTML = "";
+ mapNode.appendChild(dojo.doc.createTextNode(value));
+ break;
+ case "innerHTML":
+ mapNode.innerHTML = value;
+ break;
+ case "class":
+ dojo.replaceClass(mapNode, value, this[attr]);
+ break;
+ }
+ }, this);
+ },
+
+ get: function(name){
+ // summary:
+ // Get a property from a widget.
+ // name:
+ // The property to get.
+ // description:
+ // Get a named property from a widget. The property may
+ // potentially be retrieved via a getter method. If no getter is defined, this
+ // just retrieves the object's property.
+ // For example, if the widget has a properties "foo"
+ // and "bar" and a method named "_getFooAttr", calling:
+ // | myWidget.get("foo");
+ // would be equivalent to writing:
+ // | widget._getFooAttr();
+ // and:
+ // | myWidget.get("bar");
+ // would be equivalent to writing:
+ // | widget.bar;
+ var names = this._getAttrNames(name);
+ return this[names.g] ? this[names.g]() : this[name];
+ },
+
+ set: function(name, value){
+ // summary:
+ // Set a property on a widget
+ // name:
+ // The property to set.
+ // value:
+ // The value to set in the property.
+ // description:
+ // Sets named properties on a widget which may potentially be handled by a
+ // setter in the widget.
+ // For example, if the widget has a properties "foo"
+ // and "bar" and a method named "_setFooAttr", calling:
+ // | myWidget.set("foo", "Howdy!");
+ // would be equivalent to writing:
+ // | widget._setFooAttr("Howdy!");
+ // and:
+ // | myWidget.set("bar", 3);
+ // would be equivalent to writing:
+ // | widget.bar = 3;
+ //
+ // set() may also be called with a hash of name/value pairs, ex:
+ // | myWidget.set({
+ // | foo: "Howdy",
+ // | bar: 3
+ // | })
+ // This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
+
+ if(typeof name === "object"){
+ for(var x in name){
+ this.set(x, name[x]);
+ }
+ return this;
+ }
+ var names = this._getAttrNames(name);
+ if(this[names.s]){
+ // use the explicit setter
+ var result = this[names.s].apply(this, Array.prototype.slice.call(arguments, 1));
+ }else{
+ // if param is specified as DOM node attribute, copy it
+ if(name in this.attributeMap){
+ this._attrToDom(name, value);
+ }
+ this._set(name, value);
+ }
+ return result || this;
+ },
+
+ _attrPairNames: {}, // shared between all widgets
+ _getAttrNames: function(name){
+ // summary:
+ // Helper function for get() and set().
+ // Caches attribute name values so we don't do the string ops every time.
+ // tags:
+ // private
+
+ var apn = this._attrPairNames;
+ if(apn[name]){ return apn[name]; }
+ var uc = name.charAt(0).toUpperCase() + name.substr(1);
+ return (apn[name] = {
+ n: name+"Node",
+ s: "_set"+uc+"Attr",
+ g: "_get"+uc+"Attr"
+ });
+ },
+
+ _set: function(/*String*/ name, /*anything*/ value){
+ // summary:
+ // Helper function to set new value for specified attribute, and call handlers
+ // registered with watch() if the value has changed.
+ var oldValue = this[name];
+ this[name] = value;
+ if(this._watchCallbacks && this._created && value !== oldValue){
+ this._watchCallbacks(name, oldValue, value);
+ }
+ },
+
+ toString: function(){
+ // summary:
+ // Returns a string that represents the widget
+ // description:
+ // When a widget is cast to a string, this method will be used to generate the
+ // output. Currently, it does not implement any sort of reversible
+ // serialization.
+ return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
+ },
+
+ getDescendants: function(){
+ // summary:
+ // Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
+ // This method should generally be avoided as it returns widgets declared in templates, which are
+ // supposed to be internal/hidden, but it's left here for back-compat reasons.
+
+ return this.containerNode ? dojo.query('[widgetId]', this.containerNode).map(dijit.byNode) : []; // dijit._Widget[]
+ },
+
+ getChildren: function(){
+ // summary:
+ // Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
+ // Does not return nested widgets, nor widgets that are part of this widget's template.
+ return this.containerNode ? dijit.findWidgets(this.containerNode) : []; // dijit._Widget[]
+ },
+
+ connect: function(
+ /*Object|null*/ obj,
+ /*String|Function*/ event,
+ /*String|Function*/ method){
+ // summary:
+ // Connects specified obj/event to specified method of this object
+ // and registers for disconnect() on widget destroy.
+ // description:
+ // Provide widget-specific analog to dojo.connect, except with the
+ // implicit use of this widget as the target object.
+ // Events connected with `this.connect` are disconnected upon
+ // destruction.
+ // returns:
+ // A handle that can be passed to `disconnect` in order to disconnect before
+ // the widget is destroyed.
+ // example:
+ // | var btn = new dijit.form.Button();
+ // | // when foo.bar() is called, call the listener we're going to
+ // | // provide in the scope of btn
+ // | btn.connect(foo, "bar", function(){
+ // | console.debug(this.toString());
+ // | });
+ // tags:
+ // protected
+
+ var handles = [dojo._connect(obj, event, this, method)];
+ this._connects.push(handles);
+ return handles; // _Widget.Handle
+ },
+
+ disconnect: function(/* _Widget.Handle */ handles){
+ // summary:
+ // Disconnects handle created by `connect`.
+ // Also removes handle from this widget's list of connects.
+ // tags:
+ // protected
+ for(var i=0; i<this._connects.length; i++){
+ if(this._connects[i] == handles){
+ dojo.forEach(handles, dojo.disconnect);
+ this._connects.splice(i, 1);
+ return;
+ }
+ }
+ },
+
+ subscribe: function(
+ /*String*/ topic,
+ /*String|Function*/ method){
+ // summary:
+ // Subscribes to the specified topic and calls the specified method
+ // of this object and registers for unsubscribe() on widget destroy.
+ // description:
+ // Provide widget-specific analog to dojo.subscribe, except with the
+ // implicit use of this widget as the target object.
+ // example:
+ // | var btn = new dijit.form.Button();
+ // | // when /my/topic is published, this button changes its label to
+ // | // be the parameter of the topic.
+ // | btn.subscribe("/my/topic", function(v){
+ // | this.set("label", v);
+ // | });
+ var handle = dojo.subscribe(topic, this, method);
+
+ // return handles for Any widget that may need them
+ this._subscribes.push(handle);
+ return handle;
+ },
+
+ unsubscribe: function(/*Object*/ handle){
+ // summary:
+ // Unsubscribes handle created by this.subscribe.
+ // Also removes handle from this widget's list of subscriptions
+ for(var i=0; i<this._subscribes.length; i++){
+ if(this._subscribes[i] == handle){
+ dojo.unsubscribe(handle);
+ this._subscribes.splice(i, 1);
+ return;
+ }
+ }
+ },
+
+ isLeftToRight: function(){
+ // summary:
+ // Return this widget's explicit or implicit orientation (true for LTR, false for RTL)
+ // tags:
+ // protected
+ return this.dir ? (this.dir == "ltr") : dojo._isBodyLtr(); //Boolean
+ },
+
+ placeAt: function(/* String|DomNode|_Widget */reference, /* String?|Int? */position){
+ // summary:
+ // Place this widget's domNode reference somewhere in the DOM based
+ // on standard dojo.place conventions, or passing a Widget reference that
+ // contains and addChild member.
+ //
+ // description:
+ // A convenience function provided in all _Widgets, providing a simple
+ // shorthand mechanism to put an existing (or newly created) Widget
+ // somewhere in the dom, and allow chaining.
+ //
+ // reference:
+ // The String id of a domNode, a domNode reference, or a reference to a Widget posessing
+ // an addChild method.
+ //
+ // position:
+ // If passed a string or domNode reference, the position argument
+ // accepts a string just as dojo.place does, one of: "first", "last",
+ // "before", or "after".
+ //
+ // If passed a _Widget reference, and that widget reference has an ".addChild" method,
+ // it will be called passing this widget instance into that method, supplying the optional
+ // position index passed.
+ //
+ // returns:
+ // dijit._Widget
+ // Provides a useful return of the newly created dijit._Widget instance so you
+ // can "chain" this function by instantiating, placing, then saving the return value
+ // to a variable.
+ //
+ // example:
+ // | // create a Button with no srcNodeRef, and place it in the body:
+ // | var button = new dijit.form.Button({ label:"click" }).placeAt(dojo.body());
+ // | // now, 'button' is still the widget reference to the newly created button
+ // | dojo.connect(button, "onClick", function(e){ console.log('click'); });
+ //
+ // example:
+ // | // create a button out of a node with id="src" and append it to id="wrapper":
+ // | var button = new dijit.form.Button({},"src").placeAt("wrapper");
+ //
+ // example:
+ // | // place a new button as the first element of some div
+ // | var button = new dijit.form.Button({ label:"click" }).placeAt("wrapper","first");
+ //
+ // example:
+ // | // create a contentpane and add it to a TabContainer
+ // | var tc = dijit.byId("myTabs");
+ // | new dijit.layout.ContentPane({ href:"foo.html", title:"Wow!" }).placeAt(tc)
+
+ if(reference.declaredClass && reference.addChild){
+ reference.addChild(this, position);
+ }else{
+ dojo.place(this.domNode, reference, position);
+ }
+ return this;
+ }
+});
+
+})();
+
+}
+
+if(!dojo._hasResource["dijit._Widget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Widget"] = true;
+dojo.provide("dijit._Widget");
+
+
+
+
+
+
+////////////////// DEFERRED CONNECTS ///////////////////
+
+// This code is to assist deferring dojo.connect() calls in widgets (connecting to events on the widgets'
+// DOM nodes) until someone actually needs to monitor that event.
+dojo.connect(dojo, "_connect",
+ function(/*dijit._Widget*/ widget, /*String*/ event){
+ if(widget && dojo.isFunction(widget._onConnect)){
+ widget._onConnect(event);
+ }
+ });
+
+dijit._connectOnUseEventHandler = function(/*Event*/ event){};
+
+////////////////// ONDIJITCLICK SUPPORT ///////////////////
+
+// Keep track of where the last keydown event was, to help avoid generating
+// spurious ondijitclick events when:
+// 1. focus is on a <button> or <a>
+// 2. user presses then releases the ENTER key
+// 3. onclick handler fires and shifts focus to another node, with an ondijitclick handler
+// 4. onkeyup event fires, causing the ondijitclick handler to fire
+dijit._lastKeyDownNode = null;
+if(dojo.isIE){
+ (function(){
+ var keydownCallback = function(evt){
+ dijit._lastKeyDownNode = evt.srcElement;
+ };
+ dojo.doc.attachEvent('onkeydown', keydownCallback);
+ dojo.addOnWindowUnload(function(){
+ dojo.doc.detachEvent('onkeydown', keydownCallback);
+ });
+ })();
+}else{
+ dojo.doc.addEventListener('keydown', function(evt){
+ dijit._lastKeyDownNode = evt.target;
+ }, true);
+}
+
+(function(){
+
+dojo.declare("dijit._Widget", dijit._WidgetBase, {
+ // summary:
+ // Base class for all Dijit widgets.
+ //
+ // Extends _WidgetBase, adding support for:
+ // - deferred connections
+ // A call like dojo.connect(myWidget, "onMouseMove", func)
+ // will essentially do a dojo.connect(myWidget.domNode, "onMouseMove", func)
+ // - ondijitclick
+ // Support new dojoAttachEvent="ondijitclick: ..." that is triggered by a mouse click or a SPACE/ENTER keypress
+ // - focus related functions
+ // In particular, the onFocus()/onBlur() callbacks. Driven internally by
+ // dijit/_base/focus.js.
+ // - deprecated methods
+ // - onShow(), onHide(), onClose()
+ //
+ // Also, by loading code in dijit/_base, turns on:
+ // - browser sniffing (putting browser id like .dj_ie on <html> node)
+ // - high contrast mode sniffing (add .dijit_a11y class to <body> if machine is in high contrast mode)
+
+
+ ////////////////// DEFERRED CONNECTS ///////////////////
+
+ // _deferredConnects: [protected] Object
+ // attributeMap addendum for event handlers that should be connected only on first use
+ _deferredConnects: {
+ onClick: "",
+ onDblClick: "",
+ onKeyDown: "",
+ onKeyPress: "",
+ onKeyUp: "",
+ onMouseMove: "",
+ onMouseDown: "",
+ onMouseOut: "",
+ onMouseOver: "",
+ onMouseLeave: "",
+ onMouseEnter: "",
+ onMouseUp: ""
+ },
+
+ onClick: dijit._connectOnUseEventHandler,
+ /*=====
+ onClick: function(event){
+ // summary:
+ // Connect to this function to receive notifications of mouse click events.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onDblClick: dijit._connectOnUseEventHandler,
+ /*=====
+ onDblClick: function(event){
+ // summary:
+ // Connect to this function to receive notifications of mouse double click events.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onKeyDown: dijit._connectOnUseEventHandler,
+ /*=====
+ onKeyDown: function(event){
+ // summary:
+ // Connect to this function to receive notifications of keys being pressed down.
+ // event:
+ // key Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onKeyPress: dijit._connectOnUseEventHandler,
+ /*=====
+ onKeyPress: function(event){
+ // summary:
+ // Connect to this function to receive notifications of printable keys being typed.
+ // event:
+ // key Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onKeyUp: dijit._connectOnUseEventHandler,
+ /*=====
+ onKeyUp: function(event){
+ // summary:
+ // Connect to this function to receive notifications of keys being released.
+ // event:
+ // key Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseDown: dijit._connectOnUseEventHandler,
+ /*=====
+ onMouseDown: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse button is pressed down.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseMove: dijit._connectOnUseEventHandler,
+ /*=====
+ onMouseMove: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse moves over nodes contained within this widget.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseOut: dijit._connectOnUseEventHandler,
+ /*=====
+ onMouseOut: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse moves off of nodes contained within this widget.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseOver: dijit._connectOnUseEventHandler,
+ /*=====
+ onMouseOver: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse moves onto nodes contained within this widget.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseLeave: dijit._connectOnUseEventHandler,
+ /*=====
+ onMouseLeave: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse moves off of this widget.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseEnter: dijit._connectOnUseEventHandler,
+ /*=====
+ onMouseEnter: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse moves onto this widget.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseUp: dijit._connectOnUseEventHandler,
+ /*=====
+ onMouseUp: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse button is released.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+
+ create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
+ // To avoid double-connects, remove entries from _deferredConnects
+ // that have been setup manually by a subclass (ex, by dojoAttachEvent).
+ // If a subclass has redefined a callback (ex: onClick) then assume it's being
+ // connected to manually.
+ this._deferredConnects = dojo.clone(this._deferredConnects);
+ for(var attr in this.attributeMap){
+ delete this._deferredConnects[attr]; // can't be in both attributeMap and _deferredConnects
+ }
+ for(attr in this._deferredConnects){
+ if(this[attr] !== dijit._connectOnUseEventHandler){
+ delete this._deferredConnects[attr]; // redefined, probably dojoAttachEvent exists
+ }
+ }
+
+ this.inherited(arguments);
+
+ if(this.domNode){
+ // If the developer has specified a handler as a widget parameter
+ // (ex: new Button({onClick: ...})
+ // then naturally need to connect from DOM node to that handler immediately,
+ for(attr in this.params){
+ this._onConnect(attr);
+ }
+ }
+ },
+
+ _onConnect: function(/*String*/ event){
+ // summary:
+ // Called when someone connects to one of my handlers.
+ // "Turn on" that handler if it isn't active yet.
+ //
+ // This is also called for every single initialization parameter
+ // so need to do nothing for parameters like "id".
+ // tags:
+ // private
+ if(event in this._deferredConnects){
+ var mapNode = this[this._deferredConnects[event] || 'domNode'];
+ this.connect(mapNode, event.toLowerCase(), event);
+ delete this._deferredConnects[event];
+ }
+ },
+
+ ////////////////// FOCUS RELATED ///////////////////
+ // _onFocus() and _onBlur() are called by the focus manager
+
+ // focused: [readonly] Boolean
+ // This widget or a widget it contains has focus, or is "active" because
+ // it was recently clicked.
+ focused: false,
+
+ isFocusable: function(){
+ // summary:
+ // Return true if this widget can currently be focused
+ // and false if not
+ return this.focus && (dojo.style(this.domNode, "display") != "none");
+ },
+
+ onFocus: function(){
+ // summary:
+ // Called when the widget becomes "active" because
+ // it or a widget inside of it either has focus, or has recently
+ // been clicked.
+ // tags:
+ // callback
+ },
+
+ onBlur: function(){
+ // summary:
+ // Called when the widget stops being "active" because
+ // focus moved to something outside of it, or the user
+ // clicked somewhere outside of it, or the widget was
+ // hidden.
+ // tags:
+ // callback
+ },
+
+ _onFocus: function(e){
+ // summary:
+ // This is where widgets do processing for when they are active,
+ // such as changing CSS classes. See onFocus() for more details.
+ // tags:
+ // protected
+ this.onFocus();
+ },
+
+ _onBlur: function(){
+ // summary:
+ // This is where widgets do processing for when they stop being active,
+ // such as changing CSS classes. See onBlur() for more details.
+ // tags:
+ // protected
+ this.onBlur();
+ },
+
+ ////////////////// DEPRECATED METHODS ///////////////////
+
+ setAttribute: function(/*String*/ attr, /*anything*/ value){
+ // summary:
+ // Deprecated. Use set() instead.
+ // tags:
+ // deprecated
+ dojo.deprecated(this.declaredClass+"::setAttribute(attr, value) is deprecated. Use set() instead.", "", "2.0");
+ this.set(attr, value);
+ },
+
+ attr: function(/*String|Object*/name, /*Object?*/value){
+ // summary:
+ // Set or get properties on a widget instance.
+ // name:
+ // The property to get or set. If an object is passed here and not
+ // a string, its keys are used as names of attributes to be set
+ // and the value of the object as values to set in the widget.
+ // value:
+ // Optional. If provided, attr() operates as a setter. If omitted,
+ // the current value of the named property is returned.
+ // description:
+ // This method is deprecated, use get() or set() directly.
+
+ // Print deprecation warning but only once per calling function
+ if(dojo.config.isDebug){
+ var alreadyCalledHash = arguments.callee._ach || (arguments.callee._ach = {}),
+ caller = (arguments.callee.caller || "unknown caller").toString();
+ if(!alreadyCalledHash[caller]){
+ dojo.deprecated(this.declaredClass + "::attr() is deprecated. Use get() or set() instead, called from " +
+ caller, "", "2.0");
+ alreadyCalledHash[caller] = true;
+ }
+ }
+
+ var args = arguments.length;
+ if(args >= 2 || typeof name === "object"){ // setter
+ return this.set.apply(this, arguments);
+ }else{ // getter
+ return this.get(name);
+ }
+ },
+
+ ////////////////// ONDIJITCLICK SUPPORT ///////////////////
+
+ // nodesWithKeyClick: [private] String[]
+ // List of nodes that correctly handle click events via native browser support,
+ // and don't need dijit's help
+ nodesWithKeyClick: ["input", "button"],
+
+ connect: function(
+ /*Object|null*/ obj,
+ /*String|Function*/ event,
+ /*String|Function*/ method){
+ // summary:
+ // Connects specified obj/event to specified method of this object
+ // and registers for disconnect() on widget destroy.
+ // description:
+ // Provide widget-specific analog to dojo.connect, except with the
+ // implicit use of this widget as the target object.
+ // This version of connect also provides a special "ondijitclick"
+ // event which triggers on a click or space or enter keyup.
+ // Events connected with `this.connect` are disconnected upon
+ // destruction.
+ // returns:
+ // A handle that can be passed to `disconnect` in order to disconnect before
+ // the widget is destroyed.
+ // example:
+ // | var btn = new dijit.form.Button();
+ // | // when foo.bar() is called, call the listener we're going to
+ // | // provide in the scope of btn
+ // | btn.connect(foo, "bar", function(){
+ // | console.debug(this.toString());
+ // | });
+ // tags:
+ // protected
+
+ var d = dojo,
+ dc = d._connect,
+ handles = this.inherited(arguments, [obj, event == "ondijitclick" ? "onclick" : event, method]);
+
+ if(event == "ondijitclick"){
+ // add key based click activation for unsupported nodes.
+ // do all processing onkey up to prevent spurious clicks
+ // for details see comments at top of this file where _lastKeyDownNode is defined
+ if(d.indexOf(this.nodesWithKeyClick, obj.nodeName.toLowerCase()) == -1){ // is NOT input or button
+ var m = d.hitch(this, method);
+ handles.push(
+ dc(obj, "onkeydown", this, function(e){
+ //console.log(this.id + ": onkeydown, e.target = ", e.target, ", lastKeyDownNode was ", dijit._lastKeyDownNode, ", equality is ", (e.target === dijit._lastKeyDownNode));
+ if((e.keyCode == d.keys.ENTER || e.keyCode == d.keys.SPACE) &&
+ !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){
+ // needed on IE for when focus changes between keydown and keyup - otherwise dropdown menus do not work
+ dijit._lastKeyDownNode = e.target;
+
+ // Stop event to prevent scrolling on space key in IE.
+ // But don't do this for _HasDropDown because it surpresses the onkeypress
+ // event needed to open the drop down when the user presses the SPACE key.
+ if(!("openDropDown" in this && obj == this._buttonNode)){
+ e.preventDefault();
+ }
+ }
+ }),
+ dc(obj, "onkeyup", this, function(e){
+ //console.log(this.id + ": onkeyup, e.target = ", e.target, ", lastKeyDownNode was ", dijit._lastKeyDownNode, ", equality is ", (e.target === dijit._lastKeyDownNode));
+ if( (e.keyCode == d.keys.ENTER || e.keyCode == d.keys.SPACE) &&
+ e.target == dijit._lastKeyDownNode && // === breaks greasemonkey
+ !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){
+ //need reset here or have problems in FF when focus returns to trigger element after closing popup/alert
+ dijit._lastKeyDownNode = null;
+ return m(e);
+ }
+ })
+ );
+ }
+ }
+
+ return handles; // _Widget.Handle
+ },
+
+ ////////////////// MISCELLANEOUS METHODS ///////////////////
+
+ _onShow: function(){
+ // summary:
+ // Internal method called when this widget is made visible.
+ // See `onShow` for details.
+ this.onShow();
+ },
+
+ onShow: function(){
+ // summary:
+ // Called when this widget becomes the selected pane in a
+ // `dijit.layout.TabContainer`, `dijit.layout.StackContainer`,
+ // `dijit.layout.AccordionContainer`, etc.
+ //
+ // Also called to indicate display of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
+ // tags:
+ // callback
+ },
+
+ onHide: function(){
+ // summary:
+ // Called when another widget becomes the selected pane in a
+ // `dijit.layout.TabContainer`, `dijit.layout.StackContainer`,
+ // `dijit.layout.AccordionContainer`, etc.
+ //
+ // Also called to indicate hide of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
+ // tags:
+ // callback
+ },
+
+ onClose: function(){
+ // summary:
+ // Called when this widget is being displayed as a popup (ex: a Calendar popped
+ // up from a DateTextBox), and it is hidden.
+ // This is called from the dijit.popup code, and should not be called directly.
+ //
+ // Also used as a parameter for children of `dijit.layout.StackContainer` or subclasses.
+ // Callback if a user tries to close the child. Child will be closed if this function returns true.
+ // tags:
+ // extension
+
+ return true; // Boolean
+ }
+});
+
+})();
+
+}
+
+if(!dojo._hasResource["dojo.string"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.string"] = true;
+dojo.provide("dojo.string");
+
+
+dojo.getObject("string", true, dojo);
+
+/*=====
+dojo.string = {
+ // summary: String utilities for Dojo
+};
+=====*/
+
+dojo.string.rep = function(/*String*/str, /*Integer*/num){
+ // summary:
+ // Efficiently replicate a string `n` times.
+ // str:
+ // the string to replicate
+ // num:
+ // number of times to replicate the string
+
+ if(num <= 0 || !str){ return ""; }
+
+ var buf = [];
+ for(;;){
+ if(num & 1){
+ buf.push(str);
+ }
+ if(!(num >>= 1)){ break; }
+ str += str;
+ }
+ return buf.join(""); // String
+};
+
+dojo.string.pad = function(/*String*/text, /*Integer*/size, /*String?*/ch, /*Boolean?*/end){
+ // summary:
+ // Pad a string to guarantee that it is at least `size` length by
+ // filling with the character `ch` at either the start or end of the
+ // string. Pads at the start, by default.
+ // text:
+ // the string to pad
+ // size:
+ // length to provide padding
+ // ch:
+ // character to pad, defaults to '0'
+ // end:
+ // adds padding at the end if true, otherwise pads at start
+ // example:
+ // | // Fill the string to length 10 with "+" characters on the right. Yields "Dojo++++++".
+ // | dojo.string.pad("Dojo", 10, "+", true);
+
+ if(!ch){
+ ch = '0';
+ }
+ var out = String(text),
+ pad = dojo.string.rep(ch, Math.ceil((size - out.length) / ch.length));
+ return end ? out + pad : pad + out; // String
+};
+
+dojo.string.substitute = function( /*String*/ template,
+ /*Object|Array*/map,
+ /*Function?*/ transform,
+ /*Object?*/ thisObject){
+ // summary:
+ // Performs parameterized substitutions on a string. Throws an
+ // exception if any parameter is unmatched.
+ // template:
+ // a string with expressions in the form `${key}` to be replaced or
+ // `${key:format}` which specifies a format function. keys are case-sensitive.
+ // map:
+ // hash to search for substitutions
+ // transform:
+ // a function to process all parameters before substitution takes
+ // place, e.g. mylib.encodeXML
+ // thisObject:
+ // where to look for optional format function; default to the global
+ // namespace
+ // example:
+ // Substitutes two expressions in a string from an Array or Object
+ // | // returns "File 'foo.html' is not found in directory '/temp'."
+ // | // by providing substitution data in an Array
+ // | dojo.string.substitute(
+ // | "File '${0}' is not found in directory '${1}'.",
+ // | ["foo.html","/temp"]
+ // | );
+ // |
+ // | // also returns "File 'foo.html' is not found in directory '/temp'."
+ // | // but provides substitution data in an Object structure. Dotted
+ // | // notation may be used to traverse the structure.
+ // | dojo.string.substitute(
+ // | "File '${name}' is not found in directory '${info.dir}'.",
+ // | { name: "foo.html", info: { dir: "/temp" } }
+ // | );
+ // example:
+ // Use a transform function to modify the values:
+ // | // returns "file 'foo.html' is not found in directory '/temp'."
+ // | dojo.string.substitute(
+ // | "${0} is not found in ${1}.",
+ // | ["foo.html","/temp"],
+ // | function(str){
+ // | // try to figure out the type
+ // | var prefix = (str.charAt(0) == "/") ? "directory": "file";
+ // | return prefix + " '" + str + "'";
+ // | }
+ // | );
+ // example:
+ // Use a formatter
+ // | // returns "thinger -- howdy"
+ // | dojo.string.substitute(
+ // | "${0:postfix}", ["thinger"], null, {
+ // | postfix: function(value, key){
+ // | return value + " -- howdy";
+ // | }
+ // | }
+ // | );
+
+ thisObject = thisObject || dojo.global;
+ transform = transform ?
+ dojo.hitch(thisObject, transform) : function(v){ return v; };
+
+ return template.replace(/\$\{([^\s\:\}]+)(?:\:([^\s\:\}]+))?\}/g,
+ function(match, key, format){
+ var value = dojo.getObject(key, false, map);
+ if(format){
+ value = dojo.getObject(format, false, thisObject).call(thisObject, value, key);
+ }
+ return transform(value, key).toString();
+ }); // String
+};
+
+/*=====
+dojo.string.trim = function(str){
+ // summary:
+ // Trims whitespace from both sides of the string
+ // str: String
+ // String to be trimmed
+ // returns: String
+ // Returns the trimmed string
+ // description:
+ // This version of trim() was taken from [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript).
+ // The short yet performant version of this function is dojo.trim(),
+ // which is part of Dojo base. Uses String.prototype.trim instead, if available.
+ return ""; // String
+}
+=====*/
+
+dojo.string.trim = String.prototype.trim ?
+ dojo.trim : // aliasing to the native function
+ function(str){
+ str = str.replace(/^\s+/, '');
+ for(var i = str.length - 1; i >= 0; i--){
+ if(/\S/.test(str.charAt(i))){
+ str = str.substring(0, i + 1);
+ break;
+ }
+ }
+ return str;
+ };
+
+}
+
+if(!dojo._hasResource["dojo.cache"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.cache"] = true;
+dojo.provide("dojo.cache");
+
+
+
+/*=====
+dojo.cache = {
+ // summary:
+ // A way to cache string content that is fetchable via `dojo.moduleUrl`.
+};
+=====*/
+
+ var cache = {};
+ dojo.cache = function(/*String||Object*/module, /*String*/url, /*String||Object?*/value){
+ // summary:
+ // A getter and setter for storing the string content associated with the
+ // module and url arguments.
+ // description:
+ // module and url are used to call `dojo.moduleUrl()` to generate a module URL.
+ // If value is specified, the cache value for the moduleUrl will be set to
+ // that value. Otherwise, dojo.cache will fetch the moduleUrl and store it
+ // in its internal cache and return that cached value for the URL. To clear
+ // a cache value pass null for value. Since XMLHttpRequest (XHR) is used to fetch the
+ // the URL contents, only modules on the same domain of the page can use this capability.
+ // The build system can inline the cache values though, to allow for xdomain hosting.
+ // module: String||Object
+ // If a String, the module name to use for the base part of the URL, similar to module argument
+ // to `dojo.moduleUrl`. If an Object, something that has a .toString() method that
+ // generates a valid path for the cache item. For example, a dojo._Url object.
+ // url: String
+ // The rest of the path to append to the path derived from the module argument. If
+ // module is an object, then this second argument should be the "value" argument instead.
+ // value: String||Object?
+ // If a String, the value to use in the cache for the module/url combination.
+ // If an Object, it can have two properties: value and sanitize. The value property
+ // should be the value to use in the cache, and sanitize can be set to true or false,
+ // to indicate if XML declarations should be removed from the value and if the HTML
+ // inside a body tag in the value should be extracted as the real value. The value argument
+ // or the value property on the value argument are usually only used by the build system
+ // as it inlines cache content.
+ // example:
+ // To ask dojo.cache to fetch content and store it in the cache (the dojo["cache"] style
+ // of call is used to avoid an issue with the build system erroneously trying to intern
+ // this example. To get the build system to intern your dojo.cache calls, use the
+ // "dojo.cache" style of call):
+ // | //If template.html contains "<h1>Hello</h1>" that will be
+ // | //the value for the text variable.
+ // | var text = dojo["cache"]("my.module", "template.html");
+ // example:
+ // To ask dojo.cache to fetch content and store it in the cache, and sanitize the input
+ // (the dojo["cache"] style of call is used to avoid an issue with the build system
+ // erroneously trying to intern this example. To get the build system to intern your
+ // dojo.cache calls, use the "dojo.cache" style of call):
+ // | //If template.html contains "<html><body><h1>Hello</h1></body></html>", the
+ // | //text variable will contain just "<h1>Hello</h1>".
+ // | var text = dojo["cache"]("my.module", "template.html", {sanitize: true});
+ // example:
+ // Same example as previous, but demostrates how an object can be passed in as
+ // the first argument, then the value argument can then be the second argument.
+ // | //If template.html contains "<html><body><h1>Hello</h1></body></html>", the
+ // | //text variable will contain just "<h1>Hello</h1>".
+ // | var text = dojo["cache"](new dojo._Url("my/module/template.html"), {sanitize: true});
+
+ //Module could be a string, or an object that has a toString() method
+ //that will return a useful path. If it is an object, then the "url" argument
+ //will actually be the value argument.
+ if(typeof module == "string"){
+ var pathObj = dojo.moduleUrl(module, url);
+ }else{
+ pathObj = module;
+ value = url;
+ }
+ var key = pathObj.toString();
+
+ var val = value;
+ if(value != undefined && !dojo.isString(value)){
+ val = ("value" in value ? value.value : undefined);
+ }
+
+ var sanitize = value && value.sanitize ? true : false;
+
+ if(typeof val == "string"){
+ //We have a string, set cache value
+ val = cache[key] = sanitize ? dojo.cache._sanitize(val) : val;
+ }else if(val === null){
+ //Remove cached value
+ delete cache[key];
+ }else{
+ //Allow cache values to be empty strings. If key property does
+ //not exist, fetch it.
+ if(!(key in cache)){
+ val = dojo._getText(key);
+ cache[key] = sanitize ? dojo.cache._sanitize(val) : val;
+ }
+ val = cache[key];
+ }
+ return val; //String
+ };
+
+ dojo.cache._sanitize = function(/*String*/val){
+ // summary:
+ // Strips <?xml ...?> declarations so that external SVG and XML
+ // documents can be added to a document without worry. Also, if the string
+ // is an HTML document, only the part inside the body tag is returned.
+ // description:
+ // Copied from dijit._Templated._sanitizeTemplateString.
+ if(val){
+ val = val.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, "");
+ var matches = val.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
+ if(matches){
+ val = matches[1];
+ }
+ }else{
+ val = "";
+ }
+ return val; //String
+ };
+
+}
+
+if(!dojo._hasResource["dijit._Templated"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Templated"] = true;
+dojo.provide("dijit._Templated");
+
+
+
+
+
+
+
+dojo.declare("dijit._Templated",
+ null,
+ {
+ // summary:
+ // Mixin for widgets that are instantiated from a template
+
+ // templateString: [protected] String
+ // A string that represents the widget template. Pre-empts the
+ // templatePath. In builds that have their strings "interned", the
+ // templatePath is converted to an inline templateString, thereby
+ // preventing a synchronous network call.
+ //
+ // Use in conjunction with dojo.cache() to load from a file.
+ templateString: null,
+
+ // templatePath: [protected deprecated] String
+ // Path to template (HTML file) for this widget relative to dojo.baseUrl.
+ // Deprecated: use templateString with dojo.cache() instead.
+ templatePath: null,
+
+ // widgetsInTemplate: [protected] Boolean
+ // Should we parse the template to find widgets that might be
+ // declared in markup inside it? False by default.
+ widgetsInTemplate: false,
+
+ // skipNodeCache: [protected] Boolean
+ // If using a cached widget template node poses issues for a
+ // particular widget class, it can set this property to ensure
+ // that its template is always re-built from a string
+ _skipNodeCache: false,
+
+ // _earlyTemplatedStartup: Boolean
+ // A fallback to preserve the 1.0 - 1.3 behavior of children in
+ // templates having their startup called before the parent widget
+ // fires postCreate. Defaults to 'false', causing child widgets to
+ // have their .startup() called immediately before a parent widget
+ // .startup(), but always after the parent .postCreate(). Set to
+ // 'true' to re-enable to previous, arguably broken, behavior.
+ _earlyTemplatedStartup: false,
+
+/*=====
+ // _attachPoints: [private] String[]
+ // List of widget attribute names associated with dojoAttachPoint=... in the
+ // template, ex: ["containerNode", "labelNode"]
+ _attachPoints: [],
+ =====*/
+
+/*=====
+ // _attachEvents: [private] Handle[]
+ // List of connections associated with dojoAttachEvent=... in the
+ // template
+ _attachEvents: [],
+ =====*/
+
+ constructor: function(){
+ this._attachPoints = [];
+ this._attachEvents = [];
+ },
+
+ _stringRepl: function(tmpl){
+ // summary:
+ // Does substitution of ${foo} type properties in template string
+ // tags:
+ // private
+ var className = this.declaredClass, _this = this;
+ // Cache contains a string because we need to do property replacement
+ // do the property replacement
+ return dojo.string.substitute(tmpl, this, function(value, key){
+ if(key.charAt(0) == '!'){ value = dojo.getObject(key.substr(1), false, _this); }
+ if(typeof value == "undefined"){ throw new Error(className+" template:"+key); } // a debugging aide
+ if(value == null){ return ""; }
+
+ // Substitution keys beginning with ! will skip the transform step,
+ // in case a user wishes to insert unescaped markup, e.g. ${!foo}
+ return key.charAt(0) == "!" ? value :
+ // Safer substitution, see heading "Attribute values" in
+ // http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
+ value.toString().replace(/"/g,"&quot;"); //TODO: add &amp? use encodeXML method?
+ }, this);
+ },
+
+ buildRendering: function(){
+ // summary:
+ // Construct the UI for this widget from a template, setting this.domNode.
+ // tags:
+ // protected
+
+ // Lookup cached version of template, and download to cache if it
+ // isn't there already. Returns either a DomNode or a string, depending on
+ // whether or not the template contains ${foo} replacement parameters.
+ var cached = dijit._Templated.getCachedTemplate(this.templatePath, this.templateString, this._skipNodeCache);
+
+ var node;
+ if(dojo.isString(cached)){
+ node = dojo._toDom(this._stringRepl(cached));
+ if(node.nodeType != 1){
+ // Flag common problems such as templates with multiple top level nodes (nodeType == 11)
+ throw new Error("Invalid template: " + cached);
+ }
+ }else{
+ // if it's a node, all we have to do is clone it
+ node = cached.cloneNode(true);
+ }
+
+ this.domNode = node;
+
+ // Call down to _Widget.buildRendering() to get base classes assigned
+ // TODO: change the baseClass assignment to attributeMap
+ this.inherited(arguments);
+
+ // recurse through the node, looking for, and attaching to, our
+ // attachment points and events, which should be defined on the template node.
+ this._attachTemplateNodes(node);
+
+ if(this.widgetsInTemplate){
+ // Store widgets that we need to start at a later point in time
+ var cw = (this._startupWidgets = dojo.parser.parse(node, {
+ noStart: !this._earlyTemplatedStartup,
+ template: true,
+ inherited: {dir: this.dir, lang: this.lang},
+ propsThis: this, // so data-dojo-props of widgets in the template can reference "this" to refer to me
+ scope: "dojo" // even in multi-version mode templates use dojoType/data-dojo-type
+ }));
+
+ this._supportingWidgets = dijit.findWidgets(node);
+
+ this._attachTemplateNodes(cw, function(n,p){
+ return n[p];
+ });
+ }
+
+ this._fillContent(this.srcNodeRef);
+ },
+
+ _fillContent: function(/*DomNode*/ source){
+ // summary:
+ // Relocate source contents to templated container node.
+ // this.containerNode must be able to receive children, or exceptions will be thrown.
+ // tags:
+ // protected
+ var dest = this.containerNode;
+ if(source && dest){
+ while(source.hasChildNodes()){
+ dest.appendChild(source.firstChild);
+ }
+ }
+ },
+
+ _attachTemplateNodes: function(rootNode, getAttrFunc){
+ // summary:
+ // Iterate through the template and attach functions and nodes accordingly.
+ // Alternately, if rootNode is an array of widgets, then will process dojoAttachPoint
+ // etc. for those widgets.
+ // description:
+ // Map widget properties and functions to the handlers specified in
+ // the dom node and it's descendants. This function iterates over all
+ // nodes and looks for these properties:
+ // * dojoAttachPoint
+ // * dojoAttachEvent
+ // * waiRole
+ // * waiState
+ // rootNode: DomNode|Array[Widgets]
+ // the node to search for properties. All children will be searched.
+ // getAttrFunc: Function?
+ // a function which will be used to obtain property for a given
+ // DomNode/Widget
+ // tags:
+ // private
+
+ getAttrFunc = getAttrFunc || function(n,p){ return n.getAttribute(p); };
+
+ var nodes = dojo.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*"));
+ var x = dojo.isArray(rootNode) ? 0 : -1;
+ for(; x<nodes.length; x++){
+ var baseNode = (x == -1) ? rootNode : nodes[x];
+ if(this.widgetsInTemplate && (getAttrFunc(baseNode, "dojoType") || getAttrFunc(baseNode, "data-dojo-type"))){
+ continue;
+ }
+ // Process dojoAttachPoint
+ var attachPoint = getAttrFunc(baseNode, "dojoAttachPoint") || getAttrFunc(baseNode, "data-dojo-attach-point");
+ if(attachPoint){
+ var point, points = attachPoint.split(/\s*,\s*/);
+ while((point = points.shift())){
+ if(dojo.isArray(this[point])){
+ this[point].push(baseNode);
+ }else{
+ this[point]=baseNode;
+ }
+ this._attachPoints.push(point);
+ }
+ }
+
+ // Process dojoAttachEvent
+ var attachEvent = getAttrFunc(baseNode, "dojoAttachEvent") || getAttrFunc(baseNode, "data-dojo-attach-event");;
+ if(attachEvent){
+ // NOTE: we want to support attributes that have the form
+ // "domEvent: nativeEvent; ..."
+ var event, events = attachEvent.split(/\s*,\s*/);
+ var trim = dojo.trim;
+ while((event = events.shift())){
+ if(event){
+ var thisFunc = null;
+ if(event.indexOf(":") != -1){
+ // oh, if only JS had tuple assignment
+ var funcNameArr = event.split(":");
+ event = trim(funcNameArr[0]);
+ thisFunc = trim(funcNameArr[1]);
+ }else{
+ event = trim(event);
+ }
+ if(!thisFunc){
+ thisFunc = event;
+ }
+ this._attachEvents.push(this.connect(baseNode, event, thisFunc));
+ }
+ }
+ }
+
+ // waiRole, waiState
+ // TODO: remove this in 2.0, templates are now using role=... and aria-XXX=... attributes directicly
+ var role = getAttrFunc(baseNode, "waiRole");
+ if(role){
+ dijit.setWaiRole(baseNode, role);
+ }
+ var values = getAttrFunc(baseNode, "waiState");
+ if(values){
+ dojo.forEach(values.split(/\s*,\s*/), function(stateValue){
+ if(stateValue.indexOf('-') != -1){
+ var pair = stateValue.split('-');
+ dijit.setWaiState(baseNode, pair[0], pair[1]);
+ }
+ });
+ }
+ }
+ },
+
+ startup: function(){
+ dojo.forEach(this._startupWidgets, function(w){
+ if(w && !w._started && w.startup){
+ w.startup();
+ }
+ });
+ this.inherited(arguments);
+ },
+
+ destroyRendering: function(){
+ // Delete all attach points to prevent IE6 memory leaks.
+ dojo.forEach(this._attachPoints, function(point){
+ delete this[point];
+ }, this);
+ this._attachPoints = [];
+
+ // And same for event handlers
+ dojo.forEach(this._attachEvents, this.disconnect, this);
+ this._attachEvents = [];
+
+ this.inherited(arguments);
+ }
+ }
+);
+
+// key is either templatePath or templateString; object is either string or DOM tree
+dijit._Templated._templateCache = {};
+
+dijit._Templated.getCachedTemplate = function(templatePath, templateString, alwaysUseString){
+ // summary:
+ // Static method to get a template based on the templatePath or
+ // templateString key
+ // templatePath: String||dojo.uri.Uri
+ // The URL to get the template from.
+ // templateString: String?
+ // a string to use in lieu of fetching the template from a URL. Takes precedence
+ // over templatePath
+ // returns: Mixed
+ // Either string (if there are ${} variables that need to be replaced) or just
+ // a DOM tree (if the node can be cloned directly)
+
+ // is it already cached?
+ var tmplts = dijit._Templated._templateCache;
+ var key = templateString || templatePath;
+ var cached = tmplts[key];
+ if(cached){
+ try{
+ // if the cached value is an innerHTML string (no ownerDocument) or a DOM tree created within the current document, then use the current cached value
+ if(!cached.ownerDocument || cached.ownerDocument == dojo.doc){
+ // string or node of the same document
+ return cached;
+ }
+ }catch(e){ /* squelch */ } // IE can throw an exception if cached.ownerDocument was reloaded
+ dojo.destroy(cached);
+ }
+
+ // If necessary, load template string from template path
+ if(!templateString){
+ templateString = dojo.cache(templatePath, {sanitize: true});
+ }
+ templateString = dojo.string.trim(templateString);
+
+ if(alwaysUseString || templateString.match(/\$\{([^\}]+)\}/g)){
+ // there are variables in the template so all we can do is cache the string
+ return (tmplts[key] = templateString); //String
+ }else{
+ // there are no variables in the template so we can cache the DOM tree
+ var node = dojo._toDom(templateString);
+ if(node.nodeType != 1){
+ throw new Error("Invalid template: " + templateString);
+ }
+ return (tmplts[key] = node); //Node
+ }
+};
+
+if(dojo.isIE){
+ dojo.addOnWindowUnload(function(){
+ var cache = dijit._Templated._templateCache;
+ for(var key in cache){
+ var value = cache[key];
+ if(typeof value == "object"){ // value is either a string or a DOM node template
+ dojo.destroy(value);
+ }
+ delete cache[key];
+ }
+ });
+}
+
+// These arguments can be specified for widgets which are used in templates.
+// Since any widget can be specified as sub widgets in template, mix it
+// into the base widget class. (This is a hack, but it's effective.)
+dojo.extend(dijit._Widget,{
+ dojoAttachEvent: "",
+ dojoAttachPoint: "",
+ waiRole: "",
+ waiState:""
+});
+
+}
+
+if(!dojo._hasResource["dijit._Container"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Container"] = true;
+dojo.provide("dijit._Container");
+
+
+
+dojo.declare("dijit._Container",
+ null,
+ {
+ // summary:
+ // Mixin for widgets that contain a set of widget children.
+ // description:
+ // Use this mixin for widgets that needs to know about and
+ // keep track of their widget children. Suitable for widgets like BorderContainer
+ // and TabContainer which contain (only) a set of child widgets.
+ //
+ // It's not suitable for widgets like ContentPane
+ // which contains mixed HTML (plain DOM nodes in addition to widgets),
+ // and where contained widgets are not necessarily directly below
+ // this.containerNode. In that case calls like addChild(node, position)
+ // wouldn't make sense.
+
+ // isContainer: [protected] Boolean
+ // Indicates that this widget acts as a "parent" to the descendant widgets.
+ // When the parent is started it will call startup() on the child widgets.
+ // See also `isLayoutContainer`.
+ isContainer: true,
+
+ buildRendering: function(){
+ this.inherited(arguments);
+ if(!this.containerNode){
+ // all widgets with descendants must set containerNode
+ this.containerNode = this.domNode;
+ }
+ },
+
+ addChild: function(/*dijit._Widget*/ widget, /*int?*/ insertIndex){
+ // summary:
+ // Makes the given widget a child of this widget.
+ // description:
+ // Inserts specified child widget's dom node as a child of this widget's
+ // container node, and possibly does other processing (such as layout).
+
+ var refNode = this.containerNode;
+ if(insertIndex && typeof insertIndex == "number"){
+ var children = this.getChildren();
+ if(children && children.length >= insertIndex){
+ refNode = children[insertIndex-1].domNode;
+ insertIndex = "after";
+ }
+ }
+ dojo.place(widget.domNode, refNode, insertIndex);
+
+ // If I've been started but the child widget hasn't been started,
+ // start it now. Make sure to do this after widget has been
+ // inserted into the DOM tree, so it can see that it's being controlled by me,
+ // so it doesn't try to size itself.
+ if(this._started && !widget._started){
+ widget.startup();
+ }
+ },
+
+ removeChild: function(/*Widget or int*/ widget){
+ // summary:
+ // Removes the passed widget instance from this widget but does
+ // not destroy it. You can also pass in an integer indicating
+ // the index within the container to remove
+
+ if(typeof widget == "number"){
+ widget = this.getChildren()[widget];
+ }
+
+ if(widget){
+ var node = widget.domNode;
+ if(node && node.parentNode){
+ node.parentNode.removeChild(node); // detach but don't destroy
+ }
+ }
+ },
+
+ hasChildren: function(){
+ // summary:
+ // Returns true if widget has children, i.e. if this.containerNode contains something.
+ return this.getChildren().length > 0; // Boolean
+ },
+
+ destroyDescendants: function(/*Boolean*/ preserveDom){
+ // summary:
+ // Destroys all the widgets inside this.containerNode,
+ // but not this widget itself
+ dojo.forEach(this.getChildren(), function(child){ child.destroyRecursive(preserveDom); });
+ },
+
+ _getSiblingOfChild: function(/*dijit._Widget*/ child, /*int*/ dir){
+ // summary:
+ // Get the next or previous widget sibling of child
+ // dir:
+ // if 1, get the next sibling
+ // if -1, get the previous sibling
+ // tags:
+ // private
+ var node = child.domNode,
+ which = (dir>0 ? "nextSibling" : "previousSibling");
+ do{
+ node = node[which];
+ }while(node && (node.nodeType != 1 || !dijit.byNode(node)));
+ return node && dijit.byNode(node); // dijit._Widget
+ },
+
+ getIndexOfChild: function(/*dijit._Widget*/ child){
+ // summary:
+ // Gets the index of the child in this container or -1 if not found
+ return dojo.indexOf(this.getChildren(), child); // int
+ },
+
+ startup: function(){
+ // summary:
+ // Called after all the widgets have been instantiated and their
+ // dom nodes have been inserted somewhere under dojo.doc.body.
+ //
+ // Widgets should override this method to do any initialization
+ // dependent on other widgets existing, and then call
+ // this superclass method to finish things off.
+ //
+ // startup() in subclasses shouldn't do anything
+ // size related because the size of the widget hasn't been set yet.
+
+ if(this._started){ return; }
+
+ // Startup all children of this widget
+ dojo.forEach(this.getChildren(), function(child){ child.startup(); });
+
+ this.inherited(arguments);
+ }
+ }
+);
+
+}
+
+if(!dojo._hasResource["dijit._Contained"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Contained"] = true;
+dojo.provide("dijit._Contained");
+
+
+
+dojo.declare("dijit._Contained",
+ null,
+ {
+ // summary:
+ // Mixin for widgets that are children of a container widget
+ //
+ // example:
+ // | // make a basic custom widget that knows about it's parents
+ // | dojo.declare("my.customClass",[dijit._Widget,dijit._Contained],{});
+
+ getParent: function(){
+ // summary:
+ // Returns the parent widget of this widget, assuming the parent
+ // specifies isContainer
+ var parent = dijit.getEnclosingWidget(this.domNode.parentNode);
+ return parent && parent.isContainer ? parent : null;
+ },
+
+ _getSibling: function(/*String*/ which){
+ // summary:
+ // Returns next or previous sibling
+ // which:
+ // Either "next" or "previous"
+ // tags:
+ // private
+ var node = this.domNode;
+ do{
+ node = node[which+"Sibling"];
+ }while(node && node.nodeType != 1);
+ return node && dijit.byNode(node); // dijit._Widget
+ },
+
+ getPreviousSibling: function(){
+ // summary:
+ // Returns null if this is the first child of the parent,
+ // otherwise returns the next element sibling to the "left".
+
+ return this._getSibling("previous"); // dijit._Widget
+ },
+
+ getNextSibling: function(){
+ // summary:
+ // Returns null if this is the last child of the parent,
+ // otherwise returns the next element sibling to the "right".
+
+ return this._getSibling("next"); // dijit._Widget
+ },
+
+ getIndexInParent: function(){
+ // summary:
+ // Returns the index of this widget within its container parent.
+ // It returns -1 if the parent does not exist, or if the parent
+ // is not a dijit._Container
+
+ var p = this.getParent();
+ if(!p || !p.getIndexOfChild){
+ return -1; // int
+ }
+ return p.getIndexOfChild(this); // int
+ }
+ }
+ );
+
+}
+
+if(!dojo._hasResource["dijit.layout._LayoutWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.layout._LayoutWidget"] = true;
+dojo.provide("dijit.layout._LayoutWidget");
+
+
+
+
+
+
+dojo.declare("dijit.layout._LayoutWidget",
+ [dijit._Widget, dijit._Container, dijit._Contained],
+ {
+ // summary:
+ // Base class for a _Container widget which is responsible for laying out its children.
+ // Widgets which mixin this code must define layout() to manage placement and sizing of the children.
+
+ // baseClass: [protected extension] String
+ // This class name is applied to the widget's domNode
+ // and also may be used to generate names for sub nodes,
+ // for example dijitTabContainer-content.
+ baseClass: "dijitLayoutContainer",
+
+ // isLayoutContainer: [protected] Boolean
+ // Indicates that this widget is going to call resize() on its
+ // children widgets, setting their size, when they become visible.
+ isLayoutContainer: true,
+
+ buildRendering: function(){
+ this.inherited(arguments);
+ dojo.addClass(this.domNode, "dijitContainer");
+ },
+
+ startup: function(){
+ // summary:
+ // Called after all the widgets have been instantiated and their
+ // dom nodes have been inserted somewhere under dojo.doc.body.
+ //
+ // Widgets should override this method to do any initialization
+ // dependent on other widgets existing, and then call
+ // this superclass method to finish things off.
+ //
+ // startup() in subclasses shouldn't do anything
+ // size related because the size of the widget hasn't been set yet.
+
+ if(this._started){ return; }
+
+ // Need to call inherited first - so that child widgets get started
+ // up correctly
+ this.inherited(arguments);
+
+ // If I am a not being controlled by a parent layout widget...
+ var parent = this.getParent && this.getParent()
+ if(!(parent && parent.isLayoutContainer)){
+ // Do recursive sizing and layout of all my descendants
+ // (passing in no argument to resize means that it has to glean the size itself)
+ this.resize();
+
+ // Since my parent isn't a layout container, and my style *may be* width=height=100%
+ // or something similar (either set directly or via a CSS class),
+ // monitor when my size changes so that I can re-layout.
+ // For browsers where I can't directly monitor when my size changes,
+ // monitor when the viewport changes size, which *may* indicate a size change for me.
+ this.connect(dojo.isIE ? this.domNode : dojo.global, 'onresize', function(){
+ // Using function(){} closure to ensure no arguments to resize.
+ this.resize();
+ });
+ }
+ },
+
+ resize: function(changeSize, resultSize){
+ // summary:
+ // Call this to resize a widget, or after its size has changed.
+ // description:
+ // Change size mode:
+ // When changeSize is specified, changes the marginBox of this widget
+ // and forces it to relayout its contents accordingly.
+ // changeSize may specify height, width, or both.
+ //
+ // If resultSize is specified it indicates the size the widget will
+ // become after changeSize has been applied.
+ //
+ // Notification mode:
+ // When changeSize is null, indicates that the caller has already changed
+ // the size of the widget, or perhaps it changed because the browser
+ // window was resized. Tells widget to relayout its contents accordingly.
+ //
+ // If resultSize is also specified it indicates the size the widget has
+ // become.
+ //
+ // In either mode, this method also:
+ // 1. Sets this._borderBox and this._contentBox to the new size of
+ // the widget. Queries the current domNode size if necessary.
+ // 2. Calls layout() to resize contents (and maybe adjust child widgets).
+ //
+ // changeSize: Object?
+ // Sets the widget to this margin-box size and position.
+ // May include any/all of the following properties:
+ // | {w: int, h: int, l: int, t: int}
+ //
+ // resultSize: Object?
+ // The margin-box size of this widget after applying changeSize (if
+ // changeSize is specified). If caller knows this size and
+ // passes it in, we don't need to query the browser to get the size.
+ // | {w: int, h: int}
+
+ var node = this.domNode;
+
+ // set margin box size, unless it wasn't specified, in which case use current size
+ if(changeSize){
+ dojo.marginBox(node, changeSize);
+
+ // set offset of the node
+ if(changeSize.t){ node.style.top = changeSize.t + "px"; }
+ if(changeSize.l){ node.style.left = changeSize.l + "px"; }
+ }
+
+ // If either height or width wasn't specified by the user, then query node for it.
+ // But note that setting the margin box and then immediately querying dimensions may return
+ // inaccurate results, so try not to depend on it.
+ var mb = resultSize || {};
+ dojo.mixin(mb, changeSize || {}); // changeSize overrides resultSize
+ if( !("h" in mb) || !("w" in mb) ){
+ mb = dojo.mixin(dojo.marginBox(node), mb); // just use dojo.marginBox() to fill in missing values
+ }
+
+ // Compute and save the size of my border box and content box
+ // (w/out calling dojo.contentBox() since that may fail if size was recently set)
+ var cs = dojo.getComputedStyle(node);
+ var me = dojo._getMarginExtents(node, cs);
+ var be = dojo._getBorderExtents(node, cs);
+ var bb = (this._borderBox = {
+ w: mb.w - (me.w + be.w),
+ h: mb.h - (me.h + be.h)
+ });
+ var pe = dojo._getPadExtents(node, cs);
+ this._contentBox = {
+ l: dojo._toPixelValue(node, cs.paddingLeft),
+ t: dojo._toPixelValue(node, cs.paddingTop),
+ w: bb.w - pe.w,
+ h: bb.h - pe.h
+ };
+
+ // Callback for widget to adjust size of its children
+ this.layout();
+ },
+
+ layout: function(){
+ // summary:
+ // Widgets override this method to size and position their contents/children.
+ // When this is called this._contentBox is guaranteed to be set (see resize()).
+ //
+ // This is called after startup(), and also when the widget's size has been
+ // changed.
+ // tags:
+ // protected extension
+ },
+
+ _setupChild: function(/*dijit._Widget*/child){
+ // summary:
+ // Common setup for initial children and children which are added after startup
+ // tags:
+ // protected extension
+
+ var cls = this.baseClass + "-child "
+ + (child.baseClass ? this.baseClass + "-" + child.baseClass : "");
+ dojo.addClass(child.domNode, cls);
+ },
+
+ addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
+ // Overrides _Container.addChild() to call _setupChild()
+ this.inherited(arguments);
+ if(this._started){
+ this._setupChild(child);
+ }
+ },
+
+ removeChild: function(/*dijit._Widget*/ child){
+ // Overrides _Container.removeChild() to remove class added by _setupChild()
+ var cls = this.baseClass + "-child"
+ + (child.baseClass ?
+ " " + this.baseClass + "-" + child.baseClass : "");
+ dojo.removeClass(child.domNode, cls);
+
+ this.inherited(arguments);
+ }
+ }
+);
+
+dijit.layout.marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){
+ // summary:
+ // Given the margin-box size of a node, return its content box size.
+ // Functions like dojo.contentBox() but is more reliable since it doesn't have
+ // to wait for the browser to compute sizes.
+ var cs = dojo.getComputedStyle(node);
+ var me = dojo._getMarginExtents(node, cs);
+ var pb = dojo._getPadBorderExtents(node, cs);
+ return {
+ l: dojo._toPixelValue(node, cs.paddingLeft),
+ t: dojo._toPixelValue(node, cs.paddingTop),
+ w: mb.w - (me.w + pb.w),
+ h: mb.h - (me.h + pb.h)
+ };
+};
+
+(function(){
+ var capitalize = function(word){
+ return word.substring(0,1).toUpperCase() + word.substring(1);
+ };
+
+ var size = function(widget, dim){
+ // size the child
+ widget.resize ? widget.resize(dim) : dojo.marginBox(widget.domNode, dim);
+
+ // record child's size, but favor our own numbers when we have them.
+ // the browser lies sometimes
+ dojo.mixin(widget, dojo.marginBox(widget.domNode));
+ dojo.mixin(widget, dim);
+ };
+
+ dijit.layout.layoutChildren = function(/*DomNode*/ container, /*Object*/ dim, /*Widget[]*/ children,
+ /*String?*/ changedRegionId, /*Number?*/ changedRegionSize){
+ // summary
+ // Layout a bunch of child dom nodes within a parent dom node
+ // container:
+ // parent node
+ // dim:
+ // {l, t, w, h} object specifying dimensions of container into which to place children
+ // children:
+ // an array of Widgets or at least objects containing:
+ // * domNode: pointer to DOM node to position
+ // * region or layoutAlign: position to place DOM node
+ // * resize(): (optional) method to set size of node
+ // * id: (optional) Id of widgets, referenced from resize object, below.
+ // changedRegionId:
+ // If specified, the slider for the region with the specified id has been dragged, and thus
+ // the region's height or width should be adjusted according to changedRegionSize
+ // changedRegionSize:
+ // See changedRegionId.
+
+ // copy dim because we are going to modify it
+ dim = dojo.mixin({}, dim);
+
+ dojo.addClass(container, "dijitLayoutContainer");
+
+ // Move "client" elements to the end of the array for layout. a11y dictates that the author
+ // needs to be able to put them in the document in tab-order, but this algorithm requires that
+ // client be last. TODO: move these lines to LayoutContainer? Unneeded other places I think.
+ children = dojo.filter(children, function(item){ return item.region != "center" && item.layoutAlign != "client"; })
+ .concat(dojo.filter(children, function(item){ return item.region == "center" || item.layoutAlign == "client"; }));
+
+ // set positions/sizes
+ dojo.forEach(children, function(child){
+ var elm = child.domNode,
+ pos = (child.region || child.layoutAlign);
+
+ // set elem to upper left corner of unused space; may move it later
+ var elmStyle = elm.style;
+ elmStyle.left = dim.l+"px";
+ elmStyle.top = dim.t+"px";
+ elmStyle.bottom = elmStyle.right = "auto";
+
+ dojo.addClass(elm, "dijitAlign" + capitalize(pos));
+
+ // Size adjustments to make to this child widget
+ var sizeSetting = {};
+
+ // Check for optional size adjustment due to splitter drag (height adjustment for top/bottom align
+ // panes and width adjustment for left/right align panes.
+ if(changedRegionId && changedRegionId == child.id){
+ sizeSetting[child.region == "top" || child.region == "bottom" ? "h" : "w"] = changedRegionSize;
+ }
+
+ // set size && adjust record of remaining space.
+ // note that setting the width of a <div> may affect its height.
+ if(pos == "top" || pos == "bottom"){
+ sizeSetting.w = dim.w;
+ size(child, sizeSetting);
+ dim.h -= child.h;
+ if(pos == "top"){
+ dim.t += child.h;
+ }else{
+ elmStyle.top = dim.t + dim.h + "px";
+ }
+ }else if(pos == "left" || pos == "right"){
+ sizeSetting.h = dim.h;
+ size(child, sizeSetting);
+ dim.w -= child.w;
+ if(pos == "left"){
+ dim.l += child.w;
+ }else{
+ elmStyle.left = dim.l + dim.w + "px";
+ }
+ }else if(pos == "client" || pos == "center"){
+ size(child, dim);
+ }
+ });
+ };
+
+})();
+
+}
+
+if(!dojo._hasResource["dijit._CssStateMixin"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._CssStateMixin"] = true;
+dojo.provide("dijit._CssStateMixin");
+
+
+
+dojo.declare("dijit._CssStateMixin", [], {
+ // summary:
+ // Mixin for widgets to set CSS classes on the widget DOM nodes depending on hover/mouse press/focus
+ // state changes, and also higher-level state changes such becoming disabled or selected.
+ //
+ // description:
+ // By mixing this class into your widget, and setting the this.baseClass attribute, it will automatically
+ // maintain CSS classes on the widget root node (this.domNode) depending on hover,
+ // active, focus, etc. state. Ex: with a baseClass of dijitButton, it will apply the classes
+ // dijitButtonHovered and dijitButtonActive, as the user moves the mouse over the widget and clicks it.
+ //
+ // It also sets CSS like dijitButtonDisabled based on widget semantic state.
+ //
+ // By setting the cssStateNodes attribute, a widget can also track events on subnodes (like buttons
+ // within the widget).
+
+ // cssStateNodes: [protected] Object
+ // List of sub-nodes within the widget that need CSS classes applied on mouse hover/press and focus
+ //.
+ // Each entry in the hash is a an attachpoint names (like "upArrowButton") mapped to a CSS class names
+ // (like "dijitUpArrowButton"). Example:
+ // | {
+ // | "upArrowButton": "dijitUpArrowButton",
+ // | "downArrowButton": "dijitDownArrowButton"
+ // | }
+ // The above will set the CSS class dijitUpArrowButton to the this.upArrowButton DOMNode when it
+ // is hovered, etc.
+ cssStateNodes: {},
+
+ // hovering: [readonly] Boolean
+ // True if cursor is over this widget
+ hovering: false,
+
+ // active: [readonly] Boolean
+ // True if mouse was pressed while over this widget, and hasn't been released yet
+ active: false,
+
+ _applyAttributes: function(){
+ // This code would typically be in postCreate(), but putting in _applyAttributes() for
+ // performance: so the class changes happen before DOM is inserted into the document.
+ // Change back to postCreate() in 2.0. See #11635.
+
+ this.inherited(arguments);
+
+ // Automatically monitor mouse events (essentially :hover and :active) on this.domNode
+ dojo.forEach(["onmouseenter", "onmouseleave", "onmousedown"], function(e){
+ this.connect(this.domNode, e, "_cssMouseEvent");
+ }, this);
+
+ // Monitoring changes to disabled, readonly, etc. state, and update CSS class of root node
+ dojo.forEach(["disabled", "readOnly", "checked", "selected", "focused", "state", "hovering", "active"], function(attr){
+ this.watch(attr, dojo.hitch(this, "_setStateClass"));
+ }, this);
+
+ // Events on sub nodes within the widget
+ for(var ap in this.cssStateNodes){
+ this._trackMouseState(this[ap], this.cssStateNodes[ap]);
+ }
+ // Set state initially; there's probably no hover/active/focus state but widget might be
+ // disabled/readonly/checked/selected so we want to set CSS classes for those conditions.
+ this._setStateClass();
+ },
+
+ _cssMouseEvent: function(/*Event*/ event){
+ // summary:
+ // Sets hovering and active properties depending on mouse state,
+ // which triggers _setStateClass() to set appropriate CSS classes for this.domNode.
+
+ if(!this.disabled){
+ switch(event.type){
+ case "mouseenter":
+ case "mouseover": // generated on non-IE browsers even though we connected to mouseenter
+ this._set("hovering", true);
+ this._set("active", this._mouseDown);
+ break;
+
+ case "mouseleave":
+ case "mouseout": // generated on non-IE browsers even though we connected to mouseleave
+ this._set("hovering", false);
+ this._set("active", false);
+ break;
+
+ case "mousedown" :
+ this._set("active", true);
+ this._mouseDown = true;
+ // Set a global event to handle mouseup, so it fires properly
+ // even if the cursor leaves this.domNode before the mouse up event.
+ // Alternately could set active=false on mouseout.
+ var mouseUpConnector = this.connect(dojo.body(), "onmouseup", function(){
+ this._mouseDown = false;
+ this._set("active", false);
+ this.disconnect(mouseUpConnector);
+ });
+ break;
+ }
+ }
+ },
+
+ _setStateClass: function(){
+ // summary:
+ // Update the visual state of the widget by setting the css classes on this.domNode
+ // (or this.stateNode if defined) by combining this.baseClass with
+ // various suffixes that represent the current widget state(s).
+ //
+ // description:
+ // In the case where a widget has multiple
+ // states, it sets the class based on all possible
+ // combinations. For example, an invalid form widget that is being hovered
+ // will be "dijitInput dijitInputInvalid dijitInputHover dijitInputInvalidHover".
+ //
+ // The widget may have one or more of the following states, determined
+ // by this.state, this.checked, this.valid, and this.selected:
+ // - Error - ValidationTextBox sets this.state to "Error" if the current input value is invalid
+ // - Incomplete - ValidationTextBox sets this.state to "Incomplete" if the current input value is not finished yet
+ // - Checked - ex: a checkmark or a ToggleButton in a checked state, will have this.checked==true
+ // - Selected - ex: currently selected tab will have this.selected==true
+ //
+ // In addition, it may have one or more of the following states,
+ // based on this.disabled and flags set in _onMouse (this.active, this.hovering) and from focus manager (this.focused):
+ // - Disabled - if the widget is disabled
+ // - Active - if the mouse (or space/enter key?) is being pressed down
+ // - Focused - if the widget has focus
+ // - Hover - if the mouse is over the widget
+
+ // Compute new set of classes
+ var newStateClasses = this.baseClass.split(" ");
+
+ function multiply(modifier){
+ newStateClasses = newStateClasses.concat(dojo.map(newStateClasses, function(c){ return c+modifier; }), "dijit"+modifier);
+ }
+
+ if(!this.isLeftToRight()){
+ // For RTL mode we need to set an addition class like dijitTextBoxRtl.
+ multiply("Rtl");
+ }
+
+ if(this.checked){
+ multiply("Checked");
+ }
+ if(this.state){
+ multiply(this.state);
+ }
+ if(this.selected){
+ multiply("Selected");
+ }
+
+ if(this.disabled){
+ multiply("Disabled");
+ }else if(this.readOnly){
+ multiply("ReadOnly");
+ }else{
+ if(this.active){
+ multiply("Active");
+ }else if(this.hovering){
+ multiply("Hover");
+ }
+ }
+
+ if(this._focused){
+ multiply("Focused");
+ }
+
+ // Remove old state classes and add new ones.
+ // For performance concerns we only write into domNode.className once.
+ var tn = this.stateNode || this.domNode,
+ classHash = {}; // set of all classes (state and otherwise) for node
+
+ dojo.forEach(tn.className.split(" "), function(c){ classHash[c] = true; });
+
+ if("_stateClasses" in this){
+ dojo.forEach(this._stateClasses, function(c){ delete classHash[c]; });
+ }
+
+ dojo.forEach(newStateClasses, function(c){ classHash[c] = true; });
+
+ var newClasses = [];
+ for(var c in classHash){
+ newClasses.push(c);
+ }
+ tn.className = newClasses.join(" ");
+
+ this._stateClasses = newStateClasses;
+ },
+
+ _trackMouseState: function(/*DomNode*/ node, /*String*/ clazz){
+ // summary:
+ // Track mouse/focus events on specified node and set CSS class on that node to indicate
+ // current state. Usually not called directly, but via cssStateNodes attribute.
+ // description:
+ // Given class=foo, will set the following CSS class on the node
+ // - fooActive: if the user is currently pressing down the mouse button while over the node
+ // - fooHover: if the user is hovering the mouse over the node, but not pressing down a button
+ // - fooFocus: if the node is focused
+ //
+ // Note that it won't set any classes if the widget is disabled.
+ // node: DomNode
+ // Should be a sub-node of the widget, not the top node (this.domNode), since the top node
+ // is handled specially and automatically just by mixing in this class.
+ // clazz: String
+ // CSS class name (ex: dijitSliderUpArrow).
+
+ // Current state of node (initially false)
+ // NB: setting specifically to false because dojo.toggleClass() needs true boolean as third arg
+ var hovering=false, active=false, focused=false;
+
+ var self = this,
+ cn = dojo.hitch(this, "connect", node);
+
+ function setClass(){
+ var disabled = ("disabled" in self && self.disabled) || ("readonly" in self && self.readonly);
+ dojo.toggleClass(node, clazz+"Hover", hovering && !active && !disabled);
+ dojo.toggleClass(node, clazz+"Active", active && !disabled);
+ dojo.toggleClass(node, clazz+"Focused", focused && !disabled);
+ }
+
+ // Mouse
+ cn("onmouseenter", function(){
+ hovering = true;
+ setClass();
+ });
+ cn("onmouseleave", function(){
+ hovering = false;
+ active = false;
+ setClass();
+ });
+ cn("onmousedown", function(){
+ active = true;
+ setClass();
+ });
+ cn("onmouseup", function(){
+ active = false;
+ setClass();
+ });
+
+ // Focus
+ cn("onfocus", function(){
+ focused = true;
+ setClass();
+ });
+ cn("onblur", function(){
+ focused = false;
+ setClass();
+ });
+
+ // Just in case widget is enabled/disabled while it has focus/hover/active state.
+ // Maybe this is overkill.
+ this.watch("disabled", setClass);
+ this.watch("readOnly", setClass);
+ }
+});
+
+}
+
+if(!dojo._hasResource["dijit.form._FormWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form._FormWidget"] = true;
+dojo.provide("dijit.form._FormWidget");
+
+
+
+
+
+
+
+dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated, dijit._CssStateMixin],
+ {
+ // summary:
+ // Base class for widgets corresponding to native HTML elements such as <checkbox> or <button>,
+ // which can be children of a <form> node or a `dijit.form.Form` widget.
+ //
+ // description:
+ // Represents a single HTML element.
+ // All these widgets should have these attributes just like native HTML input elements.
+ // You can set them during widget construction or afterwards, via `dijit._Widget.attr`.
+ //
+ // They also share some common methods.
+
+ // name: [const] String
+ // Name used when submitting form; same as "name" attribute or plain HTML elements
+ name: "",
+
+ // alt: String
+ // Corresponds to the native HTML <input> element's attribute.
+ alt: "",
+
+ // value: String
+ // Corresponds to the native HTML <input> element's attribute.
+ value: "",
+
+ // type: String
+ // Corresponds to the native HTML <input> element's attribute.
+ type: "text",
+
+ // tabIndex: Integer
+ // Order fields are traversed when user hits the tab key
+ tabIndex: "0",
+
+ // disabled: Boolean
+ // Should this widget respond to user input?
+ // In markup, this is specified as "disabled='disabled'", or just "disabled".
+ disabled: false,
+
+ // intermediateChanges: Boolean
+ // Fires onChange for each value change or only on demand
+ intermediateChanges: false,
+
+ // scrollOnFocus: Boolean
+ // On focus, should this widget scroll into view?
+ scrollOnFocus: true,
+
+ // These mixins assume that the focus node is an INPUT, as many but not all _FormWidgets are.
+ attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
+ value: "focusNode",
+ id: "focusNode",
+ tabIndex: "focusNode",
+ alt: "focusNode",
+ title: "focusNode"
+ }),
+
+ postMixInProperties: function(){
+ // Setup name=foo string to be referenced from the template (but only if a name has been specified)
+ // Unfortunately we can't use attributeMap to set the name due to IE limitations, see #8660
+ // Regarding escaping, see heading "Attribute values" in
+ // http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
+ this.nameAttrSetting = this.name ? ('name="' + this.name.replace(/'/g, "&quot;") + '"') : '';
+ this.inherited(arguments);
+ },
+
+ postCreate: function(){
+ this.inherited(arguments);
+ this.connect(this.domNode, "onmousedown", "_onMouseDown");
+ },
+
+ _setDisabledAttr: function(/*Boolean*/ value){
+ this._set("disabled", value);
+ dojo.attr(this.focusNode, 'disabled', value);
+ if(this.valueNode){
+ dojo.attr(this.valueNode, 'disabled', value);
+ }
+ dijit.setWaiState(this.focusNode, "disabled", value);
+
+ if(value){
+ // reset these, because after the domNode is disabled, we can no longer receive
+ // mouse related events, see #4200
+ this._set("hovering", false);
+ this._set("active", false);
+
+ // clear tab stop(s) on this widget's focusable node(s) (ComboBox has two focusable nodes)
+ var attachPointNames = "tabIndex" in this.attributeMap ? this.attributeMap.tabIndex : "focusNode";
+ dojo.forEach(dojo.isArray(attachPointNames) ? attachPointNames : [attachPointNames], function(attachPointName){
+ var node = this[attachPointName];
+ // complex code because tabIndex=-1 on a <div> doesn't work on FF
+ if(dojo.isWebKit || dijit.hasDefaultTabStop(node)){ // see #11064 about webkit bug
+ node.setAttribute('tabIndex', "-1");
+ }else{
+ node.removeAttribute('tabIndex');
+ }
+ }, this);
+ }else{
+ if(this.tabIndex != ""){
+ this.focusNode.setAttribute('tabIndex', this.tabIndex);
+ }
+ }
+ },
+
+ setDisabled: function(/*Boolean*/ disabled){
+ // summary:
+ // Deprecated. Use set('disabled', ...) instead.
+ dojo.deprecated("setDisabled("+disabled+") is deprecated. Use set('disabled',"+disabled+") instead.", "", "2.0");
+ this.set('disabled', disabled);
+ },
+
+ _onFocus: function(e){
+ if(this.scrollOnFocus){
+ dojo.window.scrollIntoView(this.domNode);
+ }
+ this.inherited(arguments);
+ },
+
+ isFocusable: function(){
+ // summary:
+ // Tells if this widget is focusable or not. Used internally by dijit.
+ // tags:
+ // protected
+ return !this.disabled && this.focusNode && (dojo.style(this.domNode, "display") != "none");
+ },
+
+ focus: function(){
+ // summary:
+ // Put focus on this widget
+ if(!this.disabled){
+ dijit.focus(this.focusNode);
+ }
+ },
+
+ compare: function(/*anything*/ val1, /*anything*/ val2){
+ // summary:
+ // Compare 2 values (as returned by get('value') for this widget).
+ // tags:
+ // protected
+ if(typeof val1 == "number" && typeof val2 == "number"){
+ return (isNaN(val1) && isNaN(val2)) ? 0 : val1 - val2;
+ }else if(val1 > val2){
+ return 1;
+ }else if(val1 < val2){
+ return -1;
+ }else{
+ return 0;
+ }
+ },
+
+ onChange: function(newValue){
+ // summary:
+ // Callback when this widget's value is changed.
+ // tags:
+ // callback
+ },
+
+ // _onChangeActive: [private] Boolean
+ // Indicates that changes to the value should call onChange() callback.
+ // This is false during widget initialization, to avoid calling onChange()
+ // when the initial value is set.
+ _onChangeActive: false,
+
+ _handleOnChange: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
+ // summary:
+ // Called when the value of the widget is set. Calls onChange() if appropriate
+ // newValue:
+ // the new value
+ // priorityChange:
+ // For a slider, for example, dragging the slider is priorityChange==false,
+ // but on mouse up, it's priorityChange==true. If intermediateChanges==false,
+ // onChange is only called form priorityChange=true events.
+ // tags:
+ // private
+ if(this._lastValueReported == undefined && (priorityChange === null || !this._onChangeActive)){
+ // this block executes not for a change, but during initialization,
+ // and is used to store away the original value (or for ToggleButton, the original checked state)
+ this._resetValue = this._lastValueReported = newValue;
+ }
+ this._pendingOnChange = this._pendingOnChange
+ || (typeof newValue != typeof this._lastValueReported)
+ || (this.compare(newValue, this._lastValueReported) != 0);
+ if((this.intermediateChanges || priorityChange || priorityChange === undefined) && this._pendingOnChange){
+ this._lastValueReported = newValue;
+ this._pendingOnChange = false;
+ if(this._onChangeActive){
+ if(this._onChangeHandle){
+ clearTimeout(this._onChangeHandle);
+ }
+ // setTimout allows hidden value processing to run and
+ // also the onChange handler can safely adjust focus, etc
+ this._onChangeHandle = setTimeout(dojo.hitch(this,
+ function(){
+ this._onChangeHandle = null;
+ this.onChange(newValue);
+ }), 0); // try to collapse multiple onChange's fired faster than can be processed
+ }
+ }
+ },
+
+ create: function(){
+ // Overrides _Widget.create()
+ this.inherited(arguments);
+ this._onChangeActive = true;
+ },
+
+ destroy: function(){
+ if(this._onChangeHandle){ // destroy called before last onChange has fired
+ clearTimeout(this._onChangeHandle);
+ this.onChange(this._lastValueReported);
+ }
+ this.inherited(arguments);
+ },
+
+ setValue: function(/*String*/ value){
+ // summary:
+ // Deprecated. Use set('value', ...) instead.
+ dojo.deprecated("dijit.form._FormWidget:setValue("+value+") is deprecated. Use set('value',"+value+") instead.", "", "2.0");
+ this.set('value', value);
+ },
+
+ getValue: function(){
+ // summary:
+ // Deprecated. Use get('value') instead.
+ dojo.deprecated(this.declaredClass+"::getValue() is deprecated. Use get('value') instead.", "", "2.0");
+ return this.get('value');
+ },
+
+ _onMouseDown: function(e){
+ // If user clicks on the button, even if the mouse is released outside of it,
+ // this button should get focus (to mimics native browser buttons).
+ // This is also needed on chrome because otherwise buttons won't get focus at all,
+ // which leads to bizarre focus restore on Dialog close etc.
+ if(!e.ctrlKey && dojo.mouseButtons.isLeft(e) && this.isFocusable()){ // !e.ctrlKey to ignore right-click on mac
+ // Set a global event to handle mouseup, so it fires properly
+ // even if the cursor leaves this.domNode before the mouse up event.
+ var mouseUpConnector = this.connect(dojo.body(), "onmouseup", function(){
+ if (this.isFocusable()) {
+ this.focus();
+ }
+ this.disconnect(mouseUpConnector);
+ });
+ }
+ }
+});
+
+dojo.declare("dijit.form._FormValueWidget", dijit.form._FormWidget,
+{
+ // summary:
+ // Base class for widgets corresponding to native HTML elements such as <input> or <select> that have user changeable values.
+ // description:
+ // Each _FormValueWidget represents a single input value, and has a (possibly hidden) <input> element,
+ // to which it serializes it's input value, so that form submission (either normal submission or via FormBind?)
+ // works as expected.
+
+ // Don't attempt to mixin the 'type', 'name' attributes here programatically -- they must be declared
+ // directly in the template as read by the parser in order to function. IE is known to specifically
+ // require the 'name' attribute at element creation time. See #8484, #8660.
+ // TODO: unclear what that {value: ""} is for; FormWidget.attributeMap copies value to focusNode,
+ // so maybe {value: ""} is so the value *doesn't* get copied to focusNode?
+ // Seems like we really want value removed from attributeMap altogether
+ // (although there's no easy way to do that now)
+
+ // readOnly: Boolean
+ // Should this widget respond to user input?
+ // In markup, this is specified as "readOnly".
+ // Similar to disabled except readOnly form values are submitted.
+ readOnly: false,
+
+ attributeMap: dojo.delegate(dijit.form._FormWidget.prototype.attributeMap, {
+ value: "",
+ readOnly: "focusNode"
+ }),
+
+ _setReadOnlyAttr: function(/*Boolean*/ value){
+ dojo.attr(this.focusNode, 'readOnly', value);
+ dijit.setWaiState(this.focusNode, "readonly", value);
+ this._set("readOnly", value);
+ },
+
+ postCreate: function(){
+ this.inherited(arguments);
+
+ if(dojo.isIE){ // IE won't stop the event with keypress
+ this.connect(this.focusNode || this.domNode, "onkeydown", this._onKeyDown);
+ }
+ // Update our reset value if it hasn't yet been set (because this.set()
+ // is only called when there *is* a value)
+ if(this._resetValue === undefined){
+ this._lastValueReported = this._resetValue = this.value;
+ }
+ },
+
+ _setValueAttr: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
+ // summary:
+ // Hook so set('value', value) works.
+ // description:
+ // Sets the value of the widget.
+ // If the value has changed, then fire onChange event, unless priorityChange
+ // is specified as null (or false?)
+ this._handleOnChange(newValue, priorityChange);
+ },
+
+ _handleOnChange: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
+ // summary:
+ // Called when the value of the widget has changed. Saves the new value in this.value,
+ // and calls onChange() if appropriate. See _FormWidget._handleOnChange() for details.
+ this._set("value", newValue);
+ this.inherited(arguments);
+ },
+
+ undo: function(){
+ // summary:
+ // Restore the value to the last value passed to onChange
+ this._setValueAttr(this._lastValueReported, false);
+ },
+
+ reset: function(){
+ // summary:
+ // Reset the widget's value to what it was at initialization time
+ this._hasBeenBlurred = false;
+ this._setValueAttr(this._resetValue, true);
+ },
+
+ _onKeyDown: function(e){
+ if(e.keyCode == dojo.keys.ESCAPE && !(e.ctrlKey || e.altKey || e.metaKey)){
+ var te;
+ if(dojo.isIE){
+ e.preventDefault(); // default behavior needs to be stopped here since keypress is too late
+ te = document.createEventObject();
+ te.keyCode = dojo.keys.ESCAPE;
+ te.shiftKey = e.shiftKey;
+ e.srcElement.fireEvent('onkeypress', te);
+ }
+ }
+ },
+
+ _layoutHackIE7: function(){
+ // summary:
+ // Work around table sizing bugs on IE7 by forcing redraw
+
+ if(dojo.isIE == 7){ // fix IE7 layout bug when the widget is scrolled out of sight
+ var domNode = this.domNode;
+ var parent = domNode.parentNode;
+ var pingNode = domNode.firstChild || domNode; // target node most unlikely to have a custom filter
+ var origFilter = pingNode.style.filter; // save custom filter, most likely nothing
+ var _this = this;
+ while(parent && parent.clientHeight == 0){ // search for parents that haven't rendered yet
+ (function ping(){
+ var disconnectHandle = _this.connect(parent, "onscroll",
+ function(e){
+ _this.disconnect(disconnectHandle); // only call once
+ pingNode.style.filter = (new Date()).getMilliseconds(); // set to anything that's unique
+ setTimeout(function(){ pingNode.style.filter = origFilter }, 0); // restore custom filter, if any
+ }
+ );
+ })();
+ parent = parent.parentNode;
+ }
+ }
+ }
+});
+
+}
+
+if(!dojo._hasResource["dijit.dijit"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.dijit"] = true;
+dojo.provide("dijit.dijit");
+
+
+
+
+
+
+
+
+
+
+/*=====
+dijit.dijit = {
+ // summary:
+ // A roll-up for common dijit methods
+ // description:
+ // A rollup file for the build system including the core and common
+ // dijit files.
+ //
+ // example:
+ // | <script type="text/javascript" src="js/dojo/dijit/dijit.js"></script>
+ //
+};
+=====*/
+
+// All the stuff in _base (these are the function that are guaranteed available without an explicit dojo.require)
+
+// And some other stuff that we tend to pull in all the time anyway
+
+}
+
+if(!dojo._hasResource["dijit._KeyNavContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._KeyNavContainer"] = true;
+dojo.provide("dijit._KeyNavContainer");
+
+
+
+
+dojo.declare("dijit._KeyNavContainer",
+ dijit._Container,
+ {
+
+ // summary:
+ // A _Container with keyboard navigation of its children.
+ // description:
+ // To use this mixin, call connectKeyNavHandlers() in
+ // postCreate() and call startupKeyNavChildren() in startup().
+ // It provides normalized keyboard and focusing code for Container
+ // widgets.
+/*=====
+ // focusedChild: [protected] Widget
+ // The currently focused child widget, or null if there isn't one
+ focusedChild: null,
+=====*/
+
+ // tabIndex: Integer
+ // Tab index of the container; same as HTML tabIndex attribute.
+ // Note then when user tabs into the container, focus is immediately
+ // moved to the first item in the container.
+ tabIndex: "0",
+
+ _keyNavCodes: {},
+
+ connectKeyNavHandlers: function(/*dojo.keys[]*/ prevKeyCodes, /*dojo.keys[]*/ nextKeyCodes){
+ // summary:
+ // Call in postCreate() to attach the keyboard handlers
+ // to the container.
+ // preKeyCodes: dojo.keys[]
+ // Key codes for navigating to the previous child.
+ // nextKeyCodes: dojo.keys[]
+ // Key codes for navigating to the next child.
+ // tags:
+ // protected
+
+ var keyCodes = (this._keyNavCodes = {});
+ var prev = dojo.hitch(this, this.focusPrev);
+ var next = dojo.hitch(this, this.focusNext);
+ dojo.forEach(prevKeyCodes, function(code){ keyCodes[code] = prev; });
+ dojo.forEach(nextKeyCodes, function(code){ keyCodes[code] = next; });
+ keyCodes[dojo.keys.HOME] = dojo.hitch(this, "focusFirstChild");
+ keyCodes[dojo.keys.END] = dojo.hitch(this, "focusLastChild");
+ this.connect(this.domNode, "onkeypress", "_onContainerKeypress");
+ this.connect(this.domNode, "onfocus", "_onContainerFocus");
+ },
+
+ startupKeyNavChildren: function(){
+ // summary:
+ // Call in startup() to set child tabindexes to -1
+ // tags:
+ // protected
+ dojo.forEach(this.getChildren(), dojo.hitch(this, "_startupChild"));
+ },
+
+ addChild: function(/*dijit._Widget*/ widget, /*int?*/ insertIndex){
+ // summary:
+ // Add a child to our _Container
+ dijit._KeyNavContainer.superclass.addChild.apply(this, arguments);
+ this._startupChild(widget);
+ },
+
+ focus: function(){
+ // summary:
+ // Default focus() implementation: focus the first child.
+ this.focusFirstChild();
+ },
+
+ focusFirstChild: function(){
+ // summary:
+ // Focus the first focusable child in the container.
+ // tags:
+ // protected
+ var child = this._getFirstFocusableChild();
+ if(child){ // edge case: Menu could be empty or hidden
+ this.focusChild(child);
+ }
+ },
+
+ focusLastChild: function(){
+ // summary:
+ // Focus the last focusable child in the container.
+ // tags:
+ // protected
+ var child = this._getLastFocusableChild();
+ if(child){ // edge case: Menu could be empty or hidden
+ this.focusChild(child);
+ }
+ },
+
+ focusNext: function(){
+ // summary:
+ // Focus the next widget
+ // tags:
+ // protected
+ var child = this._getNextFocusableChild(this.focusedChild, 1);
+ this.focusChild(child);
+ },
+
+ focusPrev: function(){
+ // summary:
+ // Focus the last focusable node in the previous widget
+ // (ex: go to the ComboButton icon section rather than button section)
+ // tags:
+ // protected
+ var child = this._getNextFocusableChild(this.focusedChild, -1);
+ this.focusChild(child, true);
+ },
+
+ focusChild: function(/*dijit._Widget*/ widget, /*Boolean*/ last){
+ // summary:
+ // Focus widget.
+ // widget:
+ // Reference to container's child widget
+ // last:
+ // If true and if widget has multiple focusable nodes, focus the
+ // last one instead of the first one
+ // tags:
+ // protected
+
+ if(this.focusedChild && widget !== this.focusedChild){
+ this._onChildBlur(this.focusedChild);
+ }
+ widget.focus(last ? "end" : "start");
+ this._set("focusedChild", widget);
+ },
+
+ _startupChild: function(/*dijit._Widget*/ widget){
+ // summary:
+ // Setup for each child widget
+ // description:
+ // Sets tabIndex=-1 on each child, so that the tab key will
+ // leave the container rather than visiting each child.
+ // tags:
+ // private
+
+ widget.set("tabIndex", "-1");
+
+ this.connect(widget, "_onFocus", function(){
+ // Set valid tabIndex so tabbing away from widget goes to right place, see #10272
+ widget.set("tabIndex", this.tabIndex);
+ });
+ this.connect(widget, "_onBlur", function(){
+ widget.set("tabIndex", "-1");
+ });
+ },
+
+ _onContainerFocus: function(evt){
+ // summary:
+ // Handler for when the container gets focus
+ // description:
+ // Initially the container itself has a tabIndex, but when it gets
+ // focus, switch focus to first child...
+ // tags:
+ // private
+
+ // Note that we can't use _onFocus() because switching focus from the
+ // _onFocus() handler confuses the focus.js code
+ // (because it causes _onFocusNode() to be called recursively)
+
+ // focus bubbles on Firefox,
+ // so just make sure that focus has really gone to the container
+ if(evt.target !== this.domNode){ return; }
+
+ this.focusFirstChild();
+
+ // and then set the container's tabIndex to -1,
+ // (don't remove as that breaks Safari 4)
+ // so that tab or shift-tab will go to the fields after/before
+ // the container, rather than the container itself
+ dojo.attr(this.domNode, "tabIndex", "-1");
+ },
+
+ _onBlur: function(evt){
+ // When focus is moved away the container, and its descendant (popup) widgets,
+ // then restore the container's tabIndex so that user can tab to it again.
+ // Note that using _onBlur() so that this doesn't happen when focus is shifted
+ // to one of my child widgets (typically a popup)
+ if(this.tabIndex){
+ dojo.attr(this.domNode, "tabIndex", this.tabIndex);
+ }
+ this.inherited(arguments);
+ },
+
+ _onContainerKeypress: function(evt){
+ // summary:
+ // When a key is pressed, if it's an arrow key etc. then
+ // it's handled here.
+ // tags:
+ // private
+ if(evt.ctrlKey || evt.altKey){ return; }
+ var func = this._keyNavCodes[evt.charOrCode];
+ if(func){
+ func();
+ dojo.stopEvent(evt);
+ }
+ },
+
+ _onChildBlur: function(/*dijit._Widget*/ widget){
+ // summary:
+ // Called when focus leaves a child widget to go
+ // to a sibling widget.
+ // tags:
+ // protected
+ },
+
+ _getFirstFocusableChild: function(){
+ // summary:
+ // Returns first child that can be focused
+ return this._getNextFocusableChild(null, 1); // dijit._Widget
+ },
+
+ _getLastFocusableChild: function(){
+ // summary:
+ // Returns last child that can be focused
+ return this._getNextFocusableChild(null, -1); // dijit._Widget
+ },
+
+ _getNextFocusableChild: function(child, dir){
+ // summary:
+ // Returns the next or previous focusable child, compared
+ // to "child"
+ // child: Widget
+ // The current widget
+ // dir: Integer
+ // * 1 = after
+ // * -1 = before
+ if(child){
+ child = this._getSiblingOfChild(child, dir);
+ }
+ var children = this.getChildren();
+ for(var i=0; i < children.length; i++){
+ if(!child){
+ child = children[(dir>0) ? 0 : (children.length-1)];
+ }
+ if(child.isFocusable()){
+ return child; // dijit._Widget
+ }
+ child = this._getSiblingOfChild(child, dir);
+ }
+ // no focusable child found
+ return null; // dijit._Widget
+ }
+ }
+);
+
+}
+
+if(!dojo._hasResource["dijit.MenuItem"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.MenuItem"] = true;
+dojo.provide("dijit.MenuItem");
+
+
+
+
+
+
+
+dojo.declare("dijit.MenuItem",
+ [dijit._Widget, dijit._Templated, dijit._Contained, dijit._CssStateMixin],
+ {
+ // summary:
+ // A line item in a Menu Widget
+
+ // Make 3 columns
+ // icon, label, and expand arrow (BiDi-dependent) indicating sub-menu
+ templateString: dojo.cache("dijit", "templates/MenuItem.html", "<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" role=\"menuitem\" tabIndex=\"-1\"\r\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\r\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\r\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitIcon dijitMenuItemIcon\" dojoAttachPoint=\"iconNode\"/>\r\n\t</td>\r\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" dojoAttachPoint=\"containerNode\"></td>\r\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" dojoAttachPoint=\"accelKeyNode\"></td>\r\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">\r\n\t\t<div dojoAttachPoint=\"arrowWrapper\" style=\"visibility: hidden\">\r\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuExpand\"/>\r\n\t\t\t<span class=\"dijitMenuExpandA11y\">+</span>\r\n\t\t</div>\r\n\t</td>\r\n</tr>\r\n"),
+
+ attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
+ label: { node: "containerNode", type: "innerHTML" },
+ iconClass: { node: "iconNode", type: "class" }
+ }),
+
+ baseClass: "dijitMenuItem",
+
+ // label: String
+ // Menu text
+ label: '',
+
+ // iconClass: String
+ // Class to apply to DOMNode to make it display an icon.
+ iconClass: "",
+
+ // accelKey: String
+ // Text for the accelerator (shortcut) key combination.
+ // Note that although Menu can display accelerator keys there
+ // is no infrastructure to actually catch and execute these
+ // accelerators.
+ accelKey: "",
+
+ // disabled: Boolean
+ // If true, the menu item is disabled.
+ // If false, the menu item is enabled.
+ disabled: false,
+
+ _fillContent: function(/*DomNode*/ source){
+ // If button label is specified as srcNodeRef.innerHTML rather than
+ // this.params.label, handle it here.
+ if(source && !("label" in this.params)){
+ this.set('label', source.innerHTML);
+ }
+ },
+
+ buildRendering: function(){
+ this.inherited(arguments);
+ var label = this.id+"_text";
+ dojo.attr(this.containerNode, "id", label);
+ if(this.accelKeyNode){
+ dojo.attr(this.accelKeyNode, "id", this.id + "_accel");
+ label += " " + this.id + "_accel";
+ }
+ dijit.setWaiState(this.domNode, "labelledby", label);
+ dojo.setSelectable(this.domNode, false);
+ },
+
+ _onHover: function(){
+ // summary:
+ // Handler when mouse is moved onto menu item
+ // tags:
+ // protected
+ this.getParent().onItemHover(this);
+ },
+
+ _onUnhover: function(){
+ // summary:
+ // Handler when mouse is moved off of menu item,
+ // possibly to a child menu, or maybe to a sibling
+ // menuitem or somewhere else entirely.
+ // tags:
+ // protected
+
+ // if we are unhovering the currently selected item
+ // then unselect it
+ this.getParent().onItemUnhover(this);
+
+ // When menu is hidden (collapsed) due to clicking a MenuItem and having it execute,
+ // FF and IE don't generate an onmouseout event for the MenuItem.
+ // So, help out _CssStateMixin in this case.
+ this._set("hovering", false);
+ },
+
+ _onClick: function(evt){
+ // summary:
+ // Internal handler for click events on MenuItem.
+ // tags:
+ // private
+ this.getParent().onItemClick(this, evt);
+ dojo.stopEvent(evt);
+ },
+
+ onClick: function(/*Event*/ evt){
+ // summary:
+ // User defined function to handle clicks
+ // tags:
+ // callback
+ },
+
+ focus: function(){
+ // summary:
+ // Focus on this MenuItem
+ try{
+ if(dojo.isIE == 8){
+ // needed for IE8 which won't scroll TR tags into view on focus yet calling scrollIntoView creates flicker (#10275)
+ this.containerNode.focus();
+ }
+ dijit.focus(this.focusNode);
+ }catch(e){
+ // this throws on IE (at least) in some scenarios
+ }
+ },
+
+ _onFocus: function(){
+ // summary:
+ // This is called by the focus manager when focus
+ // goes to this MenuItem or a child menu.
+ // tags:
+ // protected
+ this._setSelected(true);
+ this.getParent()._onItemFocus(this);
+
+ this.inherited(arguments);
+ },
+
+ _setSelected: function(selected){
+ // summary:
+ // Indicate that this node is the currently selected one
+ // tags:
+ // private
+
+ /***
+ * TODO: remove this method and calls to it, when _onBlur() is working for MenuItem.
+ * Currently _onBlur() gets called when focus is moved from the MenuItem to a child menu.
+ * That's not supposed to happen, but the problem is:
+ * In order to allow dijit.popup's getTopPopup() to work,a sub menu's popupParent
+ * points to the parent Menu, bypassing the parent MenuItem... thus the
+ * MenuItem is not in the chain of active widgets and gets a premature call to
+ * _onBlur()
+ */
+
+ dojo.toggleClass(this.domNode, "dijitMenuItemSelected", selected);
+ },
+
+ setLabel: function(/*String*/ content){
+ // summary:
+ // Deprecated. Use set('label', ...) instead.
+ // tags:
+ // deprecated
+ dojo.deprecated("dijit.MenuItem.setLabel() is deprecated. Use set('label', ...) instead.", "", "2.0");
+ this.set("label", content);
+ },
+
+ setDisabled: function(/*Boolean*/ disabled){
+ // summary:
+ // Deprecated. Use set('disabled', bool) instead.
+ // tags:
+ // deprecated
+ dojo.deprecated("dijit.Menu.setDisabled() is deprecated. Use set('disabled', bool) instead.", "", "2.0");
+ this.set('disabled', disabled);
+ },
+ _setDisabledAttr: function(/*Boolean*/ value){
+ // summary:
+ // Hook for attr('disabled', ...) to work.
+ // Enable or disable this menu item.
+
+ dijit.setWaiState(this.focusNode, 'disabled', value ? 'true' : 'false');
+ this._set("disabled", value);
+ },
+ _setAccelKeyAttr: function(/*String*/ value){
+ // summary:
+ // Hook for attr('accelKey', ...) to work.
+ // Set accelKey on this menu item.
+
+ this.accelKeyNode.style.display=value?"":"none";
+ this.accelKeyNode.innerHTML=value;
+ //have to use colSpan to make it work in IE
+ dojo.attr(this.containerNode,'colSpan',value?"1":"2");
+
+ this._set("accelKey", value);
+ }
+ });
+
+}
+
+if(!dojo._hasResource["dijit.PopupMenuItem"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.PopupMenuItem"] = true;
+dojo.provide("dijit.PopupMenuItem");
+
+
+
+
+dojo.declare("dijit.PopupMenuItem",
+ dijit.MenuItem,
+ {
+ _fillContent: function(){
+ // summary:
+ // When Menu is declared in markup, this code gets the menu label and
+ // the popup widget from the srcNodeRef.
+ // description:
+ // srcNodeRefinnerHTML contains both the menu item text and a popup widget
+ // The first part holds the menu item text and the second part is the popup
+ // example:
+ // | <div dojoType="dijit.PopupMenuItem">
+ // | <span>pick me</span>
+ // | <popup> ... </popup>
+ // | </div>
+ // tags:
+ // protected
+
+ if(this.srcNodeRef){
+ var nodes = dojo.query("*", this.srcNodeRef);
+ dijit.PopupMenuItem.superclass._fillContent.call(this, nodes[0]);
+
+ // save pointer to srcNode so we can grab the drop down widget after it's instantiated
+ this.dropDownContainer = this.srcNodeRef;
+ }
+ },
+
+ startup: function(){
+ if(this._started){ return; }
+ this.inherited(arguments);
+
+ // we didn't copy the dropdown widget from the this.srcNodeRef, so it's in no-man's
+ // land now. move it to dojo.doc.body.
+ if(!this.popup){
+ var node = dojo.query("[widgetId]", this.dropDownContainer)[0];
+ this.popup = dijit.byNode(node);
+ }
+ dojo.body().appendChild(this.popup.domNode);
+ this.popup.startup();
+
+ this.popup.domNode.style.display="none";
+ if(this.arrowWrapper){
+ dojo.style(this.arrowWrapper, "visibility", "");
+ }
+ dijit.setWaiState(this.focusNode, "haspopup", "true");
+ },
+
+ destroyDescendants: function(){
+ if(this.popup){
+ // Destroy the popup, unless it's already been destroyed. This can happen because
+ // the popup is a direct child of <body> even though it's logically my child.
+ if(!this.popup._destroyed){
+ this.popup.destroyRecursive();
+ }
+ delete this.popup;
+ }
+ this.inherited(arguments);
+ }
+ });
+
+}
+
+if(!dojo._hasResource["dijit.CheckedMenuItem"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.CheckedMenuItem"] = true;
+dojo.provide("dijit.CheckedMenuItem");
+
+
+
+
+dojo.declare("dijit.CheckedMenuItem",
+ dijit.MenuItem,
+ {
+ // summary:
+ // A checkbox-like menu item for toggling on and off
+
+ templateString: dojo.cache("dijit", "templates/CheckedMenuItem.html", "<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" role=\"menuitemcheckbox\" tabIndex=\"-1\"\r\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\r\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\r\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" dojoAttachPoint=\"iconNode\"/>\r\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">&#10003;</span>\r\n\t</td>\r\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" dojoAttachPoint=\"containerNode,labelNode\"></td>\r\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" dojoAttachPoint=\"accelKeyNode\"></td>\r\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">&nbsp;</td>\r\n</tr>\r\n"),
+
+ // checked: Boolean
+ // Our checked state
+ checked: false,
+ _setCheckedAttr: function(/*Boolean*/ checked){
+ // summary:
+ // Hook so attr('checked', bool) works.
+ // Sets the class and state for the check box.
+ dojo.toggleClass(this.domNode, "dijitCheckedMenuItemChecked", checked);
+ dijit.setWaiState(this.domNode, "checked", checked);
+ this._set("checked", checked);
+ },
+
+ onChange: function(/*Boolean*/ checked){
+ // summary:
+ // User defined function to handle check/uncheck events
+ // tags:
+ // callback
+ },
+
+ _onClick: function(/*Event*/ e){
+ // summary:
+ // Clicking this item just toggles its state
+ // tags:
+ // private
+ if(!this.disabled){
+ this.set("checked", !this.checked);
+ this.onChange(this.checked);
+ }
+ this.inherited(arguments);
+ }
+ });
+
+}
+
+if(!dojo._hasResource["dijit.MenuSeparator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.MenuSeparator"] = true;
+dojo.provide("dijit.MenuSeparator");
+
+
+
+
+
+
+dojo.declare("dijit.MenuSeparator",
+ [dijit._Widget, dijit._Templated, dijit._Contained],
+ {
+ // summary:
+ // A line between two menu items
+
+ templateString: dojo.cache("dijit", "templates/MenuSeparator.html", "<tr class=\"dijitMenuSeparator\">\r\n\t<td class=\"dijitMenuSeparatorIconCell\">\r\n\t\t<div class=\"dijitMenuSeparatorTop\"></div>\r\n\t\t<div class=\"dijitMenuSeparatorBottom\"></div>\r\n\t</td>\r\n\t<td colspan=\"3\" class=\"dijitMenuSeparatorLabelCell\">\r\n\t\t<div class=\"dijitMenuSeparatorTop dijitMenuSeparatorLabel\"></div>\r\n\t\t<div class=\"dijitMenuSeparatorBottom\"></div>\r\n\t</td>\r\n</tr>\r\n"),
+
+ buildRendering: function(){
+ this.inherited(arguments);
+ dojo.setSelectable(this.domNode, false);
+ },
+
+ isFocusable: function(){
+ // summary:
+ // Override to always return false
+ // tags:
+ // protected
+
+ return false; // Boolean
+ }
+ });
+
+}
+
+if(!dojo._hasResource["dijit.Menu"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.Menu"] = true;
+dojo.provide("dijit.Menu");
+
+
+
+
+
+
+
+
+
+
+
+// "dijit/MenuItem", "dijit/PopupMenuItem", "dijit/CheckedMenuItem", "dijit/MenuSeparator" for Back-compat (TODO: remove in 2.0)
+
+dojo.declare("dijit._MenuBase",
+ [dijit._Widget, dijit._Templated, dijit._KeyNavContainer],
+{
+ // summary:
+ // Base class for Menu and MenuBar
+
+ // parentMenu: [readonly] Widget
+ // pointer to menu that displayed me
+ parentMenu: null,
+
+ // popupDelay: Integer
+ // number of milliseconds before hovering (without clicking) causes the popup to automatically open.
+ popupDelay: 500,
+
+ startup: function(){
+ if(this._started){ return; }
+
+ dojo.forEach(this.getChildren(), function(child){ child.startup(); });
+ this.startupKeyNavChildren();
+
+ this.inherited(arguments);
+ },
+
+ onExecute: function(){
+ // summary:
+ // Attach point for notification about when a menu item has been executed.
+ // This is an internal mechanism used for Menus to signal to their parent to
+ // close them, because they are about to execute the onClick handler. In
+ // general developers should not attach to or override this method.
+ // tags:
+ // protected
+ },
+
+ onCancel: function(/*Boolean*/ closeAll){
+ // summary:
+ // Attach point for notification about when the user cancels the current menu
+ // This is an internal mechanism used for Menus to signal to their parent to
+ // close them. In general developers should not attach to or override this method.
+ // tags:
+ // protected
+ },
+
+ _moveToPopup: function(/*Event*/ evt){
+ // summary:
+ // This handles the right arrow key (left arrow key on RTL systems),
+ // which will either open a submenu, or move to the next item in the
+ // ancestor MenuBar
+ // tags:
+ // private
+
+ if(this.focusedChild && this.focusedChild.popup && !this.focusedChild.disabled){
+ this.focusedChild._onClick(evt);
+ }else{
+ var topMenu = this._getTopMenu();
+ if(topMenu && topMenu._isMenuBar){
+ topMenu.focusNext();
+ }
+ }
+ },
+
+ _onPopupHover: function(/*Event*/ evt){
+ // summary:
+ // This handler is called when the mouse moves over the popup.
+ // tags:
+ // private
+
+ // if the mouse hovers over a menu popup that is in pending-close state,
+ // then stop the close operation.
+ // This can't be done in onItemHover since some popup targets don't have MenuItems (e.g. ColorPicker)
+ if(this.currentPopup && this.currentPopup._pendingClose_timer){
+ var parentMenu = this.currentPopup.parentMenu;
+ // highlight the parent menu item pointing to this popup
+ if(parentMenu.focusedChild){
+ parentMenu.focusedChild._setSelected(false);
+ }
+ parentMenu.focusedChild = this.currentPopup.from_item;
+ parentMenu.focusedChild._setSelected(true);
+ // cancel the pending close
+ this._stopPendingCloseTimer(this.currentPopup);
+ }
+ },
+
+ onItemHover: function(/*MenuItem*/ item){
+ // summary:
+ // Called when cursor is over a MenuItem.
+ // tags:
+ // protected
+
+ // Don't do anything unless user has "activated" the menu by:
+ // 1) clicking it
+ // 2) opening it from a parent menu (which automatically focuses it)
+ if(this.isActive){
+ this.focusChild(item);
+ if(this.focusedChild.popup && !this.focusedChild.disabled && !this.hover_timer){
+ this.hover_timer = setTimeout(dojo.hitch(this, "_openPopup"), this.popupDelay);
+ }
+ }
+ // if the user is mixing mouse and keyboard navigation,
+ // then the menu may not be active but a menu item has focus,
+ // but it's not the item that the mouse just hovered over.
+ // To avoid both keyboard and mouse selections, use the latest.
+ if(this.focusedChild){
+ this.focusChild(item);
+ }
+ this._hoveredChild = item;
+ },
+
+ _onChildBlur: function(item){
+ // summary:
+ // Called when a child MenuItem becomes inactive because focus
+ // has been removed from the MenuItem *and* it's descendant menus.
+ // tags:
+ // private
+ this._stopPopupTimer();
+ item._setSelected(false);
+ // Close all popups that are open and descendants of this menu
+ var itemPopup = item.popup;
+ if(itemPopup){
+ this._stopPendingCloseTimer(itemPopup);
+ itemPopup._pendingClose_timer = setTimeout(function(){
+ itemPopup._pendingClose_timer = null;
+ if(itemPopup.parentMenu){
+ itemPopup.parentMenu.currentPopup = null;
+ }
+ dijit.popup.close(itemPopup); // this calls onClose
+ }, this.popupDelay);
+ }
+ },
+
+ onItemUnhover: function(/*MenuItem*/ item){
+ // summary:
+ // Callback fires when mouse exits a MenuItem
+ // tags:
+ // protected
+
+ if(this.isActive){
+ this._stopPopupTimer();
+ }
+ if(this._hoveredChild == item){ this._hoveredChild = null; }
+ },
+
+ _stopPopupTimer: function(){
+ // summary:
+ // Cancels the popup timer because the user has stop hovering
+ // on the MenuItem, etc.
+ // tags:
+ // private
+ if(this.hover_timer){
+ clearTimeout(this.hover_timer);
+ this.hover_timer = null;
+ }
+ },
+
+ _stopPendingCloseTimer: function(/*dijit._Widget*/ popup){
+ // summary:
+ // Cancels the pending-close timer because the close has been preempted
+ // tags:
+ // private
+ if(popup._pendingClose_timer){
+ clearTimeout(popup._pendingClose_timer);
+ popup._pendingClose_timer = null;
+ }
+ },
+
+ _stopFocusTimer: function(){
+ // summary:
+ // Cancels the pending-focus timer because the menu was closed before focus occured
+ // tags:
+ // private
+ if(this._focus_timer){
+ clearTimeout(this._focus_timer);
+ this._focus_timer = null;
+ }
+ },
+
+ _getTopMenu: function(){
+ // summary:
+ // Returns the top menu in this chain of Menus
+ // tags:
+ // private
+ for(var top=this; top.parentMenu; top=top.parentMenu);
+ return top;
+ },
+
+ onItemClick: function(/*dijit._Widget*/ item, /*Event*/ evt){
+ // summary:
+ // Handle clicks on an item.
+ // tags:
+ // private
+
+ // this can't be done in _onFocus since the _onFocus events occurs asynchronously
+ if(typeof this.isShowingNow == 'undefined'){ // non-popup menu
+ this._markActive();
+ }
+
+ this.focusChild(item);
+
+ if(item.disabled){ return false; }
+
+ if(item.popup){
+ this._openPopup();
+ }else{
+ // before calling user defined handler, close hierarchy of menus
+ // and restore focus to place it was when menu was opened
+ this.onExecute();
+
+ // user defined handler for click
+ item.onClick(evt);
+ }
+ },
+
+ _openPopup: function(){
+ // summary:
+ // Open the popup to the side of/underneath the current menu item
+ // tags:
+ // protected
+
+ this._stopPopupTimer();
+ var from_item = this.focusedChild;
+ if(!from_item){ return; } // the focused child lost focus since the timer was started
+ var popup = from_item.popup;
+ if(popup.isShowingNow){ return; }
+ if(this.currentPopup){
+ this._stopPendingCloseTimer(this.currentPopup);
+ dijit.popup.close(this.currentPopup);
+ }
+ popup.parentMenu = this;
+ popup.from_item = from_item; // helps finding the parent item that should be focused for this popup
+ var self = this;
+ dijit.popup.open({
+ parent: this,
+ popup: popup,
+ around: from_item.domNode,
+ orient: this._orient || (this.isLeftToRight() ?
+ {'TR': 'TL', 'TL': 'TR', 'BR': 'BL', 'BL': 'BR'} :
+ {'TL': 'TR', 'TR': 'TL', 'BL': 'BR', 'BR': 'BL'}),
+ onCancel: function(){ // called when the child menu is canceled
+ // set isActive=false (_closeChild vs _cleanUp) so that subsequent hovering will NOT open child menus
+ // which seems aligned with the UX of most applications (e.g. notepad, wordpad, paint shop pro)
+ self.focusChild(from_item); // put focus back on my node
+ self._cleanUp(); // close the submenu (be sure this is done _after_ focus is moved)
+ from_item._setSelected(true); // oops, _cleanUp() deselected the item
+ self.focusedChild = from_item; // and unset focusedChild
+ },
+ onExecute: dojo.hitch(this, "_cleanUp")
+ });
+
+ this.currentPopup = popup;
+ // detect mouseovers to handle lazy mouse movements that temporarily focus other menu items
+ popup.connect(popup.domNode, "onmouseenter", dojo.hitch(self, "_onPopupHover")); // cleaned up when the popped-up widget is destroyed on close
+
+ if(popup.focus){
+ // If user is opening the popup via keyboard (right arrow, or down arrow for MenuBar),
+ // if the cursor happens to collide with the popup, it will generate an onmouseover event
+ // even though the mouse wasn't moved. Use a setTimeout() to call popup.focus so that
+ // our focus() call overrides the onmouseover event, rather than vice-versa. (#8742)
+ popup._focus_timer = setTimeout(dojo.hitch(popup, function(){
+ this._focus_timer = null;
+ this.focus();
+ }), 0);
+ }
+ },
+
+ _markActive: function(){
+ // summary:
+ // Mark this menu's state as active.
+ // Called when this Menu gets focus from:
+ // 1) clicking it (mouse or via space/arrow key)
+ // 2) being opened by a parent menu.
+ // This is not called just from mouse hover.
+ // Focusing a menu via TAB does NOT automatically set isActive
+ // since TAB is a navigation operation and not a selection one.
+ // For Windows apps, pressing the ALT key focuses the menubar
+ // menus (similar to TAB navigation) but the menu is not active
+ // (ie no dropdown) until an item is clicked.
+ this.isActive = true;
+ dojo.replaceClass(this.domNode, "dijitMenuActive", "dijitMenuPassive");
+ },
+
+ onOpen: function(/*Event*/ e){
+ // summary:
+ // Callback when this menu is opened.
+ // This is called by the popup manager as notification that the menu
+ // was opened.
+ // tags:
+ // private
+
+ this.isShowingNow = true;
+ this._markActive();
+ },
+
+ _markInactive: function(){
+ // summary:
+ // Mark this menu's state as inactive.
+ this.isActive = false; // don't do this in _onBlur since the state is pending-close until we get here
+ dojo.replaceClass(this.domNode, "dijitMenuPassive", "dijitMenuActive");
+ },
+
+ onClose: function(){
+ // summary:
+ // Callback when this menu is closed.
+ // This is called by the popup manager as notification that the menu
+ // was closed.
+ // tags:
+ // private
+
+ this._stopFocusTimer();
+ this._markInactive();
+ this.isShowingNow = false;
+ this.parentMenu = null;
+ },
+
+ _closeChild: function(){
+ // summary:
+ // Called when submenu is clicked or focus is lost. Close hierarchy of menus.
+ // tags:
+ // private
+ this._stopPopupTimer();
+
+ var fromItem = this.focusedChild && this.focusedChild.from_item;
+
+ if(this.currentPopup){
+ // If focus is on my child menu then move focus to me,
+ // because IE doesn't like it when you display:none a node with focus
+ if(dijit._curFocus && dojo.isDescendant(dijit._curFocus, this.currentPopup.domNode)){
+ this.focusedChild.focusNode.focus();
+ }
+ // Close all popups that are open and descendants of this menu
+ dijit.popup.close(this.currentPopup);
+ this.currentPopup = null;
+ }
+
+ if(this.focusedChild){ // unhighlight the focused item
+ this.focusedChild._setSelected(false);
+ this.focusedChild._onUnhover();
+ this.focusedChild = null;
+ }
+ },
+
+ _onItemFocus: function(/*MenuItem*/ item){
+ // summary:
+ // Called when child of this Menu gets focus from:
+ // 1) clicking it
+ // 2) tabbing into it
+ // 3) being opened by a parent menu.
+ // This is not called just from mouse hover.
+ if(this._hoveredChild && this._hoveredChild != item){
+ this._hoveredChild._onUnhover(); // any previous mouse movement is trumped by focus selection
+ }
+ },
+
+ _onBlur: function(){
+ // summary:
+ // Called when focus is moved away from this Menu and it's submenus.
+ // tags:
+ // protected
+ this._cleanUp();
+ this.inherited(arguments);
+ },
+
+ _cleanUp: function(){
+ // summary:
+ // Called when the user is done with this menu. Closes hierarchy of menus.
+ // tags:
+ // private
+
+ this._closeChild(); // don't call this.onClose since that's incorrect for MenuBar's that never close
+ if(typeof this.isShowingNow == 'undefined'){ // non-popup menu doesn't call onClose
+ this._markInactive();
+ }
+ }
+});
+
+dojo.declare("dijit.Menu",
+ dijit._MenuBase,
+ {
+ // summary
+ // A context menu you can assign to multiple elements
+
+ // TODO: most of the code in here is just for context menu (right-click menu)
+ // support. In retrospect that should have been a separate class (dijit.ContextMenu).
+ // Split them for 2.0
+
+ constructor: function(){
+ this._bindings = [];
+ },
+
+ templateString: dojo.cache("dijit", "templates/Menu.html", "<table class=\"dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable\" role=\"menu\" tabIndex=\"${tabIndex}\" dojoAttachEvent=\"onkeypress:_onKeyPress\" cellspacing=\"0\">\r\n\t<tbody class=\"dijitReset\" dojoAttachPoint=\"containerNode\"></tbody>\r\n</table>\r\n"),
+
+ baseClass: "dijitMenu",
+
+ // targetNodeIds: [const] String[]
+ // Array of dom node ids of nodes to attach to.
+ // Fill this with nodeIds upon widget creation and it becomes context menu for those nodes.
+ targetNodeIds: [],
+
+ // contextMenuForWindow: [const] Boolean
+ // If true, right clicking anywhere on the window will cause this context menu to open.
+ // If false, must specify targetNodeIds.
+ contextMenuForWindow: false,
+
+ // leftClickToOpen: [const] Boolean
+ // If true, menu will open on left click instead of right click, similiar to a file menu.
+ leftClickToOpen: false,
+
+ // refocus: Boolean
+ // When this menu closes, re-focus the element which had focus before it was opened.
+ refocus: true,
+
+ postCreate: function(){
+ if(this.contextMenuForWindow){
+ this.bindDomNode(dojo.body());
+ }else{
+ // TODO: should have _setTargetNodeIds() method to handle initialization and a possible
+ // later set('targetNodeIds', ...) call. There's also a problem that targetNodeIds[]
+ // gets stale after calls to bindDomNode()/unBindDomNode() as it still is just the original list (see #9610)
+ dojo.forEach(this.targetNodeIds, this.bindDomNode, this);
+ }
+ var k = dojo.keys, l = this.isLeftToRight();
+ this._openSubMenuKey = l ? k.RIGHT_ARROW : k.LEFT_ARROW;
+ this._closeSubMenuKey = l ? k.LEFT_ARROW : k.RIGHT_ARROW;
+ this.connectKeyNavHandlers([k.UP_ARROW], [k.DOWN_ARROW]);
+ },
+
+ _onKeyPress: function(/*Event*/ evt){
+ // summary:
+ // Handle keyboard based menu navigation.
+ // tags:
+ // protected
+
+ if(evt.ctrlKey || evt.altKey){ return; }
+
+ switch(evt.charOrCode){
+ case this._openSubMenuKey:
+ this._moveToPopup(evt);
+ dojo.stopEvent(evt);
+ break;
+ case this._closeSubMenuKey:
+ if(this.parentMenu){
+ if(this.parentMenu._isMenuBar){
+ this.parentMenu.focusPrev();
+ }else{
+ this.onCancel(false);
+ }
+ }else{
+ dojo.stopEvent(evt);
+ }
+ break;
+ }
+ },
+
+ // thanks burstlib!
+ _iframeContentWindow: function(/* HTMLIFrameElement */iframe_el){
+ // summary:
+ // Returns the window reference of the passed iframe
+ // tags:
+ // private
+ var win = dojo.window.get(this._iframeContentDocument(iframe_el)) ||
+ // Moz. TODO: is this available when defaultView isn't?
+ this._iframeContentDocument(iframe_el)['__parent__'] ||
+ (iframe_el.name && dojo.doc.frames[iframe_el.name]) || null;
+ return win; // Window
+ },
+
+ _iframeContentDocument: function(/* HTMLIFrameElement */iframe_el){
+ // summary:
+ // Returns a reference to the document object inside iframe_el
+ // tags:
+ // protected
+ var doc = iframe_el.contentDocument // W3
+ || (iframe_el.contentWindow && iframe_el.contentWindow.document) // IE
+ || (iframe_el.name && dojo.doc.frames[iframe_el.name] && dojo.doc.frames[iframe_el.name].document)
+ || null;
+ return doc; // HTMLDocument
+ },
+
+ bindDomNode: function(/*String|DomNode*/ node){
+ // summary:
+ // Attach menu to given node
+ node = dojo.byId(node);
+
+ var cn; // Connect node
+
+ // Support context menus on iframes. Rather than binding to the iframe itself we need
+ // to bind to the <body> node inside the iframe.
+ if(node.tagName.toLowerCase() == "iframe"){
+ var iframe = node,
+ win = this._iframeContentWindow(iframe);
+ cn = dojo.withGlobal(win, dojo.body);
+ }else{
+
+ // To capture these events at the top level, attach to <html>, not <body>.
+ // Otherwise right-click context menu just doesn't work.
+ cn = (node == dojo.body() ? dojo.doc.documentElement : node);
+ }
+
+
+ // "binding" is the object to track our connection to the node (ie, the parameter to bindDomNode())
+ var binding = {
+ node: node,
+ iframe: iframe
+ };
+
+ // Save info about binding in _bindings[], and make node itself record index(+1) into
+ // _bindings[] array. Prefix w/_dijitMenu to avoid setting an attribute that may
+ // start with a number, which fails on FF/safari.
+ dojo.attr(node, "_dijitMenu" + this.id, this._bindings.push(binding));
+
+ // Setup the connections to monitor click etc., unless we are connecting to an iframe which hasn't finished
+ // loading yet, in which case we need to wait for the onload event first, and then connect
+ // On linux Shift-F10 produces the oncontextmenu event, but on Windows it doesn't, so
+ // we need to monitor keyboard events in addition to the oncontextmenu event.
+ var doConnects = dojo.hitch(this, function(cn){
+ return [
+ // TODO: when leftClickToOpen is true then shouldn't space/enter key trigger the menu,
+ // rather than shift-F10?
+ dojo.connect(cn, this.leftClickToOpen ? "onclick" : "oncontextmenu", this, function(evt){
+ // Schedule context menu to be opened unless it's already been scheduled from onkeydown handler
+ dojo.stopEvent(evt);
+ this._scheduleOpen(evt.target, iframe, {x: evt.pageX, y: evt.pageY});
+ }),
+ dojo.connect(cn, "onkeydown", this, function(evt){
+ if(evt.shiftKey && evt.keyCode == dojo.keys.F10){
+ dojo.stopEvent(evt);
+ this._scheduleOpen(evt.target, iframe); // no coords - open near target node
+ }
+ })
+ ];
+ });
+ binding.connects = cn ? doConnects(cn) : [];
+
+ if(iframe){
+ // Setup handler to [re]bind to the iframe when the contents are initially loaded,
+ // and every time the contents change.
+ // Need to do this b/c we are actually binding to the iframe's <body> node.
+ // Note: can't use dojo.connect(), see #9609.
+
+ binding.onloadHandler = dojo.hitch(this, function(){
+ // want to remove old connections, but IE throws exceptions when trying to
+ // access the <body> node because it's already gone, or at least in a state of limbo
+
+ var win = this._iframeContentWindow(iframe);
+ cn = dojo.withGlobal(win, dojo.body);
+ binding.connects = doConnects(cn);
+ });
+ if(iframe.addEventListener){
+ iframe.addEventListener("load", binding.onloadHandler, false);
+ }else{
+ iframe.attachEvent("onload", binding.onloadHandler);
+ }
+ }
+ },
+
+ unBindDomNode: function(/*String|DomNode*/ nodeName){
+ // summary:
+ // Detach menu from given node
+
+ var node;
+ try{
+ node = dojo.byId(nodeName);
+ }catch(e){
+ // On IE the dojo.byId() call will get an exception if the attach point was
+ // the <body> node of an <iframe> that has since been reloaded (and thus the
+ // <body> node is in a limbo state of destruction.
+ return;
+ }
+
+ // node["_dijitMenu" + this.id] contains index(+1) into my _bindings[] array
+ var attrName = "_dijitMenu" + this.id;
+ if(node && dojo.hasAttr(node, attrName)){
+ var bid = dojo.attr(node, attrName)-1, b = this._bindings[bid];
+ dojo.forEach(b.connects, dojo.disconnect);
+
+ // Remove listener for iframe onload events
+ var iframe = b.iframe;
+ if(iframe){
+ if(iframe.removeEventListener){
+ iframe.removeEventListener("load", b.onloadHandler, false);
+ }else{
+ iframe.detachEvent("onload", b.onloadHandler);
+ }
+ }
+
+ dojo.removeAttr(node, attrName);
+ delete this._bindings[bid];
+ }
+ },
+
+ _scheduleOpen: function(/*DomNode?*/ target, /*DomNode?*/ iframe, /*Object?*/ coords){
+ // summary:
+ // Set timer to display myself. Using a timer rather than displaying immediately solves
+ // two problems:
+ //
+ // 1. IE: without the delay, focus work in "open" causes the system
+ // context menu to appear in spite of stopEvent.
+ //
+ // 2. Avoid double-shows on linux, where shift-F10 generates an oncontextmenu event
+ // even after a dojo.stopEvent(e). (Shift-F10 on windows doesn't generate the
+ // oncontextmenu event.)
+
+ if(!this._openTimer){
+ this._openTimer = setTimeout(dojo.hitch(this, function(){
+ delete this._openTimer;
+ this._openMyself({
+ target: target,
+ iframe: iframe,
+ coords: coords
+ });
+ }), 1);
+ }
+ },
+
+ _openMyself: function(args){
+ // summary:
+ // Internal function for opening myself when the user does a right-click or something similar.
+ // args:
+ // This is an Object containing:
+ // * target:
+ // The node that is being clicked
+ // * iframe:
+ // If an <iframe> is being clicked, iframe points to that iframe
+ // * coords:
+ // Put menu at specified x/y position in viewport, or if iframe is
+ // specified, then relative to iframe.
+ //
+ // _openMyself() formerly took the event object, and since various code references
+ // evt.target (after connecting to _openMyself()), using an Object for parameters
+ // (so that old code still works).
+
+ var target = args.target,
+ iframe = args.iframe,
+ coords = args.coords;
+
+ // Get coordinates to open menu, either at specified (mouse) position or (if triggered via keyboard)
+ // then near the node the menu is assigned to.
+ if(coords){
+ if(iframe){
+ // Specified coordinates are on <body> node of an <iframe>, convert to match main document
+ var od = target.ownerDocument,
+ ifc = dojo.position(iframe, true),
+ win = this._iframeContentWindow(iframe),
+ scroll = dojo.withGlobal(win, "_docScroll", dojo);
+
+ var cs = dojo.getComputedStyle(iframe),
+ tp = dojo._toPixelValue,
+ left = (dojo.isIE && dojo.isQuirks ? 0 : tp(iframe, cs.paddingLeft)) + (dojo.isIE && dojo.isQuirks ? tp(iframe, cs.borderLeftWidth) : 0),
+ top = (dojo.isIE && dojo.isQuirks ? 0 : tp(iframe, cs.paddingTop)) + (dojo.isIE && dojo.isQuirks ? tp(iframe, cs.borderTopWidth) : 0);
+
+ coords.x += ifc.x + left - scroll.x;
+ coords.y += ifc.y + top - scroll.y;
+ }
+ }else{
+ coords = dojo.position(target, true);
+ coords.x += 10;
+ coords.y += 10;
+ }
+
+ var self=this;
+ var savedFocus = dijit.getFocus(this);
+ function closeAndRestoreFocus(){
+ // user has clicked on a menu or popup
+ if(self.refocus){
+ dijit.focus(savedFocus);
+ }
+ dijit.popup.close(self);
+ }
+ dijit.popup.open({
+ popup: this,
+ x: coords.x,
+ y: coords.y,
+ onExecute: closeAndRestoreFocus,
+ onCancel: closeAndRestoreFocus,
+ orient: this.isLeftToRight() ? 'L' : 'R'
+ });
+ this.focus();
+
+ this._onBlur = function(){
+ this.inherited('_onBlur', arguments);
+ // Usually the parent closes the child widget but if this is a context
+ // menu then there is no parent
+ dijit.popup.close(this);
+ // don't try to restore focus; user has clicked another part of the screen
+ // and set focus there
+ };
+ },
+
+ uninitialize: function(){
+ dojo.forEach(this._bindings, function(b){ if(b){ this.unBindDomNode(b.node); } }, this);
+ this.inherited(arguments);
+ }
+}
+);
+
+}
+
+if(!dojo._hasResource["dojox.html.metrics"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.html.metrics"] = true;
+dojo.provide("dojox.html.metrics");
+
+(function(){
+ var dhm = dojox.html.metrics;
+
+ // derived from Morris John's emResized measurer
+ dhm.getFontMeasurements = function(){
+ // summary
+ // Returns an object that has pixel equivilents of standard font size values.
+ var heights = {
+ '1em':0, '1ex':0, '100%':0, '12pt':0, '16px':0, 'xx-small':0, 'x-small':0,
+ 'small':0, 'medium':0, 'large':0, 'x-large':0, 'xx-large':0
+ };
+
+ if(dojo.isIE){
+ // we do a font-size fix if and only if one isn't applied already.
+ // NOTE: If someone set the fontSize on the HTML Element, this will kill it.
+ dojo.doc.documentElement.style.fontSize="100%";
+ }
+
+ // set up the measuring node.
+ var div=dojo.doc.createElement("div");
+ var ds = div.style;
+ ds.position="absolute";
+ ds.left="-100px";
+ ds.top="0";
+ ds.width="30px";
+ ds.height="1000em";
+ ds.borderWidth="0";
+ ds.margin="0";
+ ds.padding="0";
+ ds.outline="0";
+ ds.lineHeight="1";
+ ds.overflow="hidden";
+ dojo.body().appendChild(div);
+
+ // do the measurements.
+ for(var p in heights){
+ ds.fontSize = p;
+ heights[p] = Math.round(div.offsetHeight * 12/16) * 16/12 / 1000;
+ }
+
+ dojo.body().removeChild(div);
+ div = null;
+ return heights; // object
+ };
+
+ var fontMeasurements = null;
+
+ dhm.getCachedFontMeasurements = function(recalculate){
+ if(recalculate || !fontMeasurements){
+ fontMeasurements = dhm.getFontMeasurements();
+ }
+ return fontMeasurements;
+ };
+
+ var measuringNode = null, empty = {};
+ dhm.getTextBox = function(/* String */ text, /* Object */ style, /* String? */ className){
+ var m, s;
+ if(!measuringNode){
+ m = measuringNode = dojo.doc.createElement("div");
+ // Container that we can set contraints on so that it doesn't
+ // trigger a scrollbar.
+ var c = dojo.doc.createElement("div");
+ c.appendChild(m);
+ s = c.style;
+ s.overflow='scroll';
+ s.position = "absolute";
+ s.left = "0px";
+ s.top = "-10000px";
+ s.width = "1px";
+ s.height = "1px";
+ s.visibility = "hidden";
+ s.borderWidth = "0";
+ s.margin = "0";
+ s.padding = "0";
+ s.outline = "0";
+ dojo.body().appendChild(c);
+ }else{
+ m = measuringNode;
+ }
+ // reset styles
+ m.className = "";
+ s = m.style;
+ s.borderWidth = "0";
+ s.margin = "0";
+ s.padding = "0";
+ s.outline = "0";
+ // set new style
+ if(arguments.length > 1 && style){
+ for(var i in style){
+ if(i in empty){ continue; }
+ s[i] = style[i];
+ }
+ }
+ // set classes
+ if(arguments.length > 2 && className){
+ m.className = className;
+ }
+ // take a measure
+ m.innerHTML = text;
+ var box = dojo.position(m);
+ // position doesn't report right (reports 1, since parent is 1)
+ // So we have to look at the scrollWidth to get the real width
+ // Height is right.
+ box.w = m.parentNode.scrollWidth;
+ return box;
+ };
+
+ // determine the scrollbar sizes on load.
+ var scroll={ w:16, h:16 };
+ dhm.getScrollbar=function(){ return { w:scroll.w, h:scroll.h }; };
+
+ dhm._fontResizeNode = null;
+
+ dhm.initOnFontResize = function(interval){
+ var f = dhm._fontResizeNode = dojo.doc.createElement("iframe");
+ var fs = f.style;
+ fs.position = "absolute";
+ fs.width = "5em";
+ fs.height = "10em";
+ fs.top = "-10000px";
+ if(dojo.isIE){
+ f.onreadystatechange = function(){
+ if(f.contentWindow.document.readyState == "complete"){
+ f.onresize = f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize;
+ }
+ };
+ }else{
+ f.onload = function(){
+ f.contentWindow.onresize = f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize;
+ };
+ }
+ //The script tag is to work around a known firebug race condition. See comments in bug #9046
+ f.setAttribute("src", "javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'");
+ dojo.body().appendChild(f);
+ dhm.initOnFontResize = function(){};
+ };
+
+ dhm.onFontResize = function(){};
+ dhm._fontresize = function(){
+ dhm.onFontResize();
+ }
+
+ dojo.addOnUnload(function(){
+ // destroy our font resize iframe if we have one
+ var f = dhm._fontResizeNode;
+ if(f){
+ if(dojo.isIE && f.onresize){
+ f.onresize = null;
+ }else if(f.contentWindow && f.contentWindow.onresize){
+ f.contentWindow.onresize = null;
+ }
+ dhm._fontResizeNode = null;
+ }
+ });
+
+ dojo.addOnLoad(function(){
+ // getScrollbar metrics node
+ try{
+ var n=dojo.doc.createElement("div");
+ n.style.cssText = "top:0;left:0;width:100px;height:100px;overflow:scroll;position:absolute;visibility:hidden;";
+ dojo.body().appendChild(n);
+ scroll.w = n.offsetWidth - n.clientWidth;
+ scroll.h = n.offsetHeight - n.clientHeight;
+ dojo.body().removeChild(n);
+ //console.log("Scroll bar dimensions: ", scroll);
+ delete n;
+ }catch(e){}
+
+ // text size poll setup
+ if("fontSizeWatch" in dojo.config && !!dojo.config.fontSizeWatch){
+ dhm.initOnFontResize();
+ }
+ });
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid.util"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.util"] = true;
+dojo.provide("dojox.grid.util");
+
+// summary: grid utility library
+(function(){
+ var dgu = dojox.grid.util;
+
+ dgu.na = '...';
+ dgu.rowIndexTag = "gridRowIndex";
+ dgu.gridViewTag = "gridView";
+
+
+ dgu.fire = function(ob, ev, args){
+ var fn = ob && ev && ob[ev];
+ return fn && (args ? fn.apply(ob, args) : ob[ev]());
+ };
+
+ dgu.setStyleHeightPx = function(inElement, inHeight){
+ if(inHeight >= 0){
+ var s = inElement.style;
+ var v = inHeight + 'px';
+ if(inElement && s['height'] != v){
+ s['height'] = v;
+ }
+ }
+ };
+
+ dgu.mouseEvents = [ 'mouseover', 'mouseout', /*'mousemove',*/ 'mousedown', 'mouseup', 'click', 'dblclick', 'contextmenu' ];
+
+ dgu.keyEvents = [ 'keyup', 'keydown', 'keypress' ];
+
+ dgu.funnelEvents = function(inNode, inObject, inMethod, inEvents){
+ var evts = (inEvents ? inEvents : dgu.mouseEvents.concat(dgu.keyEvents));
+ for (var i=0, l=evts.length; i<l; i++){
+ inObject.connect(inNode, 'on' + evts[i], inMethod);
+ }
+ };
+
+ dgu.removeNode = function(inNode){
+ inNode = dojo.byId(inNode);
+ inNode && inNode.parentNode && inNode.parentNode.removeChild(inNode);
+ return inNode;
+ };
+
+ dgu.arrayCompare = function(inA, inB){
+ for(var i=0,l=inA.length; i<l; i++){
+ if(inA[i] != inB[i]){return false;}
+ }
+ return (inA.length == inB.length);
+ };
+
+ dgu.arrayInsert = function(inArray, inIndex, inValue){
+ if(inArray.length <= inIndex){
+ inArray[inIndex] = inValue;
+ }else{
+ inArray.splice(inIndex, 0, inValue);
+ }
+ };
+
+ dgu.arrayRemove = function(inArray, inIndex){
+ inArray.splice(inIndex, 1);
+ };
+
+ dgu.arraySwap = function(inArray, inI, inJ){
+ var cache = inArray[inI];
+ inArray[inI] = inArray[inJ];
+ inArray[inJ] = cache;
+ };
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid._Scroller"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Scroller"] = true;
+dojo.provide("dojox.grid._Scroller");
+
+(function(){
+ var indexInParent = function(inNode){
+ var i=0, n, p=inNode.parentNode;
+ while((n = p.childNodes[i++])){
+ if(n == inNode){
+ return i - 1;
+ }
+ }
+ return -1;
+ };
+
+ var cleanNode = function(inNode){
+ if(!inNode){
+ return;
+ }
+ var filter = function(inW){
+ return inW.domNode && dojo.isDescendant(inW.domNode, inNode, true);
+ };
+ var ws = dijit.registry.filter(filter);
+ for(var i=0, w; (w=ws[i]); i++){
+ w.destroy();
+ }
+ delete ws;
+ };
+
+ var getTagName = function(inNodeOrId){
+ var node = dojo.byId(inNodeOrId);
+ return (node && node.tagName ? node.tagName.toLowerCase() : '');
+ };
+
+ var nodeKids = function(inNode, inTag){
+ var result = [];
+ var i=0, n;
+ while((n = inNode.childNodes[i])){
+ i++;
+ if(getTagName(n) == inTag){
+ result.push(n);
+ }
+ }
+ return result;
+ };
+
+ var divkids = function(inNode){
+ return nodeKids(inNode, 'div');
+ };
+
+ dojo.declare("dojox.grid._Scroller", null, {
+ constructor: function(inContentNodes){
+ this.setContentNodes(inContentNodes);
+ this.pageHeights = [];
+ this.pageNodes = [];
+ this.stack = [];
+ },
+ // specified
+ rowCount: 0, // total number of rows to manage
+ defaultRowHeight: 32, // default height of a row
+ keepRows: 100, // maximum number of rows that should exist at one time
+ contentNode: null, // node to contain pages
+ scrollboxNode: null, // node that controls scrolling
+ // calculated
+ defaultPageHeight: 0, // default height of a page
+ keepPages: 10, // maximum number of pages that should exists at one time
+ pageCount: 0,
+ windowHeight: 0,
+ firstVisibleRow: 0,
+ lastVisibleRow: 0,
+ averageRowHeight: 0, // the average height of a row
+ // private
+ page: 0,
+ pageTop: 0,
+ // init
+ init: function(inRowCount, inKeepRows, inRowsPerPage){
+ switch(arguments.length){
+ case 3: this.rowsPerPage = inRowsPerPage;
+ case 2: this.keepRows = inKeepRows;
+ case 1: this.rowCount = inRowCount;
+ default: break;
+ }
+ this.defaultPageHeight = this.defaultRowHeight * this.rowsPerPage;
+ this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage);
+ this.setKeepInfo(this.keepRows);
+ this.invalidate();
+ if(this.scrollboxNode){
+ this.scrollboxNode.scrollTop = 0;
+ this.scroll(0);
+ this.scrollboxNode.onscroll = dojo.hitch(this, 'onscroll');
+ }
+ },
+ _getPageCount: function(rowCount, rowsPerPage){
+ return rowCount ? (Math.ceil(rowCount / rowsPerPage) || 1) : 0;
+ },
+ destroy: function(){
+ this.invalidateNodes();
+ delete this.contentNodes;
+ delete this.contentNode;
+ delete this.scrollboxNode;
+ },
+ setKeepInfo: function(inKeepRows){
+ this.keepRows = inKeepRows;
+ this.keepPages = !this.keepRows ? this.keepPages : Math.max(Math.ceil(this.keepRows / this.rowsPerPage), 2);
+ },
+ // nodes
+ setContentNodes: function(inNodes){
+ this.contentNodes = inNodes;
+ this.colCount = (this.contentNodes ? this.contentNodes.length : 0);
+ this.pageNodes = [];
+ for(var i=0; i<this.colCount; i++){
+ this.pageNodes[i] = [];
+ }
+ },
+ getDefaultNodes: function(){
+ return this.pageNodes[0] || [];
+ },
+ // updating
+ invalidate: function(){
+ this._invalidating = true;
+ this.invalidateNodes();
+ this.pageHeights = [];
+ this.height = (this.pageCount ? (this.pageCount - 1)* this.defaultPageHeight + this.calcLastPageHeight() : 0);
+ this.resize();
+ this._invalidating = false;
+ },
+ updateRowCount: function(inRowCount){
+ this.invalidateNodes();
+ this.rowCount = inRowCount;
+ // update page count, adjust document height
+ var oldPageCount = this.pageCount;
+ if(oldPageCount === 0){
+ //We want to have at least 1px in height to keep scroller. Otherwise with an
+ //empty grid you can't scroll to see the header.
+ this.height = 1;
+ }
+ this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage);
+ if(this.pageCount < oldPageCount){
+ for(var i=oldPageCount-1; i>=this.pageCount; i--){
+ this.height -= this.getPageHeight(i);
+ delete this.pageHeights[i];
+ }
+ }else if(this.pageCount > oldPageCount){
+ this.height += this.defaultPageHeight * (this.pageCount - oldPageCount - 1) + this.calcLastPageHeight();
+ }
+ this.resize();
+ },
+ // implementation for page manager
+ pageExists: function(inPageIndex){
+ return Boolean(this.getDefaultPageNode(inPageIndex));
+ },
+ measurePage: function(inPageIndex){
+ if(this.grid.rowHeight){
+ var height = this.grid.rowHeight + 1;
+ return ((inPageIndex + 1) * this.rowsPerPage > this.rowCount ?
+ this.rowCount - inPageIndex * this.rowsPerPage :
+ this.rowsPerPage) * height;
+
+ }
+ var n = this.getDefaultPageNode(inPageIndex);
+ return (n && n.innerHTML) ? n.offsetHeight : undefined;
+ },
+ positionPage: function(inPageIndex, inPos){
+ for(var i=0; i<this.colCount; i++){
+ this.pageNodes[i][inPageIndex].style.top = inPos + 'px';
+ }
+ },
+ repositionPages: function(inPageIndex){
+ var nodes = this.getDefaultNodes();
+ var last = 0;
+
+ for(var i=0; i<this.stack.length; i++){
+ last = Math.max(this.stack[i], last);
+ }
+ //
+ var n = nodes[inPageIndex];
+ var y = (n ? this.getPageNodePosition(n) + this.getPageHeight(inPageIndex) : 0);
+ for(var p=inPageIndex+1; p<=last; p++){
+ n = nodes[p];
+ if(n){
+ if(this.getPageNodePosition(n) == y){
+ return;
+ }
+ this.positionPage(p, y);
+ }
+ y += this.getPageHeight(p);
+ }
+ },
+ installPage: function(inPageIndex){
+ for(var i=0; i<this.colCount; i++){
+ this.contentNodes[i].appendChild(this.pageNodes[i][inPageIndex]);
+ }
+ },
+ preparePage: function(inPageIndex, inReuseNode){
+ var p = (inReuseNode ? this.popPage() : null);
+ for(var i=0; i<this.colCount; i++){
+ var nodes = this.pageNodes[i];
+ var new_p = (p === null ? this.createPageNode() : this.invalidatePageNode(p, nodes));
+ new_p.pageIndex = inPageIndex;
+ nodes[inPageIndex] = new_p;
+ }
+ },
+ // rendering implementation
+ renderPage: function(inPageIndex){
+ var nodes = [];
+ var i, j;
+ for(i=0; i<this.colCount; i++){
+ nodes[i] = this.pageNodes[i][inPageIndex];
+ }
+ for(i=0, j=inPageIndex*this.rowsPerPage; (i<this.rowsPerPage)&&(j<this.rowCount); i++, j++){
+ this.renderRow(j, nodes);
+ }
+ },
+ removePage: function(inPageIndex){
+ for(var i=0, j=inPageIndex*this.rowsPerPage; i<this.rowsPerPage; i++, j++){
+ this.removeRow(j);
+ }
+ },
+ destroyPage: function(inPageIndex){
+ for(var i=0; i<this.colCount; i++){
+ var n = this.invalidatePageNode(inPageIndex, this.pageNodes[i]);
+ if(n){
+ dojo.destroy(n);
+ }
+ }
+ },
+ pacify: function(inShouldPacify){
+ },
+ // pacification
+ pacifying: false,
+ pacifyTicks: 200,
+ setPacifying: function(inPacifying){
+ if(this.pacifying != inPacifying){
+ this.pacifying = inPacifying;
+ this.pacify(this.pacifying);
+ }
+ },
+ startPacify: function(){
+ this.startPacifyTicks = new Date().getTime();
+ },
+ doPacify: function(){
+ var result = (new Date().getTime() - this.startPacifyTicks) > this.pacifyTicks;
+ this.setPacifying(true);
+ this.startPacify();
+ return result;
+ },
+ endPacify: function(){
+ this.setPacifying(false);
+ },
+ // default sizing implementation
+ resize: function(){
+ if(this.scrollboxNode){
+ this.windowHeight = this.scrollboxNode.clientHeight;
+ }
+ for(var i=0; i<this.colCount; i++){
+ //We want to have 1px in height min to keep scroller. Otherwise can't scroll
+ //and see header in empty grid.
+ dojox.grid.util.setStyleHeightPx(this.contentNodes[i], Math.max(1,this.height));
+ }
+
+ // Calculate the average row height and update the defaults (row and page).
+ var needPage = (!this._invalidating);
+ if(!needPage){
+ var ah = this.grid.get("autoHeight");
+ if(typeof ah == "number" && ah <= Math.min(this.rowsPerPage, this.rowCount)){
+ needPage = true;
+ }
+ }
+ if(needPage){
+ this.needPage(this.page, this.pageTop);
+ }
+ var rowsOnPage = (this.page < this.pageCount - 1) ? this.rowsPerPage : ((this.rowCount % this.rowsPerPage) || this.rowsPerPage);
+ var pageHeight = this.getPageHeight(this.page);
+ this.averageRowHeight = (pageHeight > 0 && rowsOnPage > 0) ? (pageHeight / rowsOnPage) : 0;
+ },
+ calcLastPageHeight: function(){
+ if(!this.pageCount){
+ return 0;
+ }
+ var lastPage = this.pageCount - 1;
+ var lastPageHeight = ((this.rowCount % this.rowsPerPage)||(this.rowsPerPage)) * this.defaultRowHeight;
+ this.pageHeights[lastPage] = lastPageHeight;
+ return lastPageHeight;
+ },
+ updateContentHeight: function(inDh){
+ this.height += inDh;
+ this.resize();
+ },
+ updatePageHeight: function(inPageIndex, fromBuild, fromAsynRendering){
+ if(this.pageExists(inPageIndex)){
+ var oh = this.getPageHeight(inPageIndex);
+ var h = (this.measurePage(inPageIndex));
+ if(h === undefined){
+ h = oh;
+ }
+ this.pageHeights[inPageIndex] = h;
+ if(oh != h){
+ this.updateContentHeight(h - oh);
+ var ah = this.grid.get("autoHeight");
+ if((typeof ah == "number" && ah > this.rowCount)||(ah === true && !fromBuild)){
+ if(!fromAsynRendering){
+ this.grid.sizeChange();
+ }else{//fix #11101 by using fromAsynRendering to avoid deadlock
+ var ns = this.grid.viewsNode.style;
+ ns.height = parseInt(ns.height) + h - oh + 'px';
+ this.repositionPages(inPageIndex);
+ }
+ }else{
+ this.repositionPages(inPageIndex);
+ }
+ }
+ return h;
+ }
+ return 0;
+ },
+ rowHeightChanged: function(inRowIndex, fromAsynRendering){
+ this.updatePageHeight(Math.floor(inRowIndex / this.rowsPerPage), false, fromAsynRendering);
+ },
+ // scroller core
+ invalidateNodes: function(){
+ while(this.stack.length){
+ this.destroyPage(this.popPage());
+ }
+ },
+ createPageNode: function(){
+ var p = document.createElement('div');
+ dojo.attr(p,"role","presentation");
+ p.style.position = 'absolute';
+ //p.style.width = '100%';
+ p.style[dojo._isBodyLtr() ? "left" : "right"] = '0';
+ return p;
+ },
+ getPageHeight: function(inPageIndex){
+ var ph = this.pageHeights[inPageIndex];
+ return (ph !== undefined ? ph : this.defaultPageHeight);
+ },
+ // FIXME: this is not a stack, it's a FIFO list
+ pushPage: function(inPageIndex){
+ return this.stack.push(inPageIndex);
+ },
+ popPage: function(){
+ return this.stack.shift();
+ },
+ findPage: function(inTop){
+ var i = 0, h = 0;
+ for(var ph = 0; i<this.pageCount; i++, h += ph){
+ ph = this.getPageHeight(i);
+ if(h + ph >= inTop){
+ break;
+ }
+ }
+ this.page = i;
+ this.pageTop = h;
+ },
+ buildPage: function(inPageIndex, inReuseNode, inPos){
+ this.preparePage(inPageIndex, inReuseNode);
+ this.positionPage(inPageIndex, inPos);
+ // order of operations is key below
+ this.installPage(inPageIndex);
+ this.renderPage(inPageIndex);
+ // order of operations is key above
+ this.pushPage(inPageIndex);
+ },
+ needPage: function(inPageIndex, inPos){
+ var h = this.getPageHeight(inPageIndex), oh = h;
+ if(!this.pageExists(inPageIndex)){
+ this.buildPage(inPageIndex, (!this.grid._autoHeight/*fix #10543*/ && this.keepPages&&(this.stack.length >= this.keepPages)), inPos);
+ h = this.updatePageHeight(inPageIndex, true);
+ }else{
+ this.positionPage(inPageIndex, inPos);
+ }
+ return h;
+ },
+ onscroll: function(){
+ this.scroll(this.scrollboxNode.scrollTop);
+ },
+ scroll: function(inTop){
+ this.grid.scrollTop = inTop;
+ if(this.colCount){
+ this.startPacify();
+ this.findPage(inTop);
+ var h = this.height;
+ var b = this.getScrollBottom(inTop);
+ for(var p=this.page, y=this.pageTop; (p<this.pageCount)&&((b<0)||(y<b)); p++){
+ y += this.needPage(p, y);
+ }
+ this.firstVisibleRow = this.getFirstVisibleRow(this.page, this.pageTop, inTop);
+ this.lastVisibleRow = this.getLastVisibleRow(p - 1, y, b);
+ // indicates some page size has been updated
+ if(h != this.height){
+ this.repositionPages(p-1);
+ }
+ this.endPacify();
+ }
+ },
+ getScrollBottom: function(inTop){
+ return (this.windowHeight >= 0 ? inTop + this.windowHeight : -1);
+ },
+ // events
+ processNodeEvent: function(e, inNode){
+ var t = e.target;
+ while(t && (t != inNode) && t.parentNode && (t.parentNode.parentNode != inNode)){
+ t = t.parentNode;
+ }
+ if(!t || !t.parentNode || (t.parentNode.parentNode != inNode)){
+ return false;
+ }
+ var page = t.parentNode;
+ e.topRowIndex = page.pageIndex * this.rowsPerPage;
+ e.rowIndex = e.topRowIndex + indexInParent(t);
+ e.rowTarget = t;
+ return true;
+ },
+ processEvent: function(e){
+ return this.processNodeEvent(e, this.contentNode);
+ },
+ // virtual rendering interface
+ renderRow: function(inRowIndex, inPageNode){
+ },
+ removeRow: function(inRowIndex){
+ },
+ // page node operations
+ getDefaultPageNode: function(inPageIndex){
+ return this.getDefaultNodes()[inPageIndex];
+ },
+ positionPageNode: function(inNode, inPos){
+ },
+ getPageNodePosition: function(inNode){
+ return inNode.offsetTop;
+ },
+ invalidatePageNode: function(inPageIndex, inNodes){
+ var p = inNodes[inPageIndex];
+ if(p){
+ delete inNodes[inPageIndex];
+ this.removePage(inPageIndex, p);
+ cleanNode(p);
+ p.innerHTML = '';
+ }
+ return p;
+ },
+ // scroll control
+ getPageRow: function(inPage){
+ return inPage * this.rowsPerPage;
+ },
+ getLastPageRow: function(inPage){
+ return Math.min(this.rowCount, this.getPageRow(inPage + 1)) - 1;
+ },
+ getFirstVisibleRow: function(inPage, inPageTop, inScrollTop){
+ if(!this.pageExists(inPage)){
+ return 0;
+ }
+ var row = this.getPageRow(inPage);
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[inPage]);
+ for(var i=0,l=rows.length; i<l && inPageTop<inScrollTop; i++, row++){
+ inPageTop += rows[i].offsetHeight;
+ }
+ return (row ? row - 1 : row);
+ },
+ getLastVisibleRow: function(inPage, inBottom, inScrollBottom){
+ if(!this.pageExists(inPage)){
+ return 0;
+ }
+ var nodes = this.getDefaultNodes();
+ var row = this.getLastPageRow(inPage);
+ var rows = divkids(nodes[inPage]);
+ for(var i=rows.length-1; i>=0 && inBottom>inScrollBottom; i--, row--){
+ inBottom -= rows[i].offsetHeight;
+ }
+ return row + 1;
+ },
+ findTopRow: function(inScrollTop){
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[this.page]);
+ for(var i=0,l=rows.length,t=this.pageTop,h; i<l; i++){
+ h = rows[i].offsetHeight;
+ t += h;
+ if(t >= inScrollTop){
+ this.offset = h - (t - inScrollTop);
+ return i + this.page * this.rowsPerPage;
+ }
+ }
+ return -1;
+ },
+ findScrollTop: function(inRow){
+ var rowPage = Math.floor(inRow / this.rowsPerPage);
+ var t = 0;
+ var i, l;
+ for(i=0; i<rowPage; i++){
+ t += this.getPageHeight(i);
+ }
+ this.pageTop = t;
+ this.page = rowPage;//fix #10543
+ this.needPage(rowPage, this.pageTop);
+
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[rowPage]);
+ var r = inRow - this.rowsPerPage * rowPage;
+ for(i=0,l=rows.length; i<l && i<r; i++){
+ t += rows[i].offsetHeight;
+ }
+ return t;
+ },
+ dummy: 0
+ });
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid.cells._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.cells._base"] = true;
+dojo.provide("dojox.grid.cells._base");
+
+
+
+
+dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
+ deferred: null,
+ _destroyOnRemove: true,
+ postCreate: function(){
+ if(this.deferred){
+ this.deferred.addBoth(dojo.hitch(this, function(text){
+ if(this.domNode){
+ this.domNode.innerHTML = text;
+ }
+ }));
+ }
+ }
+});
+
+(function(){
+ var focusSelectNode = function(inNode){
+ try{
+ dojox.grid.util.fire(inNode, "focus");
+ dojox.grid.util.fire(inNode, "select");
+ }catch(e){// IE sux bad
+ }
+ };
+
+ var whenIdle = function(/*inContext, inMethod, args ...*/){
+ setTimeout(dojo.hitch.apply(dojo, arguments), 0);
+ };
+
+ var dgc = dojox.grid.cells;
+
+ dojo.declare("dojox.grid.cells._Base", null, {
+ // summary:
+ // Respresents a grid cell and contains information about column options and methods
+ // for retrieving cell related information.
+ // Each column in a grid layout has a cell object and most events and many methods
+ // provide access to these objects.
+ styles: '',
+ classes: '',
+ editable: false,
+ alwaysEditing: false,
+ formatter: null,
+ defaultValue: '...',
+ value: null,
+ hidden: false,
+ noresize: false,
+ draggable: true,
+ //private
+ _valueProp: "value",
+ _formatPending: false,
+
+ constructor: function(inProps){
+ this._props = inProps || {};
+ dojo.mixin(this, inProps);
+ if(this.draggable === undefined){
+ this.draggable = true;
+ }
+ },
+
+ _defaultFormat: function(inValue, callArgs){
+ var s = this.grid.formatterScope || this;
+ var f = this.formatter;
+ if(f && s && typeof f == "string"){
+ f = this.formatter = s[f];
+ }
+ var v = (inValue != this.defaultValue && f) ? f.apply(s, callArgs) : inValue;
+ if(typeof v == "undefined"){
+ return this.defaultValue;
+ }
+ if(v && v.addBoth){
+ // Check if it's a deferred
+ v = new dojox.grid._DeferredTextWidget({deferred: v},
+ dojo.create("span", {innerHTML: this.defaultValue}));
+ }
+ if(v && v.declaredClass && v.startup){
+ return "<div class='dojoxGridStubNode' linkWidget='" +
+ v.id +
+ "' cellIdx='" +
+ this.index +
+ "'>" +
+ this.defaultValue +
+ "</div>";
+ }
+ return v;
+ },
+
+ // data source
+ format: function(inRowIndex, inItem){
+ // summary:
+ // provides the html for a given grid cell.
+ // inRowIndex: int
+ // grid row index
+ // returns: html for a given grid cell
+ var f, i=this.grid.edit.info, d=this.get ? this.get(inRowIndex, inItem) : (this.value || this.defaultValue);
+ d = (d && d.replace && this.grid.escapeHTMLInData) ? d.replace(/&/g, '&amp;').replace(/</g, '&lt;') : d;
+ if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndex && i.cell==this))){
+ return this.formatEditing(d, inRowIndex);
+ }else{
+ return this._defaultFormat(d, [d, inRowIndex, this]);
+ }
+ },
+ formatEditing: function(inDatum, inRowIndex){
+ // summary:
+ // formats the cell for editing
+ // inDatum: anything
+ // cell data to edit
+ // inRowIndex: int
+ // grid row index
+ // returns: string of html to place in grid cell
+ },
+ // utility
+ getNode: function(inRowIndex){
+ // summary:
+ // gets the dom node for a given grid cell.
+ // inRowIndex: int
+ // grid row index
+ // returns: dom node for a given grid cell
+ return this.view.getCellNode(inRowIndex, this.index);
+ },
+ getHeaderNode: function(){
+ return this.view.getHeaderCellNode(this.index);
+ },
+ getEditNode: function(inRowIndex){
+ return (this.getNode(inRowIndex) || 0).firstChild || 0;
+ },
+ canResize: function(){
+ var uw = this.unitWidth;
+ return uw && (uw!=='auto');
+ },
+ isFlex: function(){
+ var uw = this.unitWidth;
+ return uw && dojo.isString(uw) && (uw=='auto' || uw.slice(-1)=='%');
+ },
+ // edit support
+ applyEdit: function(inValue, inRowIndex){
+ this.grid.edit.applyCellEdit(inValue, this, inRowIndex);
+ },
+ cancelEdit: function(inRowIndex){
+ this.grid.doCancelEdit(inRowIndex);
+ },
+ _onEditBlur: function(inRowIndex){
+ if(this.grid.edit.isEditCell(inRowIndex, this.index)){
+ //console.log('editor onblur', e);
+ this.grid.edit.apply();
+ }
+ },
+ registerOnBlur: function(inNode, inRowIndex){
+ if(this.commitOnBlur){
+ dojo.connect(inNode, "onblur", function(e){
+ // hack: if editor still thinks this editor is current some ms after it blurs, assume we've focused away from grid
+ setTimeout(dojo.hitch(this, "_onEditBlur", inRowIndex), 250);
+ });
+ }
+ },
+ //protected
+ needFormatNode: function(inDatum, inRowIndex){
+ this._formatPending = true;
+ whenIdle(this, "_formatNode", inDatum, inRowIndex);
+ },
+ cancelFormatNode: function(){
+ this._formatPending = false;
+ },
+ //private
+ _formatNode: function(inDatum, inRowIndex){
+ if(this._formatPending){
+ this._formatPending = false;
+ // make cell selectable
+ dojo.setSelectable(this.grid.domNode, true);
+ this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex);
+ }
+ },
+ //protected
+ formatNode: function(inNode, inDatum, inRowIndex){
+ // summary:
+ // format the editing dom node. Use when editor is a widget.
+ // inNode: dom node
+ // dom node for the editor
+ // inDatum: anything
+ // cell data to edit
+ // inRowIndex: int
+ // grid row index
+ if(dojo.isIE){
+ // IE sux bad
+ whenIdle(this, "focus", inRowIndex, inNode);
+ }else{
+ this.focus(inRowIndex, inNode);
+ }
+ },
+ dispatchEvent: function(m, e){
+ if(m in this){
+ return this[m](e);
+ }
+ },
+ //public
+ getValue: function(inRowIndex){
+ // summary:
+ // returns value entered into editor
+ // inRowIndex: int
+ // grid row index
+ // returns:
+ // value of editor
+ return this.getEditNode(inRowIndex)[this._valueProp];
+ },
+ setValue: function(inRowIndex, inValue){
+ // summary:
+ // set the value of the grid editor
+ // inRowIndex: int
+ // grid row index
+ // inValue: anything
+ // value of editor
+ var n = this.getEditNode(inRowIndex);
+ if(n){
+ n[this._valueProp] = inValue;
+ }
+ },
+ focus: function(inRowIndex, inNode){
+ // summary:
+ // focus the grid editor
+ // inRowIndex: int
+ // grid row index
+ // inNode: dom node
+ // editor node
+ focusSelectNode(inNode || this.getEditNode(inRowIndex));
+ },
+ save: function(inRowIndex){
+ // summary:
+ // save editor state
+ // inRowIndex: int
+ // grid row index
+ this.value = this.value || this.getValue(inRowIndex);
+ //console.log("save", this.value, inCell.index, inRowIndex);
+ },
+ restore: function(inRowIndex){
+ // summary:
+ // restore editor state
+ // inRowIndex: int
+ // grid row index
+ this.setValue(inRowIndex, this.value);
+ //console.log("restore", this.value, inCell.index, inRowIndex);
+ },
+ //protected
+ _finish: function(inRowIndex){
+ // summary:
+ // called when editing is completed to clean up editor
+ // inRowIndex: int
+ // grid row index
+ dojo.setSelectable(this.grid.domNode, false);
+ this.cancelFormatNode();
+ },
+ //public
+ apply: function(inRowIndex){
+ // summary:
+ // apply edit from cell editor
+ // inRowIndex: int
+ // grid row index
+ this.applyEdit(this.getValue(inRowIndex), inRowIndex);
+ this._finish(inRowIndex);
+ },
+ cancel: function(inRowIndex){
+ // summary:
+ // cancel cell edit
+ // inRowIndex: int
+ // grid row index
+ this.cancelEdit(inRowIndex);
+ this._finish(inRowIndex);
+ }
+ });
+ dgc._Base.markupFactory = function(node, cellDef){
+ var d = dojo;
+ var formatter = d.trim(d.attr(node, "formatter")||"");
+ if(formatter){
+ cellDef.formatter = dojo.getObject(formatter)||formatter;
+ }
+ var get = d.trim(d.attr(node, "get")||"");
+ if(get){
+ cellDef.get = dojo.getObject(get);
+ }
+ var getBoolAttr = function(attr, cell, cellAttr){
+ var value = d.trim(d.attr(node, attr)||"");
+ if(value){ cell[cellAttr||attr] = !(value.toLowerCase()=="false"); }
+ };
+ getBoolAttr("sortDesc", cellDef);
+ getBoolAttr("editable", cellDef);
+ getBoolAttr("alwaysEditing", cellDef);
+ getBoolAttr("noresize", cellDef);
+ getBoolAttr("draggable", cellDef);
+
+ var value = d.trim(d.attr(node, "loadingText")||d.attr(node, "defaultValue")||"");
+ if(value){
+ cellDef.defaultValue = value;
+ }
+
+ var getStrAttr = function(attr, cell, cellAttr){
+ var value = d.trim(d.attr(node, attr)||"")||undefined;
+ if(value){ cell[cellAttr||attr] = value; }
+ };
+ getStrAttr("styles", cellDef);
+ getStrAttr("headerStyles", cellDef);
+ getStrAttr("cellStyles", cellDef);
+ getStrAttr("classes", cellDef);
+ getStrAttr("headerClasses", cellDef);
+ getStrAttr("cellClasses", cellDef);
+ };
+
+ dojo.declare("dojox.grid.cells.Cell", dgc._Base, {
+ // summary
+ // grid cell that provides a standard text input box upon editing
+ constructor: function(){
+ this.keyFilter = this.keyFilter;
+ },
+ // keyFilter: RegExp
+ // optional regex for disallowing keypresses
+ keyFilter: null,
+ formatEditing: function(inDatum, inRowIndex){
+ this.needFormatNode(inDatum, inRowIndex);
+ return '<input class="dojoxGridInput" type="text" value="' + inDatum + '">';
+ },
+ formatNode: function(inNode, inDatum, inRowIndex){
+ this.inherited(arguments);
+ // FIXME: feels too specific for this interface
+ this.registerOnBlur(inNode, inRowIndex);
+ },
+ doKey: function(e){
+ if(this.keyFilter){
+ var key = String.fromCharCode(e.charCode);
+ if(key.search(this.keyFilter) == -1){
+ dojo.stopEvent(e);
+ }
+ }
+ },
+ _finish: function(inRowIndex){
+ this.inherited(arguments);
+ var n = this.getEditNode(inRowIndex);
+ try{
+ dojox.grid.util.fire(n, "blur");
+ }catch(e){}
+ }
+ });
+ dgc.Cell.markupFactory = function(node, cellDef){
+ dgc._Base.markupFactory(node, cellDef);
+ var d = dojo;
+ var keyFilter = d.trim(d.attr(node, "keyFilter")||"");
+ if(keyFilter){
+ cellDef.keyFilter = new RegExp(keyFilter);
+ }
+ };
+
+ dojo.declare("dojox.grid.cells.RowIndex", dgc.Cell, {
+ name: 'Row',
+
+ postscript: function(){
+ this.editable = false;
+ },
+ get: function(inRowIndex){
+ return inRowIndex + 1;
+ }
+ });
+ dgc.RowIndex.markupFactory = function(node, cellDef){
+ dgc.Cell.markupFactory(node, cellDef);
+ };
+
+ dojo.declare("dojox.grid.cells.Select", dgc.Cell, {
+ // summary:
+ // grid cell that provides a standard select for editing
+
+ // options: Array
+ // text of each item
+ options: null,
+
+ // values: Array
+ // value for each item
+ values: null,
+
+ // returnIndex: Integer
+ // editor returns only the index of the selected option and not the value
+ returnIndex: -1,
+
+ constructor: function(inCell){
+ this.values = this.values || this.options;
+ },
+ formatEditing: function(inDatum, inRowIndex){
+ this.needFormatNode(inDatum, inRowIndex);
+ var h = [ '<select class="dojoxGridSelect">' ];
+ for (var i=0, o, v; ((o=this.options[i]) !== undefined)&&((v=this.values[i]) !== undefined); i++){
+ h.push("<option", (inDatum==v ? ' selected' : ''), ' value="' + v + '"', ">", o, "</option>");
+ }
+ h.push('</select>');
+ return h.join('');
+ },
+ getValue: function(inRowIndex){
+ var n = this.getEditNode(inRowIndex);
+ if(n){
+ var i = n.selectedIndex, o = n.options[i];
+ return this.returnIndex > -1 ? i : o.value || o.innerHTML;
+ }
+ }
+ });
+ dgc.Select.markupFactory = function(node, cell){
+ dgc.Cell.markupFactory(node, cell);
+ var d=dojo;
+ var options = d.trim(d.attr(node, "options")||"");
+ if(options){
+ var o = options.split(',');
+ if(o[0] != options){
+ cell.options = o;
+ }
+ }
+ var values = d.trim(d.attr(node, "values")||"");
+ if(values){
+ var v = values.split(',');
+ if(v[0] != values){
+ cell.values = v;
+ }
+ }
+ };
+
+ dojo.declare("dojox.grid.cells.AlwaysEdit", dgc.Cell, {
+ // summary:
+ // grid cell that is always in an editable state, regardless of grid editing state
+ alwaysEditing: true,
+ _formatNode: function(inDatum, inRowIndex){
+ this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex);
+ },
+ applyStaticValue: function(inRowIndex){
+ var e = this.grid.edit;
+ e.applyCellEdit(this.getValue(inRowIndex), this, inRowIndex);
+ e.start(this, inRowIndex, true);
+ }
+ });
+ dgc.AlwaysEdit.markupFactory = function(node, cell){
+ dgc.Cell.markupFactory(node, cell);
+ };
+
+ dojo.declare("dojox.grid.cells.Bool", dgc.AlwaysEdit, {
+ // summary:
+ // grid cell that provides a standard checkbox that is always on for editing
+ _valueProp: "checked",
+ formatEditing: function(inDatum, inRowIndex){
+ return '<input class="dojoxGridInput" type="checkbox"' + (inDatum ? ' checked="checked"' : '') + ' style="width: auto" />';
+ },
+ doclick: function(e){
+ if(e.target.tagName == 'INPUT'){
+ this.applyStaticValue(e.rowIndex);
+ }
+ }
+ });
+ dgc.Bool.markupFactory = function(node, cell){
+ dgc.AlwaysEdit.markupFactory(node, cell);
+ };
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid.cells"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.cells"] = true;
+dojo.provide("dojox.grid.cells");
+
+
+}
+
+if(!dojo._hasResource["dojo.dnd.common"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.common"] = true;
+dojo.provide("dojo.dnd.common");
+
+
+dojo.getObject("dnd", true, dojo);
+
+dojo.dnd.getCopyKeyState = dojo.isCopyKey;
+
+dojo.dnd._uniqueId = 0;
+dojo.dnd.getUniqueId = function(){
+ // summary:
+ // returns a unique string for use with any DOM element
+ var id;
+ do{
+ id = dojo._scopeName + "Unique" + (++dojo.dnd._uniqueId);
+ }while(dojo.byId(id));
+ return id;
+};
+
+dojo.dnd._empty = {};
+
+dojo.dnd.isFormElement = function(/*Event*/ e){
+ // summary:
+ // returns true if user clicked on a form element
+ var t = e.target;
+ if(t.nodeType == 3 /*TEXT_NODE*/){
+ t = t.parentNode;
+ }
+ return " button textarea input select option ".indexOf(" " + t.tagName.toLowerCase() + " ") >= 0; // Boolean
+};
+
+}
+
+if(!dojo._hasResource["dojo.dnd.autoscroll"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.autoscroll"] = true;
+dojo.provide("dojo.dnd.autoscroll");
+
+
+
+dojo.getObject("dnd", true, dojo);
+
+dojo.dnd.getViewport = dojo.window.getBox;
+
+dojo.dnd.V_TRIGGER_AUTOSCROLL = 32;
+dojo.dnd.H_TRIGGER_AUTOSCROLL = 32;
+
+dojo.dnd.V_AUTOSCROLL_VALUE = 16;
+dojo.dnd.H_AUTOSCROLL_VALUE = 16;
+
+dojo.dnd.autoScroll = function(e){
+ // summary:
+ // a handler for onmousemove event, which scrolls the window, if
+ // necesary
+ // e: Event
+ // onmousemove event
+
+ // FIXME: needs more docs!
+ var v = dojo.window.getBox(), dx = 0, dy = 0;
+ if(e.clientX < dojo.dnd.H_TRIGGER_AUTOSCROLL){
+ dx = -dojo.dnd.H_AUTOSCROLL_VALUE;
+ }else if(e.clientX > v.w - dojo.dnd.H_TRIGGER_AUTOSCROLL){
+ dx = dojo.dnd.H_AUTOSCROLL_VALUE;
+ }
+ if(e.clientY < dojo.dnd.V_TRIGGER_AUTOSCROLL){
+ dy = -dojo.dnd.V_AUTOSCROLL_VALUE;
+ }else if(e.clientY > v.h - dojo.dnd.V_TRIGGER_AUTOSCROLL){
+ dy = dojo.dnd.V_AUTOSCROLL_VALUE;
+ }
+ window.scrollBy(dx, dy);
+};
+
+dojo.dnd._validNodes = {"div": 1, "p": 1, "td": 1};
+dojo.dnd._validOverflow = {"auto": 1, "scroll": 1};
+
+dojo.dnd.autoScrollNodes = function(e){
+ // summary:
+ // a handler for onmousemove event, which scrolls the first avaialble
+ // Dom element, it falls back to dojo.dnd.autoScroll()
+ // e: Event
+ // onmousemove event
+
+ // FIXME: needs more docs!
+ for(var n = e.target; n;){
+ if(n.nodeType == 1 && (n.tagName.toLowerCase() in dojo.dnd._validNodes)){
+ var s = dojo.getComputedStyle(n);
+ if(s.overflow.toLowerCase() in dojo.dnd._validOverflow){
+ var b = dojo._getContentBox(n, s), t = dojo.position(n, true);
+ //console.log(b.l, b.t, t.x, t.y, n.scrollLeft, n.scrollTop);
+ var w = Math.min(dojo.dnd.H_TRIGGER_AUTOSCROLL, b.w / 2),
+ h = Math.min(dojo.dnd.V_TRIGGER_AUTOSCROLL, b.h / 2),
+ rx = e.pageX - t.x, ry = e.pageY - t.y, dx = 0, dy = 0;
+ if(dojo.isWebKit || dojo.isOpera){
+ // FIXME: this code should not be here, it should be taken into account
+ // either by the event fixing code, or the dojo.position()
+ // FIXME: this code doesn't work on Opera 9.5 Beta
+ rx += dojo.body().scrollLeft;
+ ry += dojo.body().scrollTop;
+ }
+ if(rx > 0 && rx < b.w){
+ if(rx < w){
+ dx = -w;
+ }else if(rx > b.w - w){
+ dx = w;
+ }
+ }
+ //console.log("ry =", ry, "b.h =", b.h, "h =", h);
+ if(ry > 0 && ry < b.h){
+ if(ry < h){
+ dy = -h;
+ }else if(ry > b.h - h){
+ dy = h;
+ }
+ }
+ var oldLeft = n.scrollLeft, oldTop = n.scrollTop;
+ n.scrollLeft = n.scrollLeft + dx;
+ n.scrollTop = n.scrollTop + dy;
+ if(oldLeft != n.scrollLeft || oldTop != n.scrollTop){ return; }
+ }
+ }
+ try{
+ n = n.parentNode;
+ }catch(x){
+ n = null;
+ }
+ }
+ dojo.dnd.autoScroll(e);
+};
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Mover"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Mover"] = true;
+dojo.provide("dojo.dnd.Mover");
+
+
+
+
+
+dojo.declare("dojo.dnd.Mover", null, {
+ constructor: function(node, e, host){
+ // summary:
+ // an object which makes a node follow the mouse, or touch-drag on touch devices.
+ // Used as a default mover, and as a base class for custom movers.
+ // node: Node
+ // a node (or node's id) to be moved
+ // e: Event
+ // a mouse event, which started the move;
+ // only pageX and pageY properties are used
+ // host: Object?
+ // object which implements the functionality of the move,
+ // and defines proper events (onMoveStart and onMoveStop)
+ this.node = dojo.byId(node);
+ var pos = e.touches ? e.touches[0] : e;
+ this.marginBox = {l: pos.pageX, t: pos.pageY};
+ this.mouseButton = e.button;
+ var h = (this.host = host), d = node.ownerDocument;
+ this.events = [
+ // At the start of a drag, onFirstMove is called, and then the following two
+ // connects are disconnected
+ dojo.connect(d, "onmousemove", this, "onFirstMove"),
+ dojo.connect(d, "ontouchmove", this, "onFirstMove"),
+
+ // These are called continually during the drag
+ dojo.connect(d, "onmousemove", this, "onMouseMove"),
+ dojo.connect(d, "ontouchmove", this, "onMouseMove"),
+
+ // And these are called at the end of the drag
+ dojo.connect(d, "onmouseup", this, "onMouseUp"),
+ dojo.connect(d, "ontouchend", this, "onMouseUp"),
+
+ // cancel text selection and text dragging
+ dojo.connect(d, "ondragstart", dojo.stopEvent),
+ dojo.connect(d.body, "onselectstart", dojo.stopEvent)
+ ];
+ // notify that the move has started
+ if(h && h.onMoveStart){
+ h.onMoveStart(this);
+ }
+ },
+ // mouse event processors
+ onMouseMove: function(e){
+ // summary:
+ // event processor for onmousemove/ontouchmove
+ // e: Event
+ // mouse/touch event
+ dojo.dnd.autoScroll(e);
+ var m = this.marginBox,
+ pos = e.touches ? e.touches[0] : e;
+ this.host.onMove(this, {l: m.l + pos.pageX, t: m.t + pos.pageY}, e);
+ dojo.stopEvent(e);
+ },
+ onMouseUp: function(e){
+ if(dojo.isWebKit && dojo.isMac && this.mouseButton == 2 ?
+ e.button == 0 : this.mouseButton == e.button){ // TODO Should condition be met for touch devices, too?
+ this.destroy();
+ }
+ dojo.stopEvent(e);
+ },
+ // utilities
+ onFirstMove: function(e){
+ // summary:
+ // makes the node absolute; it is meant to be called only once.
+ // relative and absolutely positioned nodes are assumed to use pixel units
+ var s = this.node.style, l, t, h = this.host;
+ switch(s.position){
+ case "relative":
+ case "absolute":
+ // assume that left and top values are in pixels already
+ l = Math.round(parseFloat(s.left)) || 0;
+ t = Math.round(parseFloat(s.top)) || 0;
+ break;
+ default:
+ s.position = "absolute"; // enforcing the absolute mode
+ var m = dojo.marginBox(this.node);
+ // event.pageX/pageY (which we used to generate the initial
+ // margin box) includes padding and margin set on the body.
+ // However, setting the node's position to absolute and then
+ // doing dojo.marginBox on it *doesn't* take that additional
+ // space into account - so we need to subtract the combined
+ // padding and margin. We use getComputedStyle and
+ // _getMarginBox/_getContentBox to avoid the extra lookup of
+ // the computed style.
+ var b = dojo.doc.body;
+ var bs = dojo.getComputedStyle(b);
+ var bm = dojo._getMarginBox(b, bs);
+ var bc = dojo._getContentBox(b, bs);
+ l = m.l - (bc.l - bm.l);
+ t = m.t - (bc.t - bm.t);
+ break;
+ }
+ this.marginBox.l = l - this.marginBox.l;
+ this.marginBox.t = t - this.marginBox.t;
+ if(h && h.onFirstMove){
+ h.onFirstMove(this, e);
+ }
+
+ // Disconnect onmousemove and ontouchmove events that call this function
+ dojo.disconnect(this.events.shift());
+ dojo.disconnect(this.events.shift());
+ },
+ destroy: function(){
+ // summary:
+ // stops the move, deletes all references, so the object can be garbage-collected
+ dojo.forEach(this.events, dojo.disconnect);
+ // undo global settings
+ var h = this.host;
+ if(h && h.onMoveStop){
+ h.onMoveStop(this);
+ }
+ // destroy objects
+ this.events = this.node = this.host = null;
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Moveable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Moveable"] = true;
+dojo.provide("dojo.dnd.Moveable");
+
+
+
+
+/*=====
+dojo.declare("dojo.dnd.__MoveableArgs", [], {
+ // handle: Node||String
+ // A node (or node's id), which is used as a mouse handle.
+ // If omitted, the node itself is used as a handle.
+ handle: null,
+
+ // delay: Number
+ // delay move by this number of pixels
+ delay: 0,
+
+ // skip: Boolean
+ // skip move of form elements
+ skip: false,
+
+ // mover: Object
+ // a constructor of custom Mover
+ mover: dojo.dnd.Mover
+});
+=====*/
+
+dojo.declare("dojo.dnd.Moveable", null, {
+ // object attributes (for markup)
+ handle: "",
+ delay: 0,
+ skip: false,
+
+ constructor: function(node, params){
+ // summary:
+ // an object, which makes a node moveable
+ // node: Node
+ // a node (or node's id) to be moved
+ // params: dojo.dnd.__MoveableArgs?
+ // optional parameters
+ this.node = dojo.byId(node);
+ if(!params){ params = {}; }
+ this.handle = params.handle ? dojo.byId(params.handle) : null;
+ if(!this.handle){ this.handle = this.node; }
+ this.delay = params.delay > 0 ? params.delay : 0;
+ this.skip = params.skip;
+ this.mover = params.mover ? params.mover : dojo.dnd.Mover;
+ this.events = [
+ dojo.connect(this.handle, "onmousedown", this, "onMouseDown"),
+ dojo.connect(this.handle, "ontouchstart", this, "onMouseDown"),
+ // cancel text selection and text dragging
+ dojo.connect(this.handle, "ondragstart", this, "onSelectStart"),
+ dojo.connect(this.handle, "onselectstart", this, "onSelectStart")
+ ];
+ },
+
+ // markup methods
+ markupFactory: function(params, node){
+ return new dojo.dnd.Moveable(node, params);
+ },
+
+ // methods
+ destroy: function(){
+ // summary:
+ // stops watching for possible move, deletes all references, so the object can be garbage-collected
+ dojo.forEach(this.events, dojo.disconnect);
+ this.events = this.node = this.handle = null;
+ },
+
+ // mouse event processors
+ onMouseDown: function(e){
+ // summary:
+ // event processor for onmousedown/ontouchstart, creates a Mover for the node
+ // e: Event
+ // mouse/touch event
+ if(this.skip && dojo.dnd.isFormElement(e)){ return; }
+ if(this.delay){
+ this.events.push(
+ dojo.connect(this.handle, "onmousemove", this, "onMouseMove"),
+ dojo.connect(this.handle, "ontouchmove", this, "onMouseMove"),
+ dojo.connect(this.handle, "onmouseup", this, "onMouseUp"),
+ dojo.connect(this.handle, "ontouchend", this, "onMouseUp")
+ );
+ var pos = e.touches ? e.touches[0] : e;
+ this._lastX = pos.pageX;
+ this._lastY = pos.pageY;
+ }else{
+ this.onDragDetected(e);
+ }
+ dojo.stopEvent(e);
+ },
+ onMouseMove: function(e){
+ // summary:
+ // event processor for onmousemove/ontouchmove, used only for delayed drags
+ // e: Event
+ // mouse/touch event
+ var pos = e.touches ? e.touches[0] : e;
+ if(Math.abs(pos.pageX - this._lastX) > this.delay || Math.abs(pos.pageY - this._lastY) > this.delay){
+ this.onMouseUp(e);
+ this.onDragDetected(e);
+ }
+ dojo.stopEvent(e);
+ },
+ onMouseUp: function(e){
+ // summary:
+ // event processor for onmouseup, used only for delayed drags
+ // e: Event
+ // mouse event
+ for(var i = 0; i < 2; ++i){
+ dojo.disconnect(this.events.pop());
+ }
+ dojo.stopEvent(e);
+ },
+ onSelectStart: function(e){
+ // summary:
+ // event processor for onselectevent and ondragevent
+ // e: Event
+ // mouse event
+ if(!this.skip || !dojo.dnd.isFormElement(e)){
+ dojo.stopEvent(e);
+ }
+ },
+
+ // local events
+ onDragDetected: function(/* Event */ e){
+ // summary:
+ // called when the drag is detected;
+ // responsible for creation of the mover
+ new this.mover(this.node, e, this);
+ },
+ onMoveStart: function(/* dojo.dnd.Mover */ mover){
+ // summary:
+ // called before every move operation
+ dojo.publish("/dnd/move/start", [mover]);
+ dojo.addClass(dojo.body(), "dojoMove");
+ dojo.addClass(this.node, "dojoMoveItem");
+ },
+ onMoveStop: function(/* dojo.dnd.Mover */ mover){
+ // summary:
+ // called after every move operation
+ dojo.publish("/dnd/move/stop", [mover]);
+ dojo.removeClass(dojo.body(), "dojoMove");
+ dojo.removeClass(this.node, "dojoMoveItem");
+ },
+ onFirstMove: function(/* dojo.dnd.Mover */ mover, /* Event */ e){
+ // summary:
+ // called during the very first move notification;
+ // can be used to initialize coordinates, can be overwritten.
+
+ // default implementation does nothing
+ },
+ onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop, /* Event */ e){
+ // summary:
+ // called during every move notification;
+ // should actually move the node; can be overwritten.
+ this.onMoving(mover, leftTop);
+ var s = mover.node.style;
+ s.left = leftTop.l + "px";
+ s.top = leftTop.t + "px";
+ this.onMoved(mover, leftTop);
+ },
+ onMoving: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+ // summary:
+ // called before every incremental move; can be overwritten.
+
+ // default implementation does nothing
+ },
+ onMoved: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+ // summary:
+ // called after every incremental move; can be overwritten.
+
+ // default implementation does nothing
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._Builder"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Builder"] = true;
+dojo.provide("dojox.grid._Builder");
+
+
+
+
+(function(){
+ var dg = dojox.grid;
+
+ var getTdIndex = function(td){
+ return td.cellIndex >=0 ? td.cellIndex : dojo.indexOf(td.parentNode.cells, td);
+ };
+
+ var getTrIndex = function(tr){
+ return tr.rowIndex >=0 ? tr.rowIndex : dojo.indexOf(tr.parentNode.childNodes, tr);
+ };
+
+ var getTr = function(rowOwner, index){
+ return rowOwner && ((rowOwner.rows||0)[index] || rowOwner.childNodes[index]);
+ };
+
+ var findTable = function(node){
+ for(var n=node; n && n.tagName!='TABLE'; n=n.parentNode){}
+ return n;
+ };
+
+ var ascendDom = function(inNode, inWhile){
+ for(var n=inNode; n && inWhile(n); n=n.parentNode){}
+ return n;
+ };
+
+ var makeNotTagName = function(inTagName){
+ var name = inTagName.toUpperCase();
+ return function(node){ return node.tagName != name; };
+ };
+
+ var rowIndexTag = dojox.grid.util.rowIndexTag;
+ var gridViewTag = dojox.grid.util.gridViewTag;
+
+ // base class for generating markup for the views
+ dg._Builder = dojo.extend(function(view){
+ if(view){
+ this.view = view;
+ this.grid = view.grid;
+ }
+ },{
+ view: null,
+ // boilerplate HTML
+ _table: '<table class="dojoxGridRowTable" border="0" cellspacing="0" cellpadding="0" role="presentation"',
+
+ // Returns the table variable as an array - and with the view width, if specified
+ getTableArray: function(){
+ var html = [this._table];
+ if(this.view.viewWidth){
+ html.push([' style="width:', this.view.viewWidth, ';"'].join(''));
+ }
+ html.push('>');
+ return html;
+ },
+
+ // generate starting tags for a cell
+ generateCellMarkup: function(inCell, inMoreStyles, inMoreClasses, isHeader){
+ var result = [], html;
+ if(isHeader){
+ var sortInfo = inCell.index != inCell.grid.getSortIndex() ? "" : inCell.grid.sortInfo > 0 ? 'aria-sort="ascending"' : 'aria-sort="descending"';
+ if (!inCell.id){
+ inCell.id = this.grid.id + "Hdr" + inCell.index;
+ }
+ // column headers are not editable, mark as aria-readonly=true
+ html = ['<th tabIndex="-1" aria-readonly="true" role="columnheader"', sortInfo, 'id="', inCell.id, '"'];
+ }else{
+ // cells inherit grid aria-readonly property; default value for aria-readonly is false(grid is editable)
+ // if grid is editable (had any editable cells), mark non editable cells as aria-readonly=true
+ // if no editable cells, grid's aria-readonly value will have been set to true and cells will inherit
+ var editInfo = this.grid.editable && !inCell.editable ? 'aria-readonly="true"' : "";
+ html = ['<td tabIndex="-1" role="gridcell"', editInfo];
+ }
+ if(inCell.colSpan){
+ html.push(' colspan="', inCell.colSpan, '"');
+ }
+ if(inCell.rowSpan){
+ html.push(' rowspan="', inCell.rowSpan, '"');
+ }
+ html.push(' class="dojoxGridCell ');
+ if(inCell.classes){
+ html.push(inCell.classes, ' ');
+ }
+ if(inMoreClasses){
+ html.push(inMoreClasses, ' ');
+ }
+ // result[0] => td opener, style
+ result.push(html.join(''));
+ // SLOT: result[1] => td classes
+ result.push('');
+ html = ['" idx="', inCell.index, '" style="'];
+ if(inMoreStyles && inMoreStyles[inMoreStyles.length-1] != ';'){
+ inMoreStyles += ';';
+ }
+ html.push(inCell.styles, inMoreStyles||'', inCell.hidden?'display:none;':'');
+ if(inCell.unitWidth){
+ html.push('width:', inCell.unitWidth, ';');
+ }
+ // result[2] => markup
+ result.push(html.join(''));
+ // SLOT: result[3] => td style
+ result.push('');
+ html = [ '"' ];
+ if(inCell.attrs){
+ html.push(" ", inCell.attrs);
+ }
+ html.push('>');
+ // result[4] => td postfix
+ result.push(html.join(''));
+ // SLOT: result[5] => content
+ result.push('');
+ // result[6] => td closes
+ result.push(isHeader?'</th>':'</td>');
+ return result; // Array
+ },
+
+ // cell finding
+ isCellNode: function(inNode){
+ return Boolean(inNode && inNode!=dojo.doc && dojo.attr(inNode, "idx"));
+ },
+
+ getCellNodeIndex: function(inCellNode){
+ return inCellNode ? Number(dojo.attr(inCellNode, "idx")) : -1;
+ },
+
+ getCellNode: function(inRowNode, inCellIndex){
+ for(var i=0, row; (row=getTr(inRowNode.firstChild, i)); i++){
+ for(var j=0, cell; (cell=row.cells[j]); j++){
+ if(this.getCellNodeIndex(cell) == inCellIndex){
+ return cell;
+ }
+ }
+ }
+ return null;
+ },
+
+ findCellTarget: function(inSourceNode, inTopNode){
+ var n = inSourceNode;
+ while(n && (!this.isCellNode(n) || (n.offsetParent && gridViewTag in n.offsetParent.parentNode && n.offsetParent.parentNode[gridViewTag] != this.view.id)) && (n!=inTopNode)){
+ n = n.parentNode;
+ }
+ return n!=inTopNode ? n : null;
+ },
+
+ // event decoration
+ baseDecorateEvent: function(e){
+ e.dispatch = 'do' + e.type;
+ e.grid = this.grid;
+ e.sourceView = this.view;
+ e.cellNode = this.findCellTarget(e.target, e.rowNode);
+ e.cellIndex = this.getCellNodeIndex(e.cellNode);
+ e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null);
+ },
+
+ // event dispatch
+ findTarget: function(inSource, inTag){
+ var n = inSource;
+ while(n && (n!=this.domNode) && (!(inTag in n) || (gridViewTag in n && n[gridViewTag] != this.view.id))){
+ n = n.parentNode;
+ }
+ return (n != this.domNode) ? n : null;
+ },
+
+ findRowTarget: function(inSource){
+ return this.findTarget(inSource, rowIndexTag);
+ },
+
+ isIntraNodeEvent: function(e){
+ try{
+ return (e.cellNode && e.relatedTarget && dojo.isDescendant(e.relatedTarget, e.cellNode));
+ }catch(x){
+ // e.relatedTarget has permission problem in FF if it's an input: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+ return false;
+ }
+ },
+
+ isIntraRowEvent: function(e){
+ try{
+ var row = e.relatedTarget && this.findRowTarget(e.relatedTarget);
+ return !row && (e.rowIndex==-1) || row && (e.rowIndex==row.gridRowIndex);
+ }catch(x){
+ // e.relatedTarget on INPUT has permission problem in FF: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+ return false;
+ }
+ },
+
+ dispatchEvent: function(e){
+ if(e.dispatch in this){
+ return this[e.dispatch](e);
+ }
+ return false;
+ },
+
+ // dispatched event handlers
+ domouseover: function(e){
+ if(e.cellNode && (e.cellNode!=this.lastOverCellNode)){
+ this.lastOverCellNode = e.cellNode;
+ this.grid.onMouseOver(e);
+ }
+ this.grid.onMouseOverRow(e);
+ },
+
+ domouseout: function(e){
+ if(e.cellNode && (e.cellNode==this.lastOverCellNode) && !this.isIntraNodeEvent(e, this.lastOverCellNode)){
+ this.lastOverCellNode = null;
+ this.grid.onMouseOut(e);
+ if(!this.isIntraRowEvent(e)){
+ this.grid.onMouseOutRow(e);
+ }
+ }
+ },
+
+ domousedown: function(e){
+ if (e.cellNode)
+ this.grid.onMouseDown(e);
+ this.grid.onMouseDownRow(e);
+ }
+ });
+
+ // Produces html for grid data content. Owned by grid and used internally
+ // for rendering data. Override to implement custom rendering.
+ dg._ContentBuilder = dojo.extend(function(view){
+ dg._Builder.call(this, view);
+ },dg._Builder.prototype,{
+ update: function(){
+ this.prepareHtml();
+ },
+
+ // cache html for rendering data rows
+ prepareHtml: function(){
+ var defaultGet=this.grid.get, cells=this.view.structure.cells;
+ for(var j=0, row; (row=cells[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ cell.get = cell.get || (cell.value == undefined) && defaultGet;
+ cell.markup = this.generateCellMarkup(cell, cell.cellStyles, cell.cellClasses, false);
+ if (!this.grid.editable && cell.editable){
+ this.grid.editable = true;
+ }
+ }
+ }
+ },
+
+ // time critical: generate html using cache and data source
+ generateHtml: function(inDataIndex, inRowIndex){
+ var
+ html = this.getTableArray(),
+ v = this.view,
+ cells = v.structure.cells,
+ item = this.grid.getItem(inRowIndex);
+
+ dojox.grid.util.fire(this.view, "onBeforeRow", [inRowIndex, cells]);
+ for(var j=0, row; (row=cells[j]); j++){
+ if(row.hidden || row.header){
+ continue;
+ }
+ html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
+ for(var i=0, cell, m, cc, cs; (cell=row[i]); i++){
+ m = cell.markup; cc = cell.customClasses = []; cs = cell.customStyles = [];
+ // content (format can fill in cc and cs as side-effects)
+ m[5] = cell.format(inRowIndex, item);
+ // classes
+ m[1] = cc.join(' ');
+ // styles
+ m[3] = cs.join(';');
+ // in-place concat
+ html.push.apply(html, m);
+ }
+ html.push('</tr>');
+ }
+ html.push('</table>');
+ return html.join(''); // String
+ },
+
+ decorateEvent: function(e){
+ e.rowNode = this.findRowTarget(e.target);
+ if(!e.rowNode){return false;}
+ e.rowIndex = e.rowNode[rowIndexTag];
+ this.baseDecorateEvent(e);
+ e.cell = this.grid.getCell(e.cellIndex);
+ return true; // Boolean
+ }
+ });
+
+ // Produces html for grid header content. Owned by grid and used internally
+ // for rendering data. Override to implement custom rendering.
+ dg._HeaderBuilder = dojo.extend(function(view){
+ this.moveable = null;
+ dg._Builder.call(this, view);
+ },dg._Builder.prototype,{
+ _skipBogusClicks: false,
+ overResizeWidth: 4,
+ minColWidth: 1,
+
+ update: function(){
+ if(this.tableMap){
+ this.tableMap.mapRows(this.view.structure.cells);
+ }else{
+ this.tableMap = new dg._TableMap(this.view.structure.cells);
+ }
+ },
+
+ generateHtml: function(inGetValue, inValue){
+ var html = this.getTableArray(), cells = this.view.structure.cells;
+
+ dojox.grid.util.fire(this.view, "onBeforeRow", [-1, cells]);
+ for(var j=0, row; (row=cells[j]); j++){
+ if(row.hidden){
+ continue;
+ }
+ html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
+ for(var i=0, cell, markup; (cell=row[i]); i++){
+ cell.customClasses = [];
+ cell.customStyles = [];
+ if(this.view.simpleStructure){
+ if(cell.draggable){
+ if(cell.headerClasses){
+ if(cell.headerClasses.indexOf('dojoDndItem') == -1){
+ cell.headerClasses += ' dojoDndItem';
+ }
+ }else{
+ cell.headerClasses = 'dojoDndItem';
+ }
+ }
+ if(cell.attrs){
+ if(cell.attrs.indexOf("dndType='gridColumn_") == -1){
+ cell.attrs += " dndType='gridColumn_" + this.grid.id + "'";
+ }
+ }else{
+ cell.attrs = "dndType='gridColumn_" + this.grid.id + "'";
+ }
+ }
+ markup = this.generateCellMarkup(cell, cell.headerStyles, cell.headerClasses, true);
+ // content
+ markup[5] = (inValue != undefined ? inValue : inGetValue(cell));
+ // styles
+ markup[3] = cell.customStyles.join(';');
+ // classes
+ markup[1] = cell.customClasses.join(' '); //(cell.customClasses ? ' ' + cell.customClasses : '');
+ html.push(markup.join(''));
+ }
+ html.push('</tr>');
+ }
+ html.push('</table>');
+ return html.join('');
+ },
+
+ // event helpers
+ getCellX: function(e){
+ var n, x = e.layerX;
+ if(dojo.isMoz){
+ n = ascendDom(e.target, makeNotTagName("th"));
+ x -= (n && n.offsetLeft) || 0;
+ var t = e.sourceView.getScrollbarWidth();
+ if(!dojo._isBodyLtr()/*&& e.sourceView.headerNode.scrollLeft < t*/){
+ //fix #11253
+ table = ascendDom(n,makeNotTagName("table"));
+ x -= (table && table.offsetLeft) || 0;
+ }
+ //x -= getProp(ascendDom(e.target, mkNotTagName("td")), "offsetLeft") || 0;
+ }
+ n = ascendDom(e.target, function(){
+ if(!n || n == e.cellNode){
+ return false;
+ }
+ // Mozilla 1.8 (FF 1.5) has a bug that makes offsetLeft = -parent border width
+ // when parent has border, overflow: hidden, and is positioned
+ // handle this problem here ... not a general solution!
+ x += (n.offsetLeft < 0 ? 0 : n.offsetLeft);
+ return true;
+ });
+ return x;
+ },
+
+ // event decoration
+ decorateEvent: function(e){
+ this.baseDecorateEvent(e);
+ e.rowIndex = -1;
+ e.cellX = this.getCellX(e);
+ return true;
+ },
+
+ // event handlers
+ // resizing
+ prepareResize: function(e, mod){
+ do{
+ var i = getTdIndex(e.cellNode);
+ e.cellNode = (i ? e.cellNode.parentNode.cells[i+mod] : null);
+ e.cellIndex = (e.cellNode ? this.getCellNodeIndex(e.cellNode) : -1);
+ }while(e.cellNode && e.cellNode.style.display == "none");
+ return Boolean(e.cellNode);
+ },
+
+ canResize: function(e){
+ if(!e.cellNode || e.cellNode.colSpan > 1){
+ return false;
+ }
+ var cell = this.grid.getCell(e.cellIndex);
+ return !cell.noresize && cell.canResize();
+ },
+
+ overLeftResizeArea: function(e){
+ // We are never over a resize area if we are in the process of moving
+ if(dojo.hasClass(dojo.body(), "dojoDndMove")){
+ return false;
+ }
+ //Bugfix for crazy IE problem (#8807). IE returns position information for the icon and text arrow divs
+ //as if they were still on the left instead of returning the position they were 'float: right' to.
+ //So, the resize check ends up checking the wrong adjacent cell. This checks to see if the hover was over
+ //the image or text nodes, then just ignored them/treat them not in scale range.
+ if(dojo.isIE){
+ var tN = e.target;
+ if(dojo.hasClass(tN, "dojoxGridArrowButtonNode") ||
+ dojo.hasClass(tN, "dojoxGridArrowButtonChar")){
+ return false;
+ }
+ }
+
+ if(dojo._isBodyLtr()){
+ return (e.cellIndex>0) && (e.cellX > 0 && e.cellX < this.overResizeWidth) && this.prepareResize(e, -1);
+ }
+ var t = e.cellNode && (e.cellX > 0 && e.cellX < this.overResizeWidth);
+ return t;
+ },
+
+ overRightResizeArea: function(e){
+ // We are never over a resize area if we are in the process of moving
+ if(dojo.hasClass(dojo.body(), "dojoDndMove")){
+ return false;
+ }
+ //Bugfix for crazy IE problem (#8807). IE returns position information for the icon and text arrow divs
+ //as if they were still on the left instead of returning the position they were 'float: right' to.
+ //So, the resize check ends up checking the wrong adjacent cell. This checks to see if the hover was over
+ //the image or text nodes, then just ignored them/treat them not in scale range.
+ if(dojo.isIE){
+ var tN = e.target;
+ if(dojo.hasClass(tN, "dojoxGridArrowButtonNode") ||
+ dojo.hasClass(tN, "dojoxGridArrowButtonChar")){
+ return false;
+ }
+ }
+
+ if(dojo._isBodyLtr()){
+ return e.cellNode && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth);
+ }
+ return (e.cellIndex>0) && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth) && this.prepareResize(e, -1);
+ },
+
+ domousemove: function(e){
+ //console.log(e.cellIndex, e.cellX, e.cellNode.offsetWidth);
+ if(!this.moveable){
+ var c = (this.overRightResizeArea(e) ? 'dojoxGridColResize' : (this.overLeftResizeArea(e) ? 'dojoxGridColResize' : ''));
+ if(c && !this.canResize(e)){
+ c = 'dojoxGridColNoResize';
+ }
+ dojo.toggleClass(e.sourceView.headerNode, "dojoxGridColNoResize", (c == "dojoxGridColNoResize"));
+ dojo.toggleClass(e.sourceView.headerNode, "dojoxGridColResize", (c == "dojoxGridColResize"));
+ if(dojo.isIE){
+ var t = e.sourceView.headerNode.scrollLeft;
+ e.sourceView.headerNode.scrollLeft = t;
+ }
+ if(c){
+ dojo.stopEvent(e);
+ }
+ }
+ },
+
+ domousedown: function(e){
+ if(!this.moveable){
+ if((this.overRightResizeArea(e) || this.overLeftResizeArea(e)) && this.canResize(e)){
+ this.beginColumnResize(e);
+ }else{
+ this.grid.onMouseDown(e);
+ this.grid.onMouseOverRow(e);
+ }
+ //else{
+ // this.beginMoveColumn(e);
+ //}
+ }
+ },
+
+ doclick: function(e) {
+ if(this._skipBogusClicks){
+ dojo.stopEvent(e);
+ return true;
+ }
+ return false;
+ },
+
+ // column resizing
+ colResizeSetup: function(/*Event Object*/e, /*boolean*/ isMouse ){
+ //Set up the drag object for column resizing
+ // Called with mouse event in case of drag and drop,
+ // Also called from keyboard shift-arrow event when focus is on a header
+ var headContentBox = dojo.contentBox(e.sourceView.headerNode);
+
+ if(isMouse){ //IE draws line even with no mouse down so separate from keyboard
+ this.lineDiv = document.createElement('div');
+
+ // NOTE: this is for backwards compatibility with Dojo 1.3
+ var vw = (dojo.position||dojo._abs)(e.sourceView.headerNode, true);
+ var bodyContentBox = dojo.contentBox(e.sourceView.domNode);
+ //fix #11340
+ var l = e.pageX;
+ if(!dojo._isBodyLtr() && dojo.isIE < 8){
+ l -= dojox.html.metrics.getScrollbar().w;
+ }
+ dojo.style(this.lineDiv, {
+ top: vw.y + "px",
+ left: l + "px",
+ height: (bodyContentBox.h + headContentBox.h) + "px"
+ });
+ dojo.addClass(this.lineDiv, "dojoxGridResizeColLine");
+ this.lineDiv._origLeft = l;
+ dojo.body().appendChild(this.lineDiv);
+ }
+ var spanners = [], nodes = this.tableMap.findOverlappingNodes(e.cellNode);
+ for(var i=0, cell; (cell=nodes[i]); i++){
+ spanners.push({ node: cell, index: this.getCellNodeIndex(cell), width: cell.offsetWidth });
+ //console.log("spanner: " + this.getCellNodeIndex(cell));
+ }
+
+ var view = e.sourceView;
+ var adj = dojo._isBodyLtr() ? 1 : -1;
+ var views = e.grid.views.views;
+ var followers = [];
+ for(var j=view.idx+adj, cView; (cView=views[j]); j=j+adj){
+ followers.push({ node: cView.headerNode, left: window.parseInt(cView.headerNode.style.left) });
+ }
+ var table = view.headerContentNode.firstChild;
+ var drag = {
+ scrollLeft: e.sourceView.headerNode.scrollLeft,
+ view: view,
+ node: e.cellNode,
+ index: e.cellIndex,
+ w: dojo.contentBox(e.cellNode).w,
+ vw: headContentBox.w,
+ table: table,
+ tw: dojo.contentBox(table).w,
+ spanners: spanners,
+ followers: followers
+ };
+ return drag;
+ },
+ beginColumnResize: function(e){
+ this.moverDiv = document.createElement("div");
+ dojo.style(this.moverDiv,{position: "absolute", left:0}); // to make DnD work with dir=rtl
+ dojo.body().appendChild(this.moverDiv);
+ dojo.addClass(this.grid.domNode, "dojoxGridColumnResizing");
+ var m = (this.moveable = new dojo.dnd.Moveable(this.moverDiv));
+
+ var drag = this.colResizeSetup(e,true);
+
+ m.onMove = dojo.hitch(this, "doResizeColumn", drag);
+
+ dojo.connect(m, "onMoveStop", dojo.hitch(this, function(){
+ this.endResizeColumn(drag);
+ if(drag.node.releaseCapture){
+ drag.node.releaseCapture();
+ }
+ this.moveable.destroy();
+ delete this.moveable;
+ this.moveable = null;
+ dojo.removeClass(this.grid.domNode, "dojoxGridColumnResizing");
+ }));
+
+ if(e.cellNode.setCapture){
+ e.cellNode.setCapture();
+ }
+ m.onMouseDown(e);
+ },
+
+ doResizeColumn: function(inDrag, mover, leftTop){
+ var changeX = leftTop.l;
+ var data = {
+ deltaX: changeX,
+ w: inDrag.w + (dojo._isBodyLtr() ? changeX : -changeX),//fix #11341
+ vw: inDrag.vw + changeX,
+ tw: inDrag.tw + changeX
+ };
+
+ this.dragRecord = {inDrag: inDrag, mover: mover, leftTop:leftTop};
+
+ if(data.w >= this.minColWidth){
+ if (!mover) { // we are using keyboard do immediate resize
+ this.doResizeNow(inDrag, data);
+ }
+ else{
+ dojo.style(this.lineDiv, "left", (this.lineDiv._origLeft + data.deltaX) + "px");
+ }
+ }
+ },
+
+ endResizeColumn: function(inDrag){
+ if(this.dragRecord){
+ var leftTop = this.dragRecord.leftTop;
+ var changeX = dojo._isBodyLtr() ? leftTop.l : -leftTop.l;
+ // Make sure we are not under our minimum
+ // http://bugs.dojotoolkit.org/ticket/9390
+ changeX += Math.max(inDrag.w + changeX, this.minColWidth) - (inDrag.w + changeX);
+ if(dojo.isWebKit && inDrag.spanners.length){
+ // Webkit needs the pad border extents back in
+ changeX += dojo._getPadBorderExtents(inDrag.spanners[0].node).w;
+ }
+ var data = {
+ deltaX: changeX,
+ w: inDrag.w + changeX,
+ vw: inDrag.vw + changeX,
+ tw: inDrag.tw + changeX
+ };
+ // Only resize the columns when the drag has finished
+ this.doResizeNow(inDrag, data);
+ delete this.dragRecord;
+ }
+
+ dojo.destroy(this.lineDiv);
+ dojo.destroy(this.moverDiv);
+ dojo.destroy(this.moverDiv);
+ delete this.moverDiv;
+ this._skipBogusClicks = true;
+ inDrag.view.update();
+ this._skipBogusClicks = false;
+ this.grid.onResizeColumn(inDrag.index);
+ },
+ doResizeNow: function(inDrag, data){
+ inDrag.view.convertColPctToFixed();
+ if(inDrag.view.flexCells && !inDrag.view.testFlexCells()){
+ var t = findTable(inDrag.node);
+ if(t){
+ (t.style.width = '');
+ }
+ }
+ var i, s, sw, f, fl;
+ for(i=0; (s=inDrag.spanners[i]); i++){
+ sw = s.width + data.deltaX;
+ s.node.style.width = sw + 'px';
+ inDrag.view.setColWidth(s.index, sw);
+ }
+ if(dojo._isBodyLtr() || !dojo.isIE){//fix #11339
+ for(i=0; (f=inDrag.followers[i]); i++){
+ fl = f.left + data.deltaX;
+ f.node.style.left = fl + 'px';
+ }
+ }
+ inDrag.node.style.width = data.w + 'px';
+ inDrag.view.setColWidth(inDrag.index, data.w);
+ inDrag.view.headerNode.style.width = data.vw + 'px';
+ inDrag.view.setColumnsWidth(data.tw);
+ if(!dojo._isBodyLtr()){
+ inDrag.view.headerNode.scrollLeft = inDrag.scrollLeft + data.deltaX;
+ }
+ }
+ });
+
+ // Maps an html table into a structure parsable for information about cell row and col spanning.
+ // Used by HeaderBuilder.
+ dg._TableMap = dojo.extend(function(rows){
+ this.mapRows(rows);
+ },{
+ map: null,
+
+ mapRows: function(inRows){
+ // summary: Map table topography
+
+ //console.log('mapRows');
+ // # of rows
+ var rowCount = inRows.length;
+ if(!rowCount){
+ return;
+ }
+ // map which columns and rows fill which cells
+ this.map = [];
+ var row;
+ for(var k=0; (row=inRows[k]); k++){
+ this.map[k] = [];
+ }
+ for(var j=0; (row=inRows[j]); j++){
+ for(var i=0, x=0, cell, colSpan, rowSpan; (cell=row[i]); i++){
+ while(this.map[j][x]){x++;}
+ this.map[j][x] = { c: i, r: j };
+ rowSpan = cell.rowSpan || 1;
+ colSpan = cell.colSpan || 1;
+ for(var y=0; y<rowSpan; y++){
+ for(var s=0; s<colSpan; s++){
+ this.map[j+y][x+s] = this.map[j][x];
+ }
+ }
+ x += colSpan;
+ }
+ }
+ //this.dumMap();
+ },
+
+ dumpMap: function(){
+ for(var j=0, row, h=''; (row=this.map[j]); j++,h=''){
+ for(var i=0, cell; (cell=row[i]); i++){
+ h += cell.r + ',' + cell.c + ' ';
+ }
+ }
+ },
+
+ getMapCoords: function(inRow, inCol){
+ // summary: Find node's map coords by it's structure coords
+ for(var j=0, row; (row=this.map[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ if(cell.c==inCol && cell.r == inRow){
+ return { j: j, i: i };
+ }
+ //else{console.log(inRow, inCol, ' : ', i, j, " : ", cell.r, cell.c); };
+ }
+ }
+ return { j: -1, i: -1 };
+ },
+
+ getNode: function(inTable, inRow, inCol){
+ // summary: Find a node in inNode's table with the given structure coords
+ var row = inTable && inTable.rows[inRow];
+ return row && row.cells[inCol];
+ },
+
+ _findOverlappingNodes: function(inTable, inRow, inCol){
+ var nodes = [];
+ var m = this.getMapCoords(inRow, inCol);
+ //console.log("node j: %d, i: %d", m.j, m.i);
+ for(var j=0, row; (row=this.map[j]); j++){
+ if(j == m.j){ continue; }
+ var rw = row[m.i];
+ //console.log("overlaps: r: %d, c: %d", rw.r, rw.c);
+ var n = (rw?this.getNode(inTable, rw.r, rw.c):null);
+ if(n){ nodes.push(n); }
+ }
+ //console.log(nodes);
+ return nodes;
+ },
+
+ findOverlappingNodes: function(inNode){
+ return this._findOverlappingNodes(findTable(inNode), getTrIndex(inNode.parentNode), getTdIndex(inNode));
+ }
+ });
+})();
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Container"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Container"] = true;
+dojo.provide("dojo.dnd.Container");
+
+
+
+
+
+/*
+ Container states:
+ "" - normal state
+ "Over" - mouse over a container
+ Container item states:
+ "" - normal state
+ "Over" - mouse over a container item
+*/
+
+/*=====
+dojo.declare("dojo.dnd.__ContainerArgs", [], {
+ creator: function(){
+ // summary:
+ // a creator function, which takes a data item, and returns an object like that:
+ // {node: newNode, data: usedData, type: arrayOfStrings}
+ },
+
+ // skipForm: Boolean
+ // don't start the drag operation, if clicked on form elements
+ skipForm: false,
+
+ // dropParent: Node||String
+ // node or node's id to use as the parent node for dropped items
+ // (must be underneath the 'node' parameter in the DOM)
+ dropParent: null,
+
+ // _skipStartup: Boolean
+ // skip startup(), which collects children, for deferred initialization
+ // (this is used in the markup mode)
+ _skipStartup: false
+});
+
+dojo.dnd.Item = function(){
+ // summary:
+ // Represents (one of) the source node(s) being dragged.
+ // Contains (at least) the "type" and "data" attributes.
+ // type: String[]
+ // Type(s) of this item, by default this is ["text"]
+ // data: Object
+ // Logical representation of the object being dragged.
+ // If the drag object's type is "text" then data is a String,
+ // if it's another type then data could be a different Object,
+ // perhaps a name/value hash.
+
+ this.type = type;
+ this.data = data;
+}
+=====*/
+
+dojo.declare("dojo.dnd.Container", null, {
+ // summary:
+ // a Container object, which knows when mouse hovers over it,
+ // and over which element it hovers
+
+ // object attributes (for markup)
+ skipForm: false,
+
+ /*=====
+ // current: DomNode
+ // The DOM node the mouse is currently hovered over
+ current: null,
+
+ // map: Hash<String, dojo.dnd.Item>
+ // Map from an item's id (which is also the DOMNode's id) to
+ // the dojo.dnd.Item itself.
+ map: {},
+ =====*/
+
+ constructor: function(node, params){
+ // summary:
+ // a constructor of the Container
+ // node: Node
+ // node or node's id to build the container on
+ // params: dojo.dnd.__ContainerArgs
+ // a dictionary of parameters
+ this.node = dojo.byId(node);
+ if(!params){ params = {}; }
+ this.creator = params.creator || null;
+ this.skipForm = params.skipForm;
+ this.parent = params.dropParent && dojo.byId(params.dropParent);
+
+ // class-specific variables
+ this.map = {};
+ this.current = null;
+
+ // states
+ this.containerState = "";
+ dojo.addClass(this.node, "dojoDndContainer");
+
+ // mark up children
+ if(!(params && params._skipStartup)){
+ this.startup();
+ }
+
+ // set up events
+ this.events = [
+ dojo.connect(this.node, "onmouseover", this, "onMouseOver"),
+ dojo.connect(this.node, "onmouseout", this, "onMouseOut"),
+ // cancel text selection and text dragging
+ dojo.connect(this.node, "ondragstart", this, "onSelectStart"),
+ dojo.connect(this.node, "onselectstart", this, "onSelectStart")
+ ];
+ },
+
+ // object attributes (for markup)
+ creator: function(){
+ // summary:
+ // creator function, dummy at the moment
+ },
+
+ // abstract access to the map
+ getItem: function(/*String*/ key){
+ // summary:
+ // returns a data item by its key (id)
+ return this.map[key]; // dojo.dnd.Item
+ },
+ setItem: function(/*String*/ key, /*dojo.dnd.Item*/ data){
+ // summary:
+ // associates a data item with its key (id)
+ this.map[key] = data;
+ },
+ delItem: function(/*String*/ key){
+ // summary:
+ // removes a data item from the map by its key (id)
+ delete this.map[key];
+ },
+ forInItems: function(/*Function*/ f, /*Object?*/ o){
+ // summary:
+ // iterates over a data map skipping members that
+ // are present in the empty object (IE and/or 3rd-party libraries).
+ o = o || dojo.global;
+ var m = this.map, e = dojo.dnd._empty;
+ for(var i in m){
+ if(i in e){ continue; }
+ f.call(o, m[i], i, this);
+ }
+ return o; // Object
+ },
+ clearItems: function(){
+ // summary:
+ // removes all data items from the map
+ this.map = {};
+ },
+
+ // methods
+ getAllNodes: function(){
+ // summary:
+ // returns a list (an array) of all valid child nodes
+ return dojo.query("> .dojoDndItem", this.parent); // NodeList
+ },
+ sync: function(){
+ // summary:
+ // sync up the node list with the data map
+ var map = {};
+ this.getAllNodes().forEach(function(node){
+ if(node.id){
+ var item = this.getItem(node.id);
+ if(item){
+ map[node.id] = item;
+ return;
+ }
+ }else{
+ node.id = dojo.dnd.getUniqueId();
+ }
+ var type = node.getAttribute("dndType"),
+ data = node.getAttribute("dndData");
+ map[node.id] = {
+ data: data || node.innerHTML,
+ type: type ? type.split(/\s*,\s*/) : ["text"]
+ };
+ }, this);
+ this.map = map;
+ return this; // self
+ },
+ insertNodes: function(data, before, anchor){
+ // summary:
+ // inserts an array of new nodes before/after an anchor node
+ // data: Array
+ // a list of data items, which should be processed by the creator function
+ // before: Boolean
+ // insert before the anchor, if true, and after the anchor otherwise
+ // anchor: Node
+ // the anchor node to be used as a point of insertion
+ if(!this.parent.firstChild){
+ anchor = null;
+ }else if(before){
+ if(!anchor){
+ anchor = this.parent.firstChild;
+ }
+ }else{
+ if(anchor){
+ anchor = anchor.nextSibling;
+ }
+ }
+ if(anchor){
+ for(var i = 0; i < data.length; ++i){
+ var t = this._normalizedCreator(data[i]);
+ this.setItem(t.node.id, {data: t.data, type: t.type});
+ this.parent.insertBefore(t.node, anchor);
+ }
+ }else{
+ for(var i = 0; i < data.length; ++i){
+ var t = this._normalizedCreator(data[i]);
+ this.setItem(t.node.id, {data: t.data, type: t.type});
+ this.parent.appendChild(t.node);
+ }
+ }
+ return this; // self
+ },
+ destroy: function(){
+ // summary:
+ // prepares this object to be garbage-collected
+ dojo.forEach(this.events, dojo.disconnect);
+ this.clearItems();
+ this.node = this.parent = this.current = null;
+ },
+
+ // markup methods
+ markupFactory: function(params, node){
+ params._skipStartup = true;
+ return new dojo.dnd.Container(node, params);
+ },
+ startup: function(){
+ // summary:
+ // collects valid child items and populate the map
+
+ // set up the real parent node
+ if(!this.parent){
+ // use the standard algorithm, if not assigned
+ this.parent = this.node;
+ if(this.parent.tagName.toLowerCase() == "table"){
+ var c = this.parent.getElementsByTagName("tbody");
+ if(c && c.length){ this.parent = c[0]; }
+ }
+ }
+ this.defaultCreator = dojo.dnd._defaultCreator(this.parent);
+
+ // process specially marked children
+ this.sync();
+ },
+
+ // mouse events
+ onMouseOver: function(e){
+ // summary:
+ // event processor for onmouseover
+ // e: Event
+ // mouse event
+ var n = e.relatedTarget;
+ while(n){
+ if(n == this.node){ break; }
+ try{
+ n = n.parentNode;
+ }catch(x){
+ n = null;
+ }
+ }
+ if(!n){
+ this._changeState("Container", "Over");
+ this.onOverEvent();
+ }
+ n = this._getChildByEvent(e);
+ if(this.current == n){ return; }
+ if(this.current){ this._removeItemClass(this.current, "Over"); }
+ if(n){ this._addItemClass(n, "Over"); }
+ this.current = n;
+ },
+ onMouseOut: function(e){
+ // summary:
+ // event processor for onmouseout
+ // e: Event
+ // mouse event
+ for(var n = e.relatedTarget; n;){
+ if(n == this.node){ return; }
+ try{
+ n = n.parentNode;
+ }catch(x){
+ n = null;
+ }
+ }
+ if(this.current){
+ this._removeItemClass(this.current, "Over");
+ this.current = null;
+ }
+ this._changeState("Container", "");
+ this.onOutEvent();
+ },
+ onSelectStart: function(e){
+ // summary:
+ // event processor for onselectevent and ondragevent
+ // e: Event
+ // mouse event
+ if(!this.skipForm || !dojo.dnd.isFormElement(e)){
+ dojo.stopEvent(e);
+ }
+ },
+
+ // utilities
+ onOverEvent: function(){
+ // summary:
+ // this function is called once, when mouse is over our container
+ },
+ onOutEvent: function(){
+ // summary:
+ // this function is called once, when mouse is out of our container
+ },
+ _changeState: function(type, newState){
+ // summary:
+ // changes a named state to new state value
+ // type: String
+ // a name of the state to change
+ // newState: String
+ // new state
+ var prefix = "dojoDnd" + type;
+ var state = type.toLowerCase() + "State";
+ //dojo.replaceClass(this.node, prefix + newState, prefix + this[state]);
+ dojo.replaceClass(this.node, prefix + newState, prefix + this[state]);
+ this[state] = newState;
+ },
+ _addItemClass: function(node, type){
+ // summary:
+ // adds a class with prefix "dojoDndItem"
+ // node: Node
+ // a node
+ // type: String
+ // a variable suffix for a class name
+ dojo.addClass(node, "dojoDndItem" + type);
+ },
+ _removeItemClass: function(node, type){
+ // summary:
+ // removes a class with prefix "dojoDndItem"
+ // node: Node
+ // a node
+ // type: String
+ // a variable suffix for a class name
+ dojo.removeClass(node, "dojoDndItem" + type);
+ },
+ _getChildByEvent: function(e){
+ // summary:
+ // gets a child, which is under the mouse at the moment, or null
+ // e: Event
+ // a mouse event
+ var node = e.target;
+ if(node){
+ for(var parent = node.parentNode; parent; node = parent, parent = node.parentNode){
+ if(parent == this.parent && dojo.hasClass(node, "dojoDndItem")){ return node; }
+ }
+ }
+ return null;
+ },
+ _normalizedCreator: function(/*dojo.dnd.Item*/ item, /*String*/ hint){
+ // summary:
+ // adds all necessary data to the output of the user-supplied creator function
+ var t = (this.creator || this.defaultCreator).call(this, item, hint);
+ if(!dojo.isArray(t.type)){ t.type = ["text"]; }
+ if(!t.node.id){ t.node.id = dojo.dnd.getUniqueId(); }
+ dojo.addClass(t.node, "dojoDndItem");
+ return t;
+ }
+});
+
+dojo.dnd._createNode = function(tag){
+ // summary:
+ // returns a function, which creates an element of given tag
+ // (SPAN by default) and sets its innerHTML to given text
+ // tag: String
+ // a tag name or empty for SPAN
+ if(!tag){ return dojo.dnd._createSpan; }
+ return function(text){ // Function
+ return dojo.create(tag, {innerHTML: text}); // Node
+ };
+};
+
+dojo.dnd._createTrTd = function(text){
+ // summary:
+ // creates a TR/TD structure with given text as an innerHTML of TD
+ // text: String
+ // a text for TD
+ var tr = dojo.create("tr");
+ dojo.create("td", {innerHTML: text}, tr);
+ return tr; // Node
+};
+
+dojo.dnd._createSpan = function(text){
+ // summary:
+ // creates a SPAN element with given text as its innerHTML
+ // text: String
+ // a text for SPAN
+ return dojo.create("span", {innerHTML: text}); // Node
+};
+
+// dojo.dnd._defaultCreatorNodes: Object
+// a dictionary that maps container tag names to child tag names
+dojo.dnd._defaultCreatorNodes = {ul: "li", ol: "li", div: "div", p: "div"};
+
+dojo.dnd._defaultCreator = function(node){
+ // summary:
+ // takes a parent node, and returns an appropriate creator function
+ // node: Node
+ // a container node
+ var tag = node.tagName.toLowerCase();
+ var c = tag == "tbody" || tag == "thead" ? dojo.dnd._createTrTd :
+ dojo.dnd._createNode(dojo.dnd._defaultCreatorNodes[tag]);
+ return function(item, hint){ // Function
+ var isObj = item && dojo.isObject(item), data, type, n;
+ if(isObj && item.tagName && item.nodeType && item.getAttribute){
+ // process a DOM node
+ data = item.getAttribute("dndData") || item.innerHTML;
+ type = item.getAttribute("dndType");
+ type = type ? type.split(/\s*,\s*/) : ["text"];
+ n = item; // this node is going to be moved rather than copied
+ }else{
+ // process a DnD item object or a string
+ data = (isObj && item.data) ? item.data : item;
+ type = (isObj && item.type) ? item.type : ["text"];
+ n = (hint == "avatar" ? dojo.dnd._createSpan : c)(String(data));
+ }
+ if(!n.id){
+ n.id = dojo.dnd.getUniqueId();
+ }
+ return {node: n, data: data, type: type};
+ };
+};
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Selector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Selector"] = true;
+dojo.provide("dojo.dnd.Selector");
+
+
+
+
+
+/*
+ Container item states:
+ "" - an item is not selected
+ "Selected" - an item is selected
+ "Anchor" - an item is selected, and is an anchor for a "shift" selection
+*/
+
+/*=====
+dojo.declare("dojo.dnd.__SelectorArgs", [dojo.dnd.__ContainerArgs], {
+ // singular: Boolean
+ // allows selection of only one element, if true
+ singular: false,
+
+ // autoSync: Boolean
+ // autosynchronizes the source with its list of DnD nodes,
+ autoSync: false
+});
+=====*/
+
+dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
+ // summary:
+ // a Selector object, which knows how to select its children
+
+ /*=====
+ // selection: Set<String>
+ // The set of id's that are currently selected, such that this.selection[id] == 1
+ // if the node w/that id is selected. Can iterate over selected node's id's like:
+ // | for(var id in this.selection)
+ selection: {},
+ =====*/
+
+ constructor: function(node, params){
+ // summary:
+ // constructor of the Selector
+ // node: Node||String
+ // node or node's id to build the selector on
+ // params: dojo.dnd.__SelectorArgs?
+ // a dictionary of parameters
+ if(!params){ params = {}; }
+ this.singular = params.singular;
+ this.autoSync = params.autoSync;
+ // class-specific variables
+ this.selection = {};
+ this.anchor = null;
+ this.simpleSelection = false;
+ // set up events
+ this.events.push(
+ dojo.connect(this.node, "onmousedown", this, "onMouseDown"),
+ dojo.connect(this.node, "onmouseup", this, "onMouseUp"));
+ },
+
+ // object attributes (for markup)
+ singular: false, // is singular property
+
+ // methods
+ getSelectedNodes: function(){
+ // summary:
+ // returns a list (an array) of selected nodes
+ var t = new dojo.NodeList();
+ var e = dojo.dnd._empty;
+ for(var i in this.selection){
+ if(i in e){ continue; }
+ t.push(dojo.byId(i));
+ }
+ return t; // NodeList
+ },
+ selectNone: function(){
+ // summary:
+ // unselects all items
+ return this._removeSelection()._removeAnchor(); // self
+ },
+ selectAll: function(){
+ // summary:
+ // selects all items
+ this.forInItems(function(data, id){
+ this._addItemClass(dojo.byId(id), "Selected");
+ this.selection[id] = 1;
+ }, this);
+ return this._removeAnchor(); // self
+ },
+ deleteSelectedNodes: function(){
+ // summary:
+ // deletes all selected items
+ var e = dojo.dnd._empty;
+ for(var i in this.selection){
+ if(i in e){ continue; }
+ var n = dojo.byId(i);
+ this.delItem(i);
+ dojo.destroy(n);
+ }
+ this.anchor = null;
+ this.selection = {};
+ return this; // self
+ },
+ forInSelectedItems: function(/*Function*/ f, /*Object?*/ o){
+ // summary:
+ // iterates over selected items;
+ // see `dojo.dnd.Container.forInItems()` for details
+ o = o || dojo.global;
+ var s = this.selection, e = dojo.dnd._empty;
+ for(var i in s){
+ if(i in e){ continue; }
+ f.call(o, this.getItem(i), i, this);
+ }
+ },
+ sync: function(){
+ // summary:
+ // sync up the node list with the data map
+
+ dojo.dnd.Selector.superclass.sync.call(this);
+
+ // fix the anchor
+ if(this.anchor){
+ if(!this.getItem(this.anchor.id)){
+ this.anchor = null;
+ }
+ }
+
+ // fix the selection
+ var t = [], e = dojo.dnd._empty;
+ for(var i in this.selection){
+ if(i in e){ continue; }
+ if(!this.getItem(i)){
+ t.push(i);
+ }
+ }
+ dojo.forEach(t, function(i){
+ delete this.selection[i];
+ }, this);
+
+ return this; // self
+ },
+ insertNodes: function(addSelected, data, before, anchor){
+ // summary:
+ // inserts new data items (see `dojo.dnd.Container.insertNodes()` method for details)
+ // addSelected: Boolean
+ // all new nodes will be added to selected items, if true, no selection change otherwise
+ // data: Array
+ // a list of data items, which should be processed by the creator function
+ // before: Boolean
+ // insert before the anchor, if true, and after the anchor otherwise
+ // anchor: Node
+ // the anchor node to be used as a point of insertion
+ var oldCreator = this._normalizedCreator;
+ this._normalizedCreator = function(item, hint){
+ var t = oldCreator.call(this, item, hint);
+ if(addSelected){
+ if(!this.anchor){
+ this.anchor = t.node;
+ this._removeItemClass(t.node, "Selected");
+ this._addItemClass(this.anchor, "Anchor");
+ }else if(this.anchor != t.node){
+ this._removeItemClass(t.node, "Anchor");
+ this._addItemClass(t.node, "Selected");
+ }
+ this.selection[t.node.id] = 1;
+ }else{
+ this._removeItemClass(t.node, "Selected");
+ this._removeItemClass(t.node, "Anchor");
+ }
+ return t;
+ };
+ dojo.dnd.Selector.superclass.insertNodes.call(this, data, before, anchor);
+ this._normalizedCreator = oldCreator;
+ return this; // self
+ },
+ destroy: function(){
+ // summary:
+ // prepares the object to be garbage-collected
+ dojo.dnd.Selector.superclass.destroy.call(this);
+ this.selection = this.anchor = null;
+ },
+
+ // markup methods
+ markupFactory: function(params, node){
+ params._skipStartup = true;
+ return new dojo.dnd.Selector(node, params);
+ },
+
+ // mouse events
+ onMouseDown: function(e){
+ // summary:
+ // event processor for onmousedown
+ // e: Event
+ // mouse event
+ if(this.autoSync){ this.sync(); }
+ if(!this.current){ return; }
+ if(!this.singular && !dojo.isCopyKey(e) && !e.shiftKey && (this.current.id in this.selection)){
+ this.simpleSelection = true;
+ if(e.button === dojo.mouseButtons.LEFT){
+ // accept the left button and stop the event
+ // for IE we don't stop event when multiple buttons are pressed
+ dojo.stopEvent(e);
+ }
+ return;
+ }
+ if(!this.singular && e.shiftKey){
+ if(!dojo.isCopyKey(e)){
+ this._removeSelection();
+ }
+ var c = this.getAllNodes();
+ if(c.length){
+ if(!this.anchor){
+ this.anchor = c[0];
+ this._addItemClass(this.anchor, "Anchor");
+ }
+ this.selection[this.anchor.id] = 1;
+ if(this.anchor != this.current){
+ var i = 0;
+ for(; i < c.length; ++i){
+ var node = c[i];
+ if(node == this.anchor || node == this.current){ break; }
+ }
+ for(++i; i < c.length; ++i){
+ var node = c[i];
+ if(node == this.anchor || node == this.current){ break; }
+ this._addItemClass(node, "Selected");
+ this.selection[node.id] = 1;
+ }
+ this._addItemClass(this.current, "Selected");
+ this.selection[this.current.id] = 1;
+ }
+ }
+ }else{
+ if(this.singular){
+ if(this.anchor == this.current){
+ if(dojo.isCopyKey(e)){
+ this.selectNone();
+ }
+ }else{
+ this.selectNone();
+ this.anchor = this.current;
+ this._addItemClass(this.anchor, "Anchor");
+ this.selection[this.current.id] = 1;
+ }
+ }else{
+ if(dojo.isCopyKey(e)){
+ if(this.anchor == this.current){
+ delete this.selection[this.anchor.id];
+ this._removeAnchor();
+ }else{
+ if(this.current.id in this.selection){
+ this._removeItemClass(this.current, "Selected");
+ delete this.selection[this.current.id];
+ }else{
+ if(this.anchor){
+ this._removeItemClass(this.anchor, "Anchor");
+ this._addItemClass(this.anchor, "Selected");
+ }
+ this.anchor = this.current;
+ this._addItemClass(this.current, "Anchor");
+ this.selection[this.current.id] = 1;
+ }
+ }
+ }else{
+ if(!(this.current.id in this.selection)){
+ this.selectNone();
+ this.anchor = this.current;
+ this._addItemClass(this.current, "Anchor");
+ this.selection[this.current.id] = 1;
+ }
+ }
+ }
+ }
+ dojo.stopEvent(e);
+ },
+ onMouseUp: function(e){
+ // summary:
+ // event processor for onmouseup
+ // e: Event
+ // mouse event
+ if(!this.simpleSelection){ return; }
+ this.simpleSelection = false;
+ this.selectNone();
+ if(this.current){
+ this.anchor = this.current;
+ this._addItemClass(this.anchor, "Anchor");
+ this.selection[this.current.id] = 1;
+ }
+ },
+ onMouseMove: function(e){
+ // summary
+ // event processor for onmousemove
+ // e: Event
+ // mouse event
+ this.simpleSelection = false;
+ },
+
+ // utilities
+ onOverEvent: function(){
+ // summary:
+ // this function is called once, when mouse is over our container
+ this.onmousemoveEvent = dojo.connect(this.node, "onmousemove", this, "onMouseMove");
+ },
+ onOutEvent: function(){
+ // summary:
+ // this function is called once, when mouse is out of our container
+ dojo.disconnect(this.onmousemoveEvent);
+ delete this.onmousemoveEvent;
+ },
+ _removeSelection: function(){
+ // summary:
+ // unselects all items
+ var e = dojo.dnd._empty;
+ for(var i in this.selection){
+ if(i in e){ continue; }
+ var node = dojo.byId(i);
+ if(node){ this._removeItemClass(node, "Selected"); }
+ }
+ this.selection = {};
+ return this; // self
+ },
+ _removeAnchor: function(){
+ if(this.anchor){
+ this._removeItemClass(this.anchor, "Anchor");
+ this.anchor = null;
+ }
+ return this; // self
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Avatar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Avatar"] = true;
+dojo.provide("dojo.dnd.Avatar");
+
+
+
+
+dojo.declare("dojo.dnd.Avatar", null, {
+ // summary:
+ // Object that represents transferred DnD items visually
+ // manager: Object
+ // a DnD manager object
+
+ constructor: function(manager){
+ this.manager = manager;
+ this.construct();
+ },
+
+ // methods
+ construct: function(){
+ // summary:
+ // constructor function;
+ // it is separate so it can be (dynamically) overwritten in case of need
+ this.isA11y = dojo.hasClass(dojo.body(),"dijit_a11y");
+ var a = dojo.create("table", {
+ "class": "dojoDndAvatar",
+ style: {
+ position: "absolute",
+ zIndex: "1999",
+ margin: "0px"
+ }
+ }),
+ source = this.manager.source, node,
+ b = dojo.create("tbody", null, a),
+ tr = dojo.create("tr", null, b),
+ td = dojo.create("td", null, tr),
+ icon = this.isA11y ? dojo.create("span", {
+ id : "a11yIcon",
+ innerHTML : this.manager.copy ? '+' : "<"
+ }, td) : null,
+ span = dojo.create("span", {
+ innerHTML: source.generateText ? this._generateText() : ""
+ }, td),
+ k = Math.min(5, this.manager.nodes.length), i = 0;
+ // we have to set the opacity on IE only after the node is live
+ dojo.attr(tr, {
+ "class": "dojoDndAvatarHeader",
+ style: {opacity: 0.9}
+ });
+ for(; i < k; ++i){
+ if(source.creator){
+ // create an avatar representation of the node
+ node = source._normalizedCreator(source.getItem(this.manager.nodes[i].id).data, "avatar").node;
+ }else{
+ // or just clone the node and hope it works
+ node = this.manager.nodes[i].cloneNode(true);
+ if(node.tagName.toLowerCase() == "tr"){
+ // insert extra table nodes
+ var table = dojo.create("table"),
+ tbody = dojo.create("tbody", null, table);
+ tbody.appendChild(node);
+ node = table;
+ }
+ }
+ node.id = "";
+ tr = dojo.create("tr", null, b);
+ td = dojo.create("td", null, tr);
+ td.appendChild(node);
+ dojo.attr(tr, {
+ "class": "dojoDndAvatarItem",
+ style: {opacity: (9 - i) / 10}
+ });
+ }
+ this.node = a;
+ },
+ destroy: function(){
+ // summary:
+ // destructor for the avatar; called to remove all references so it can be garbage-collected
+ dojo.destroy(this.node);
+ this.node = false;
+ },
+ update: function(){
+ // summary:
+ // updates the avatar to reflect the current DnD state
+ dojo[(this.manager.canDropFlag ? "add" : "remove") + "Class"](this.node, "dojoDndAvatarCanDrop");
+ if (this.isA11y){
+ var icon = dojo.byId("a11yIcon");
+ var text = '+'; // assume canDrop && copy
+ if (this.manager.canDropFlag && !this.manager.copy) {
+ text = '< '; // canDrop && move
+ }else if (!this.manager.canDropFlag && !this.manager.copy) {
+ text = "o"; //!canDrop && move
+ }else if(!this.manager.canDropFlag){
+ text = 'x'; // !canDrop && copy
+ }
+ icon.innerHTML=text;
+ }
+ // replace text
+ dojo.query(("tr.dojoDndAvatarHeader td span" +(this.isA11y ? " span" : "")), this.node).forEach(
+ function(node){
+ node.innerHTML = this._generateText();
+ }, this);
+ },
+ _generateText: function(){
+ // summary: generates a proper text to reflect copying or moving of items
+ return this.manager.nodes.length.toString();
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Manager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Manager"] = true;
+dojo.provide("dojo.dnd.Manager");
+
+
+
+
+
+
+dojo.declare("dojo.dnd.Manager", null, {
+ // summary:
+ // the manager of DnD operations (usually a singleton)
+ constructor: function(){
+ this.avatar = null;
+ this.source = null;
+ this.nodes = [];
+ this.copy = true;
+ this.target = null;
+ this.canDropFlag = false;
+ this.events = [];
+ },
+
+ // avatar's offset from the mouse
+ OFFSET_X: 16,
+ OFFSET_Y: 16,
+
+ // methods
+ overSource: function(source){
+ // summary:
+ // called when a source detected a mouse-over condition
+ // source: Object
+ // the reporter
+ if(this.avatar){
+ this.target = (source && source.targetState != "Disabled") ? source : null;
+ this.canDropFlag = Boolean(this.target);
+ this.avatar.update();
+ }
+ dojo.publish("/dnd/source/over", [source]);
+ },
+ outSource: function(source){
+ // summary:
+ // called when a source detected a mouse-out condition
+ // source: Object
+ // the reporter
+ if(this.avatar){
+ if(this.target == source){
+ this.target = null;
+ this.canDropFlag = false;
+ this.avatar.update();
+ dojo.publish("/dnd/source/over", [null]);
+ }
+ }else{
+ dojo.publish("/dnd/source/over", [null]);
+ }
+ },
+ startDrag: function(source, nodes, copy){
+ // summary:
+ // called to initiate the DnD operation
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+ this.source = source;
+ this.nodes = nodes;
+ this.copy = Boolean(copy); // normalizing to true boolean
+ this.avatar = this.makeAvatar();
+ dojo.body().appendChild(this.avatar.node);
+ dojo.publish("/dnd/start", [source, nodes, this.copy]);
+ this.events = [
+ dojo.connect(dojo.doc, "onmousemove", this, "onMouseMove"),
+ dojo.connect(dojo.doc, "onmouseup", this, "onMouseUp"),
+ dojo.connect(dojo.doc, "onkeydown", this, "onKeyDown"),
+ dojo.connect(dojo.doc, "onkeyup", this, "onKeyUp"),
+ // cancel text selection and text dragging
+ dojo.connect(dojo.doc, "ondragstart", dojo.stopEvent),
+ dojo.connect(dojo.body(), "onselectstart", dojo.stopEvent)
+ ];
+ var c = "dojoDnd" + (copy ? "Copy" : "Move");
+ dojo.addClass(dojo.body(), c);
+ },
+ canDrop: function(flag){
+ // summary:
+ // called to notify if the current target can accept items
+ var canDropFlag = Boolean(this.target && flag);
+ if(this.canDropFlag != canDropFlag){
+ this.canDropFlag = canDropFlag;
+ this.avatar.update();
+ }
+ },
+ stopDrag: function(){
+ // summary:
+ // stop the DnD in progress
+ dojo.removeClass(dojo.body(), ["dojoDndCopy", "dojoDndMove"]);
+ dojo.forEach(this.events, dojo.disconnect);
+ this.events = [];
+ this.avatar.destroy();
+ this.avatar = null;
+ this.source = this.target = null;
+ this.nodes = [];
+ },
+ makeAvatar: function(){
+ // summary:
+ // makes the avatar; it is separate to be overwritten dynamically, if needed
+ return new dojo.dnd.Avatar(this);
+ },
+ updateAvatar: function(){
+ // summary:
+ // updates the avatar; it is separate to be overwritten dynamically, if needed
+ this.avatar.update();
+ },
+
+ // mouse event processors
+ onMouseMove: function(e){
+ // summary:
+ // event processor for onmousemove
+ // e: Event
+ // mouse event
+ var a = this.avatar;
+ if(a){
+ dojo.dnd.autoScrollNodes(e);
+ //dojo.dnd.autoScroll(e);
+ var s = a.node.style;
+ s.left = (e.pageX + this.OFFSET_X) + "px";
+ s.top = (e.pageY + this.OFFSET_Y) + "px";
+ var copy = Boolean(this.source.copyState(dojo.isCopyKey(e)));
+ if(this.copy != copy){
+ this._setCopyStatus(copy);
+ }
+ }
+ },
+ onMouseUp: function(e){
+ // summary:
+ // event processor for onmouseup
+ // e: Event
+ // mouse event
+ if(this.avatar){
+ if(this.target && this.canDropFlag){
+ var copy = Boolean(this.source.copyState(dojo.isCopyKey(e))),
+ params = [this.source, this.nodes, copy, this.target, e];
+ dojo.publish("/dnd/drop/before", params);
+ dojo.publish("/dnd/drop", params);
+ }else{
+ dojo.publish("/dnd/cancel");
+ }
+ this.stopDrag();
+ }
+ },
+
+ // keyboard event processors
+ onKeyDown: function(e){
+ // summary:
+ // event processor for onkeydown:
+ // watching for CTRL for copy/move status, watching for ESCAPE to cancel the drag
+ // e: Event
+ // keyboard event
+ if(this.avatar){
+ switch(e.keyCode){
+ case dojo.keys.CTRL:
+ var copy = Boolean(this.source.copyState(true));
+ if(this.copy != copy){
+ this._setCopyStatus(copy);
+ }
+ break;
+ case dojo.keys.ESCAPE:
+ dojo.publish("/dnd/cancel");
+ this.stopDrag();
+ break;
+ }
+ }
+ },
+ onKeyUp: function(e){
+ // summary:
+ // event processor for onkeyup, watching for CTRL for copy/move status
+ // e: Event
+ // keyboard event
+ if(this.avatar && e.keyCode == dojo.keys.CTRL){
+ var copy = Boolean(this.source.copyState(false));
+ if(this.copy != copy){
+ this._setCopyStatus(copy);
+ }
+ }
+ },
+
+ // utilities
+ _setCopyStatus: function(copy){
+ // summary:
+ // changes the copy status
+ // copy: Boolean
+ // the copy status
+ this.copy = copy;
+ this.source._markDndStatus(this.copy);
+ this.updateAvatar();
+ dojo.replaceClass(dojo.body(),
+ "dojoDnd" + (this.copy ? "Copy" : "Move"),
+ "dojoDnd" + (this.copy ? "Move" : "Copy"));
+ }
+});
+
+// dojo.dnd._manager:
+// The manager singleton variable. Can be overwritten if needed.
+dojo.dnd._manager = null;
+
+dojo.dnd.manager = function(){
+ // summary:
+ // Returns the current DnD manager. Creates one if it is not created yet.
+ if(!dojo.dnd._manager){
+ dojo.dnd._manager = new dojo.dnd.Manager();
+ }
+ return dojo.dnd._manager; // Object
+};
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Source"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Source"] = true;
+dojo.provide("dojo.dnd.Source");
+
+
+
+
+
+/*
+ Container property:
+ "Horizontal"- if this is the horizontal container
+ Source states:
+ "" - normal state
+ "Moved" - this source is being moved
+ "Copied" - this source is being copied
+ Target states:
+ "" - normal state
+ "Disabled" - the target cannot accept an avatar
+ Target anchor state:
+ "" - item is not selected
+ "Before" - insert point is before the anchor
+ "After" - insert point is after the anchor
+*/
+
+/*=====
+dojo.dnd.__SourceArgs = function(){
+ // summary:
+ // a dict of parameters for DnD Source configuration. Note that any
+ // property on Source elements may be configured, but this is the
+ // short-list
+ // isSource: Boolean?
+ // can be used as a DnD source. Defaults to true.
+ // accept: Array?
+ // list of accepted types (text strings) for a target; defaults to
+ // ["text"]
+ // autoSync: Boolean
+ // if true refreshes the node list on every operation; false by default
+ // copyOnly: Boolean?
+ // copy items, if true, use a state of Ctrl key otherwise,
+ // see selfCopy and selfAccept for more details
+ // delay: Number
+ // the move delay in pixels before detecting a drag; 0 by default
+ // horizontal: Boolean?
+ // a horizontal container, if true, vertical otherwise or when omitted
+ // selfCopy: Boolean?
+ // copy items by default when dropping on itself,
+ // false by default, works only if copyOnly is true
+ // selfAccept: Boolean?
+ // accept its own items when copyOnly is true,
+ // true by default, works only if copyOnly is true
+ // withHandles: Boolean?
+ // allows dragging only by handles, false by default
+ // generateText: Boolean?
+ // generate text node for drag and drop, true by default
+ this.isSource = isSource;
+ this.accept = accept;
+ this.autoSync = autoSync;
+ this.copyOnly = copyOnly;
+ this.delay = delay;
+ this.horizontal = horizontal;
+ this.selfCopy = selfCopy;
+ this.selfAccept = selfAccept;
+ this.withHandles = withHandles;
+ this.generateText = true;
+}
+=====*/
+
+dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
+ // summary:
+ // a Source object, which can be used as a DnD source, or a DnD target
+
+ // object attributes (for markup)
+ isSource: true,
+ horizontal: false,
+ copyOnly: false,
+ selfCopy: false,
+ selfAccept: true,
+ skipForm: false,
+ withHandles: false,
+ autoSync: false,
+ delay: 0, // pixels
+ accept: ["text"],
+ generateText: true,
+
+ constructor: function(/*DOMNode|String*/node, /*dojo.dnd.__SourceArgs?*/params){
+ // summary:
+ // a constructor of the Source
+ // node:
+ // node or node's id to build the source on
+ // params:
+ // any property of this class may be configured via the params
+ // object which is mixed-in to the `dojo.dnd.Source` instance
+ dojo.mixin(this, dojo.mixin({}, params));
+ var type = this.accept;
+ if(type.length){
+ this.accept = {};
+ for(var i = 0; i < type.length; ++i){
+ this.accept[type[i]] = 1;
+ }
+ }
+ // class-specific variables
+ this.isDragging = false;
+ this.mouseDown = false;
+ this.targetAnchor = null;
+ this.targetBox = null;
+ this.before = true;
+ this._lastX = 0;
+ this._lastY = 0;
+ // states
+ this.sourceState = "";
+ if(this.isSource){
+ dojo.addClass(this.node, "dojoDndSource");
+ }
+ this.targetState = "";
+ if(this.accept){
+ dojo.addClass(this.node, "dojoDndTarget");
+ }
+ if(this.horizontal){
+ dojo.addClass(this.node, "dojoDndHorizontal");
+ }
+ // set up events
+ this.topics = [
+ dojo.subscribe("/dnd/source/over", this, "onDndSourceOver"),
+ dojo.subscribe("/dnd/start", this, "onDndStart"),
+ dojo.subscribe("/dnd/drop", this, "onDndDrop"),
+ dojo.subscribe("/dnd/cancel", this, "onDndCancel")
+ ];
+ },
+
+ // methods
+ checkAcceptance: function(source, nodes){
+ // summary:
+ // checks if the target can accept nodes from this source
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ if(this == source){
+ return !this.copyOnly || this.selfAccept;
+ }
+ for(var i = 0; i < nodes.length; ++i){
+ var type = source.getItem(nodes[i].id).type;
+ // type instanceof Array
+ var flag = false;
+ for(var j = 0; j < type.length; ++j){
+ if(type[j] in this.accept){
+ flag = true;
+ break;
+ }
+ }
+ if(!flag){
+ return false; // Boolean
+ }
+ }
+ return true; // Boolean
+ },
+ copyState: function(keyPressed, self){
+ // summary:
+ // Returns true if we need to copy items, false to move.
+ // It is separated to be overwritten dynamically, if needed.
+ // keyPressed: Boolean
+ // the "copy" key was pressed
+ // self: Boolean?
+ // optional flag that means that we are about to drop on itself
+
+ if(keyPressed){ return true; }
+ if(arguments.length < 2){
+ self = this == dojo.dnd.manager().target;
+ }
+ if(self){
+ if(this.copyOnly){
+ return this.selfCopy;
+ }
+ }else{
+ return this.copyOnly;
+ }
+ return false; // Boolean
+ },
+ destroy: function(){
+ // summary:
+ // prepares the object to be garbage-collected
+ dojo.dnd.Source.superclass.destroy.call(this);
+ dojo.forEach(this.topics, dojo.unsubscribe);
+ this.targetAnchor = null;
+ },
+
+ // markup methods
+ markupFactory: function(params, node){
+ params._skipStartup = true;
+ return new dojo.dnd.Source(node, params);
+ },
+
+ // mouse event processors
+ onMouseMove: function(e){
+ // summary:
+ // event processor for onmousemove
+ // e: Event
+ // mouse event
+ if(this.isDragging && this.targetState == "Disabled"){ return; }
+ dojo.dnd.Source.superclass.onMouseMove.call(this, e);
+ var m = dojo.dnd.manager();
+ if(!this.isDragging){
+ if(this.mouseDown && this.isSource &&
+ (Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.pageY - this._lastY) > this.delay)){
+ var nodes = this.getSelectedNodes();
+ if(nodes.length){
+ m.startDrag(this, nodes, this.copyState(dojo.isCopyKey(e), true));
+ }
+ }
+ }
+ if(this.isDragging){
+ // calculate before/after
+ var before = false;
+ if(this.current){
+ if(!this.targetBox || this.targetAnchor != this.current){
+ this.targetBox = dojo.position(this.current, true);
+ }
+ if(this.horizontal){
+ before = (e.pageX - this.targetBox.x) < (this.targetBox.w / 2);
+ }else{
+ before = (e.pageY - this.targetBox.y) < (this.targetBox.h / 2);
+ }
+ }
+ if(this.current != this.targetAnchor || before != this.before){
+ this._markTargetAnchor(before);
+ m.canDrop(!this.current || m.source != this || !(this.current.id in this.selection));
+ }
+ }
+ },
+ onMouseDown: function(e){
+ // summary:
+ // event processor for onmousedown
+ // e: Event
+ // mouse event
+ if(!this.mouseDown && this._legalMouseDown(e) && (!this.skipForm || !dojo.dnd.isFormElement(e))){
+ this.mouseDown = true;
+ this._lastX = e.pageX;
+ this._lastY = e.pageY;
+ dojo.dnd.Source.superclass.onMouseDown.call(this, e);
+ }
+ },
+ onMouseUp: function(e){
+ // summary:
+ // event processor for onmouseup
+ // e: Event
+ // mouse event
+ if(this.mouseDown){
+ this.mouseDown = false;
+ dojo.dnd.Source.superclass.onMouseUp.call(this, e);
+ }
+ },
+
+ // topic event processors
+ onDndSourceOver: function(source){
+ // summary:
+ // topic event processor for /dnd/source/over, called when detected a current source
+ // source: Object
+ // the source which has the mouse over it
+ if(this != source){
+ this.mouseDown = false;
+ if(this.targetAnchor){
+ this._unmarkTargetAnchor();
+ }
+ }else if(this.isDragging){
+ var m = dojo.dnd.manager();
+ m.canDrop(this.targetState != "Disabled" && (!this.current || m.source != this || !(this.current.id in this.selection)));
+ }
+ },
+ onDndStart: function(source, nodes, copy){
+ // summary:
+ // topic event processor for /dnd/start, called to initiate the DnD operation
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+ if(this.autoSync){ this.sync(); }
+ if(this.isSource){
+ this._changeState("Source", this == source ? (copy ? "Copied" : "Moved") : "");
+ }
+ var accepted = this.accept && this.checkAcceptance(source, nodes);
+ this._changeState("Target", accepted ? "" : "Disabled");
+ if(this == source){
+ dojo.dnd.manager().overSource(this);
+ }
+ this.isDragging = true;
+ },
+ onDndDrop: function(source, nodes, copy, target){
+ // summary:
+ // topic event processor for /dnd/drop, called to finish the DnD operation
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+ // target: Object
+ // the target which accepts items
+ if(this == target){
+ // this one is for us => move nodes!
+ this.onDrop(source, nodes, copy);
+ }
+ this.onDndCancel();
+ },
+ onDndCancel: function(){
+ // summary:
+ // topic event processor for /dnd/cancel, called to cancel the DnD operation
+ if(this.targetAnchor){
+ this._unmarkTargetAnchor();
+ this.targetAnchor = null;
+ }
+ this.before = true;
+ this.isDragging = false;
+ this.mouseDown = false;
+ this._changeState("Source", "");
+ this._changeState("Target", "");
+ },
+
+ // local events
+ onDrop: function(source, nodes, copy){
+ // summary:
+ // called only on the current target, when drop is performed
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+
+ if(this != source){
+ this.onDropExternal(source, nodes, copy);
+ }else{
+ this.onDropInternal(nodes, copy);
+ }
+ },
+ onDropExternal: function(source, nodes, copy){
+ // summary:
+ // called only on the current target, when drop is performed
+ // from an external source
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+
+ var oldCreator = this._normalizedCreator;
+ // transferring nodes from the source to the target
+ if(this.creator){
+ // use defined creator
+ this._normalizedCreator = function(node, hint){
+ return oldCreator.call(this, source.getItem(node.id).data, hint);
+ };
+ }else{
+ // we have no creator defined => move/clone nodes
+ if(copy){
+ // clone nodes
+ this._normalizedCreator = function(node, hint){
+ var t = source.getItem(node.id);
+ var n = node.cloneNode(true);
+ n.id = dojo.dnd.getUniqueId();
+ return {node: n, data: t.data, type: t.type};
+ };
+ }else{
+ // move nodes
+ this._normalizedCreator = function(node, hint){
+ var t = source.getItem(node.id);
+ source.delItem(node.id);
+ return {node: node, data: t.data, type: t.type};
+ };
+ }
+ }
+ this.selectNone();
+ if(!copy && !this.creator){
+ source.selectNone();
+ }
+ this.insertNodes(true, nodes, this.before, this.current);
+ if(!copy && this.creator){
+ source.deleteSelectedNodes();
+ }
+ this._normalizedCreator = oldCreator;
+ },
+ onDropInternal: function(nodes, copy){
+ // summary:
+ // called only on the current target, when drop is performed
+ // from the same target/source
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+
+ var oldCreator = this._normalizedCreator;
+ // transferring nodes within the single source
+ if(this.current && this.current.id in this.selection){
+ // do nothing
+ return;
+ }
+ if(copy){
+ if(this.creator){
+ // create new copies of data items
+ this._normalizedCreator = function(node, hint){
+ return oldCreator.call(this, this.getItem(node.id).data, hint);
+ };
+ }else{
+ // clone nodes
+ this._normalizedCreator = function(node, hint){
+ var t = this.getItem(node.id);
+ var n = node.cloneNode(true);
+ n.id = dojo.dnd.getUniqueId();
+ return {node: n, data: t.data, type: t.type};
+ };
+ }
+ }else{
+ // move nodes
+ if(!this.current){
+ // do nothing
+ return;
+ }
+ this._normalizedCreator = function(node, hint){
+ var t = this.getItem(node.id);
+ return {node: node, data: t.data, type: t.type};
+ };
+ }
+ this._removeSelection();
+ this.insertNodes(true, nodes, this.before, this.current);
+ this._normalizedCreator = oldCreator;
+ },
+ onDraggingOver: function(){
+ // summary:
+ // called during the active DnD operation, when items
+ // are dragged over this target, and it is not disabled
+ },
+ onDraggingOut: function(){
+ // summary:
+ // called during the active DnD operation, when items
+ // are dragged away from this target, and it is not disabled
+ },
+
+ // utilities
+ onOverEvent: function(){
+ // summary:
+ // this function is called once, when mouse is over our container
+ dojo.dnd.Source.superclass.onOverEvent.call(this);
+ dojo.dnd.manager().overSource(this);
+ if(this.isDragging && this.targetState != "Disabled"){
+ this.onDraggingOver();
+ }
+ },
+ onOutEvent: function(){
+ // summary:
+ // this function is called once, when mouse is out of our container
+ dojo.dnd.Source.superclass.onOutEvent.call(this);
+ dojo.dnd.manager().outSource(this);
+ if(this.isDragging && this.targetState != "Disabled"){
+ this.onDraggingOut();
+ }
+ },
+ _markTargetAnchor: function(before){
+ // summary:
+ // assigns a class to the current target anchor based on "before" status
+ // before: Boolean
+ // insert before, if true, after otherwise
+ if(this.current == this.targetAnchor && this.before == before){ return; }
+ if(this.targetAnchor){
+ this._removeItemClass(this.targetAnchor, this.before ? "Before" : "After");
+ }
+ this.targetAnchor = this.current;
+ this.targetBox = null;
+ this.before = before;
+ if(this.targetAnchor){
+ this._addItemClass(this.targetAnchor, this.before ? "Before" : "After");
+ }
+ },
+ _unmarkTargetAnchor: function(){
+ // summary:
+ // removes a class of the current target anchor based on "before" status
+ if(!this.targetAnchor){ return; }
+ this._removeItemClass(this.targetAnchor, this.before ? "Before" : "After");
+ this.targetAnchor = null;
+ this.targetBox = null;
+ this.before = true;
+ },
+ _markDndStatus: function(copy){
+ // summary:
+ // changes source's state based on "copy" status
+ this._changeState("Source", copy ? "Copied" : "Moved");
+ },
+ _legalMouseDown: function(e){
+ // summary:
+ // checks if user clicked on "approved" items
+ // e: Event
+ // mouse event
+
+ // accept only the left mouse button
+ if(!dojo.mouseButtons.isLeft(e)){ return false; }
+
+ if(!this.withHandles){ return true; }
+
+ // check for handles
+ for(var node = e.target; node && node !== this.node; node = node.parentNode){
+ if(dojo.hasClass(node, "dojoDndHandle")){ return true; }
+ if(dojo.hasClass(node, "dojoDndItem") || dojo.hasClass(node, "dojoDndIgnore")){ break; }
+ }
+ return false; // Boolean
+ }
+});
+
+dojo.declare("dojo.dnd.Target", dojo.dnd.Source, {
+ // summary: a Target object, which can be used as a DnD target
+
+ constructor: function(node, params){
+ // summary:
+ // a constructor of the Target --- see the `dojo.dnd.Source.constructor` for details
+ this.isSource = false;
+ dojo.removeClass(this.node, "dojoDndSource");
+ },
+
+ // markup methods
+ markupFactory: function(params, node){
+ params._skipStartup = true;
+ return new dojo.dnd.Target(node, params);
+ }
+});
+
+dojo.declare("dojo.dnd.AutoSource", dojo.dnd.Source, {
+ // summary:
+ // a source that syncs its DnD nodes by default
+
+ constructor: function(node, params){
+ // summary:
+ // constructor of the AutoSource --- see the Source constructor for details
+ this.autoSync = true;
+ },
+
+ // markup methods
+ markupFactory: function(params, node){
+ params._skipStartup = true;
+ return new dojo.dnd.AutoSource(node, params);
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._View"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._View"] = true;
+dojo.provide("dojox.grid._View");
+
+
+
+
+
+
+
+
+
+
+(function(){
+ // a private function
+ var getStyleText = function(inNode, inStyleText){
+ return inNode.style.cssText == undefined ? inNode.getAttribute("style") : inNode.style.cssText;
+ };
+
+ // some public functions
+ dojo.declare('dojox.grid._View', [dijit._Widget, dijit._Templated], {
+ // summary:
+ // A collection of grid columns. A grid is comprised of a set of views that stack horizontally.
+ // Grid creates views automatically based on grid's layout structure.
+ // Users should typically not need to access individual views directly.
+ //
+ // defaultWidth: String
+ // Default width of the view
+ defaultWidth: "18em",
+
+ // viewWidth: String
+ // Width for the view, in valid css unit
+ viewWidth: "",
+
+ templateString:"<div class=\"dojoxGridView\" role=\"presentation\">\r\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" role=\"presentation\">\r\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" role=\"presentation\">\r\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" role=\"row\"></div>\r\n\t\t</div>\r\n\t</div>\r\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" role=\"presentation\" />\r\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" role=\"presentation\" />\r\n\t<div class=\"dojoxGridScrollbox\" dojoAttachPoint=\"scrollboxNode\" role=\"presentation\">\r\n\t\t<div class=\"dojoxGridContent\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\" role=\"presentation\"></div>\r\n\t</div>\r\n</div>\r\n",
+
+ themeable: false,
+ classTag: 'dojoxGrid',
+ marginBottom: 0,
+ rowPad: 2,
+
+ // _togglingColumn: int
+ // Width of the column being toggled (-1 for none)
+ _togglingColumn: -1,
+
+ // _headerBuilderClass: Object
+ // The class to use for our header builder
+ _headerBuilderClass: dojox.grid._HeaderBuilder,
+
+ // _contentBuilderClass: Object
+ // The class to use for our content builder
+ _contentBuilderClass: dojox.grid._ContentBuilder,
+
+ postMixInProperties: function(){
+ this.rowNodes = {};
+ },
+
+ postCreate: function(){
+ this.connect(this.scrollboxNode,"onscroll","doscroll");
+ dojox.grid.util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]);
+ dojox.grid.util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]);
+ this.content = new this._contentBuilderClass(this);
+ this.header = new this._headerBuilderClass(this);
+ //BiDi: in RTL case, style width='9000em' causes scrolling problem in head node
+ if(!dojo._isBodyLtr()){
+ this.headerNodeContainer.style.width = "";
+ }
+ },
+
+ destroy: function(){
+ dojo.destroy(this.headerNode);
+ delete this.headerNode;
+ for(var i in this.rowNodes){
+ dojo.destroy(this.rowNodes[i]);
+ }
+ this.rowNodes = {};
+ if(this.source){
+ this.source.destroy();
+ }
+ this.inherited(arguments);
+ },
+
+ // focus
+ focus: function(){
+ if(dojo.isIE || dojo.isWebKit || dojo.isOpera){
+ this.hiddenFocusNode.focus();
+ }else{
+ this.scrollboxNode.focus();
+ }
+ },
+
+ setStructure: function(inStructure){
+ var vs = (this.structure = inStructure);
+ // FIXME: similar logic is duplicated in layout
+ if(vs.width && !isNaN(vs.width)){
+ this.viewWidth = vs.width + 'em';
+ }else{
+ this.viewWidth = vs.width || (vs.noscroll ? 'auto' : this.viewWidth); //|| this.defaultWidth;
+ }
+ this._onBeforeRow = vs.onBeforeRow||function(){};
+ this._onAfterRow = vs.onAfterRow||function(){};
+ this.noscroll = vs.noscroll;
+ if(this.noscroll){
+ this.scrollboxNode.style.overflow = "hidden";
+ }
+ this.simpleStructure = Boolean(vs.cells.length == 1);
+ // bookkeeping
+ this.testFlexCells();
+ // accomodate new structure
+ this.updateStructure();
+ },
+
+ _cleanupRowWidgets: function(inRowNode){
+ // Summary:
+ // Cleans up the widgets for the given row node so that
+ // we can reattach them if needed
+ if(inRowNode){
+ dojo.forEach(dojo.query("[widgetId]", inRowNode).map(dijit.byNode), function(w){
+ if(w._destroyOnRemove){
+ w.destroy();
+ delete w;
+ }else if(w.domNode && w.domNode.parentNode){
+ w.domNode.parentNode.removeChild(w.domNode);
+ }
+ });
+ }
+ },
+
+ onBeforeRow: function(inRowIndex, cells){
+ this._onBeforeRow(inRowIndex, cells);
+ if(inRowIndex >= 0){
+ this._cleanupRowWidgets(this.getRowNode(inRowIndex));
+ }
+ },
+
+ onAfterRow: function(inRowIndex, cells, inRowNode){
+ this._onAfterRow(inRowIndex, cells, inRowNode);
+ var g = this.grid;
+ dojo.forEach(dojo.query(".dojoxGridStubNode", inRowNode), function(n){
+ if(n && n.parentNode){
+ var lw = n.getAttribute("linkWidget");
+ var cellIdx = window.parseInt(dojo.attr(n, "cellIdx"), 10);
+ var cellDef = g.getCell(cellIdx);
+ var w = dijit.byId(lw);
+ if(w){
+ n.parentNode.replaceChild(w.domNode, n);
+ if(!w._started){
+ w.startup();
+ }
+ }else{
+ n.innerHTML = "";
+ }
+ }
+ }, this);
+ },
+
+ testFlexCells: function(){
+ // FIXME: cheater, this function does double duty as initializer and tester
+ this.flexCells = false;
+ for(var j=0, row; (row=this.structure.cells[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ cell.view = this;
+ this.flexCells = this.flexCells || cell.isFlex();
+ }
+ }
+ return this.flexCells;
+ },
+
+ updateStructure: function(){
+ // header builder needs to update table map
+ this.header.update();
+ // content builder needs to update markup cache
+ this.content.update();
+ },
+
+ getScrollbarWidth: function(){
+ var hasScrollSpace = this.hasVScrollbar();
+ var overflow = dojo.style(this.scrollboxNode, "overflow");
+ if(this.noscroll || !overflow || overflow == "hidden"){
+ hasScrollSpace = false;
+ }else if(overflow == "scroll"){
+ hasScrollSpace = true;
+ }
+ return (hasScrollSpace ? dojox.html.metrics.getScrollbar().w : 0); // Integer
+ },
+
+ getColumnsWidth: function(){
+ var h = this.headerContentNode;
+ return h && h.firstChild ? h.firstChild.offsetWidth : 0; // Integer
+ },
+
+ setColumnsWidth: function(width){
+ this.headerContentNode.firstChild.style.width = width + 'px';
+ if(this.viewWidth){
+ this.viewWidth = width + 'px';
+ }
+ },
+
+ getWidth: function(){
+ return this.viewWidth || (this.getColumnsWidth()+this.getScrollbarWidth()) +'px'; // String
+ },
+
+ getContentWidth: function(){
+ return Math.max(0, dojo._getContentBox(this.domNode).w - this.getScrollbarWidth()) + 'px'; // String
+ },
+
+ render: function(){
+ this.scrollboxNode.style.height = '';
+ this.renderHeader();
+ if(this._togglingColumn >= 0){
+ this.setColumnsWidth(this.getColumnsWidth() - this._togglingColumn);
+ this._togglingColumn = -1;
+ }
+ var cells = this.grid.layout.cells;
+ var getSibling = dojo.hitch(this, function(node, before){
+ !dojo._isBodyLtr() && (before = !before);
+ var inc = before?-1:1;
+ var idx = this.header.getCellNodeIndex(node) + inc;
+ var cell = cells[idx];
+ while(cell && cell.getHeaderNode() && cell.getHeaderNode().style.display == "none"){
+ idx += inc;
+ cell = cells[idx];
+ }
+ if(cell){
+ return cell.getHeaderNode();
+ }
+ return null;
+ });
+ if(this.grid.columnReordering && this.simpleStructure){
+ if(this.source){
+ this.source.destroy();
+ }
+
+ // Create the top and bottom markers
+ var bottomMarkerId = "dojoxGrid_bottomMarker";
+ var topMarkerId = "dojoxGrid_topMarker";
+ if(this.bottomMarker){
+ dojo.destroy(this.bottomMarker);
+ }
+ this.bottomMarker = dojo.byId(bottomMarkerId);
+ if(this.topMarker){
+ dojo.destroy(this.topMarker);
+ }
+ this.topMarker = dojo.byId(topMarkerId);
+ if (!this.bottomMarker) {
+ this.bottomMarker = dojo.create("div", {
+ "id": bottomMarkerId,
+ "class": "dojoxGridColPlaceBottom"
+ }, dojo.body());
+ this._hide(this.bottomMarker);
+
+
+ this.topMarker = dojo.create("div", {
+ "id": topMarkerId,
+ "class": "dojoxGridColPlaceTop"
+ }, dojo.body());
+ this._hide(this.topMarker);
+ }
+ this.arrowDim = dojo.contentBox(this.bottomMarker);
+
+ var headerHeight = dojo.contentBox(this.headerContentNode.firstChild.rows[0]).h;
+
+ this.source = new dojo.dnd.Source(this.headerContentNode.firstChild.rows[0], {
+ horizontal: true,
+ accept: [ "gridColumn_" + this.grid.id ],
+ viewIndex: this.index,
+ generateText: false,
+ onMouseDown: dojo.hitch(this, function(e){
+ this.header.decorateEvent(e);
+ if((this.header.overRightResizeArea(e) || this.header.overLeftResizeArea(e)) &&
+ this.header.canResize(e) && !this.header.moveable){
+ this.header.beginColumnResize(e);
+ }else{
+ if(this.grid.headerMenu){
+ this.grid.headerMenu.onCancel(true);
+ }
+ // IE reports a left click as 1, where everything else reports 0
+ if(e.button === (dojo.isIE ? 1 : 0)){
+ dojo.dnd.Source.prototype.onMouseDown.call(this.source, e);
+ }
+ }
+ }),
+ onMouseOver: dojo.hitch(this, function(e){
+ var src = this.source;
+ if(src._getChildByEvent(e)){
+ dojo.dnd.Source.prototype.onMouseOver.apply(src, arguments);
+ }
+ }),
+ _markTargetAnchor: dojo.hitch(this, function(before){
+ var src = this.source;
+ if(src.current == src.targetAnchor && src.before == before){ return; }
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ dojo.dnd.Source.prototype._markTargetAnchor.call(src, before);
+
+ var target = before ? src.targetAnchor : getSibling(src.targetAnchor, src.before);
+ var endAdd = 0;
+
+ if (!target) {
+ target = src.targetAnchor;
+ endAdd = dojo.contentBox(target).w + this.arrowDim.w/2 + 2;
+ }
+
+ // NOTE: this is for backwards compatibility with Dojo 1.3
+ var pos = (dojo.position||dojo._abs)(target, true);
+ var left = Math.floor(pos.x - this.arrowDim.w/2 + endAdd);
+
+ dojo.style(this.bottomMarker, "visibility", "visible");
+ dojo.style(this.topMarker, "visibility", "visible");
+ dojo.style(this.bottomMarker, {
+ "left": left + "px",
+ "top" : (headerHeight + pos.y) + "px"
+ });
+
+ dojo.style(this.topMarker, {
+ "left": left + "px",
+ "top" : (pos.y - this.arrowDim.h) + "px"
+ });
+
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._addItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ }),
+ _unmarkTargetAnchor: dojo.hitch(this, function(){
+ var src = this.source;
+ if(!src.targetAnchor){ return; }
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+ dojo.dnd.Source.prototype._unmarkTargetAnchor.call(src);
+ }),
+ destroy: dojo.hitch(this, function(){
+ dojo.disconnect(this._source_conn);
+ dojo.unsubscribe(this._source_sub);
+ dojo.dnd.Source.prototype.destroy.call(this.source);
+ if(this.bottomMarker){
+ dojo.destroy(this.bottomMarker);
+ delete this.bottomMarker;
+ }
+ if(this.topMarker){
+ dojo.destroy(this.topMarker);
+ delete this.topMarker;
+ }
+ }),
+ onDndCancel: dojo.hitch(this, function(){
+ dojo.dnd.Source.prototype.onDndCancel.call(this.source);
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+ })
+ });
+
+ this._source_conn = dojo.connect(this.source, "onDndDrop", this, "_onDndDrop");
+ this._source_sub = dojo.subscribe("/dnd/drop/before", this, "_onDndDropBefore");
+ this.source.startup();
+ }
+ },
+
+ _hide: function(node){
+ dojo.style(node, {
+ left: "-10000px",
+ top: "-10000px",
+ "visibility": "hidden"
+ });
+ },
+
+ _onDndDropBefore: function(source, nodes, copy){
+ if(dojo.dnd.manager().target !== this.source){
+ return;
+ }
+ this.source._targetNode = this.source.targetAnchor;
+ this.source._beforeTarget = this.source.before;
+ var views = this.grid.views.views;
+ var srcView = views[source.viewIndex];
+ var tgtView = views[this.index];
+ if(tgtView != srcView){
+ srcView.convertColPctToFixed();
+ tgtView.convertColPctToFixed();
+ }
+ },
+
+ _onDndDrop: function(source, nodes, copy){
+ if(dojo.dnd.manager().target !== this.source){
+ if(dojo.dnd.manager().source === this.source){
+ this._removingColumn = true;
+ }
+ return;
+ }
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+
+ var getIdx = function(n){
+ return n ? dojo.attr(n, "idx") : null;
+ };
+ var w = dojo.marginBox(nodes[0]).w;
+ if(source.viewIndex !== this.index){
+ var views = this.grid.views.views;
+ var srcView = views[source.viewIndex];
+ var tgtView = views[this.index];
+ if(srcView.viewWidth && srcView.viewWidth != "auto"){
+ srcView.setColumnsWidth(srcView.getColumnsWidth() - w);
+ }
+ if(tgtView.viewWidth && tgtView.viewWidth != "auto"){
+ tgtView.setColumnsWidth(tgtView.getColumnsWidth());
+ }
+ }
+ var stn = this.source._targetNode;
+ var stb = this.source._beforeTarget;
+ !dojo._isBodyLtr() && (stb = !stb);
+ var layout = this.grid.layout;
+ var idx = this.index;
+ delete this.source._targetNode;
+ delete this.source._beforeTarget;
+
+ layout.moveColumn(
+ source.viewIndex,
+ idx,
+ getIdx(nodes[0]),
+ getIdx(stn),
+ stb);
+ },
+
+ renderHeader: function(){
+ this.headerContentNode.innerHTML = this.header.generateHtml(this._getHeaderContent);
+ if(this.flexCells){
+ this.contentWidth = this.getContentWidth();
+ this.headerContentNode.firstChild.style.width = this.contentWidth;
+ }
+ dojox.grid.util.fire(this, "onAfterRow", [-1, this.structure.cells, this.headerContentNode]);
+ },
+
+ // note: not called in 'view' context
+ _getHeaderContent: function(inCell){
+ var n = inCell.name || inCell.grid.getCellName(inCell);
+ var ret = [ '<div class="dojoxGridSortNode' ];
+
+ if(inCell.index != inCell.grid.getSortIndex()){
+ ret.push('">');
+ }else{
+ ret = ret.concat([ ' ',
+ inCell.grid.sortInfo > 0 ? 'dojoxGridSortUp' : 'dojoxGridSortDown',
+ '"><div class="dojoxGridArrowButtonChar">',
+ inCell.grid.sortInfo > 0 ? '&#9650;' : '&#9660;',
+ '</div><div class="dojoxGridArrowButtonNode" role="presentation"></div>',
+ '<div class="dojoxGridColCaption">']);
+ }
+ ret = ret.concat([n, '</div></div>']);
+ return ret.join('');
+ },
+
+ resize: function(){
+ this.adaptHeight();
+ this.adaptWidth();
+ },
+
+ hasHScrollbar: function(reset){
+ var hadScroll = this._hasHScroll||false;
+ if(this._hasHScroll == undefined || reset){
+ if(this.noscroll){
+ this._hasHScroll = false;
+ }else{
+ var style = dojo.style(this.scrollboxNode, "overflow");
+ if(style == "hidden"){
+ this._hasHScroll = false;
+ }else if(style == "scroll"){
+ this._hasHScroll = true;
+ }else{
+ this._hasHScroll = (this.scrollboxNode.offsetWidth - this.getScrollbarWidth() < this.contentNode.offsetWidth );
+ }
+ }
+ }
+ if(hadScroll !== this._hasHScroll){
+ this.grid.update();
+ }
+ return this._hasHScroll; // Boolean
+ },
+
+ hasVScrollbar: function(reset){
+ var hadScroll = this._hasVScroll||false;
+ if(this._hasVScroll == undefined || reset){
+ if(this.noscroll){
+ this._hasVScroll = false;
+ }else{
+ var style = dojo.style(this.scrollboxNode, "overflow");
+ if(style == "hidden"){
+ this._hasVScroll = false;
+ }else if(style == "scroll"){
+ this._hasVScroll = true;
+ }else{
+ this._hasVScroll = (this.scrollboxNode.scrollHeight > this.scrollboxNode.clientHeight);
+ }
+ }
+ }
+ if(hadScroll !== this._hasVScroll){
+ this.grid.update();
+ }
+ return this._hasVScroll; // Boolean
+ },
+
+ convertColPctToFixed: function(){
+ // Fix any percentage widths to be pixel values
+ var hasPct = false;
+ this.grid.initialWidth = "";
+ var cellNodes = dojo.query("th", this.headerContentNode);
+ var fixedWidths = dojo.map(cellNodes, function(c, vIdx){
+ var w = c.style.width;
+ dojo.attr(c, "vIdx", vIdx);
+ if(w && w.slice(-1) == "%"){
+ hasPct = true;
+ }else if(w && w.slice(-2) == "px"){
+ return window.parseInt(w, 10);
+ }
+ return dojo.contentBox(c).w;
+ });
+ if(hasPct){
+ dojo.forEach(this.grid.layout.cells, function(cell, idx){
+ if(cell.view == this){
+ var cellNode = cell.view.getHeaderCellNode(cell.index);
+ if(cellNode && dojo.hasAttr(cellNode, "vIdx")){
+ var vIdx = window.parseInt(dojo.attr(cellNode, "vIdx"));
+ this.setColWidth(idx, fixedWidths[vIdx]);
+ dojo.removeAttr(cellNode, "vIdx");
+ }
+ }
+ }, this);
+ return true;
+ }
+ return false;
+ },
+
+ adaptHeight: function(minusScroll){
+ if(!this.grid._autoHeight){
+ var h = (this.domNode.style.height && parseInt(this.domNode.style.height.replace(/px/,''), 10)) || this.domNode.clientHeight;
+ var self = this;
+ var checkOtherViewScrollers = function(){
+ var v;
+ for(var i in self.grid.views.views){
+ v = self.grid.views.views[i];
+ if(v !== self && v.hasHScrollbar()){
+ return true;
+ }
+ }
+ return false;
+ };
+ if(minusScroll || (this.noscroll && checkOtherViewScrollers())){
+ h -= dojox.html.metrics.getScrollbar().h;
+ }
+ dojox.grid.util.setStyleHeightPx(this.scrollboxNode, h);
+ }
+ this.hasVScrollbar(true);
+ },
+
+ adaptWidth: function(){
+ if(this.flexCells){
+ // the view content width
+ this.contentWidth = this.getContentWidth();
+ this.headerContentNode.firstChild.style.width = this.contentWidth;
+ }
+ // FIXME: it should be easier to get w from this.scrollboxNode.clientWidth,
+ // but clientWidth seemingly does not include scrollbar width in some cases
+ var w = this.scrollboxNode.offsetWidth - this.getScrollbarWidth();
+ if(!this._removingColumn){
+ w = Math.max(w, this.getColumnsWidth()) + 'px';
+ }else{
+ w = Math.min(w, this.getColumnsWidth()) + 'px';
+ this._removingColumn = false;
+ }
+ var cn = this.contentNode;
+ cn.style.width = w;
+ this.hasHScrollbar(true);
+ },
+
+ setSize: function(w, h){
+ var ds = this.domNode.style;
+ var hs = this.headerNode.style;
+
+ if(w){
+ ds.width = w;
+ hs.width = w;
+ }
+ ds.height = (h >= 0 ? h + 'px' : '');
+ },
+
+ renderRow: function(inRowIndex){
+ var rowNode = this.createRowNode(inRowIndex);
+ this.buildRow(inRowIndex, rowNode);
+ this.grid.edit.restore(this, inRowIndex);
+ return rowNode;
+ },
+
+ createRowNode: function(inRowIndex){
+ var node = document.createElement("div");
+ node.className = this.classTag + 'Row';
+ if (this instanceof dojox.grid._RowSelector){
+ dojo.attr(node,"role","presentation");
+ }else{
+ dojo.attr(node,"role","row");
+ if (this.grid.selectionMode != "none") {
+ dojo.attr(node, "aria-selected", "false"); //rows can be selected so add aria-selected prop
+ }
+ }
+ node[dojox.grid.util.gridViewTag] = this.id;
+ node[dojox.grid.util.rowIndexTag] = inRowIndex;
+ this.rowNodes[inRowIndex] = node;
+ return node;
+ },
+
+ buildRow: function(inRowIndex, inRowNode){
+
+ this.buildRowContent(inRowIndex, inRowNode);
+
+ this.styleRow(inRowIndex, inRowNode);
+
+
+ },
+
+ buildRowContent: function(inRowIndex, inRowNode){
+ inRowNode.innerHTML = this.content.generateHtml(inRowIndex, inRowIndex);
+ if(this.flexCells && this.contentWidth){
+ // FIXME: accessing firstChild here breaks encapsulation
+ inRowNode.firstChild.style.width = this.contentWidth;
+ }
+ dojox.grid.util.fire(this, "onAfterRow", [inRowIndex, this.structure.cells, inRowNode]);
+ },
+
+ rowRemoved:function(inRowIndex){
+ if(inRowIndex >= 0){
+ this._cleanupRowWidgets(this.getRowNode(inRowIndex));
+ }
+ this.grid.edit.save(this, inRowIndex);
+ delete this.rowNodes[inRowIndex];
+ },
+
+ getRowNode: function(inRowIndex){
+ return this.rowNodes[inRowIndex];
+ },
+
+ getCellNode: function(inRowIndex, inCellIndex){
+ var row = this.getRowNode(inRowIndex);
+ if(row){
+ return this.content.getCellNode(row, inCellIndex);
+ }
+ },
+
+ getHeaderCellNode: function(inCellIndex){
+ if(this.headerContentNode){
+ return this.header.getCellNode(this.headerContentNode, inCellIndex);
+ }
+ },
+
+ // styling
+ styleRow: function(inRowIndex, inRowNode){
+ inRowNode._style = getStyleText(inRowNode);
+ this.styleRowNode(inRowIndex, inRowNode);
+ },
+
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ this.doStyleRowNode(inRowIndex, inRowNode);
+ }
+ },
+
+ doStyleRowNode: function(inRowIndex, inRowNode){
+ this.grid.styleRowNode(inRowIndex, inRowNode);
+ },
+
+ // updating
+ updateRow: function(inRowIndex){
+ var rowNode = this.getRowNode(inRowIndex);
+ if(rowNode){
+ rowNode.style.height = '';
+ this.buildRow(inRowIndex, rowNode);
+ }
+ return rowNode;
+ },
+
+ updateRowStyles: function(inRowIndex){
+ this.styleRowNode(inRowIndex, this.getRowNode(inRowIndex));
+ },
+
+ // scrolling
+ lastTop: 0,
+ firstScroll:0,
+
+ doscroll: function(inEvent){
+ //var s = dojo.marginBox(this.headerContentNode.firstChild);
+ var isLtr = dojo._isBodyLtr();
+ if(this.firstScroll < 2){
+ if((!isLtr && this.firstScroll == 1) || (isLtr && this.firstScroll === 0)){
+ var s = dojo.marginBox(this.headerNodeContainer);
+ if(dojo.isIE){
+ this.headerNodeContainer.style.width = s.w + this.getScrollbarWidth() + 'px';
+ }else if(dojo.isMoz){
+ //TODO currently only for FF, not sure for safari and opera
+ this.headerNodeContainer.style.width = s.w - this.getScrollbarWidth() + 'px';
+ //this.headerNodeContainer.style.width = s.w + 'px';
+ //set scroll to right in FF
+ this.scrollboxNode.scrollLeft = isLtr ?
+ this.scrollboxNode.clientWidth - this.scrollboxNode.scrollWidth :
+ this.scrollboxNode.scrollWidth - this.scrollboxNode.clientWidth;
+ }
+ }
+ this.firstScroll++;
+ }
+ this.headerNode.scrollLeft = this.scrollboxNode.scrollLeft;
+ // 'lastTop' is a semaphore to prevent feedback-loop with setScrollTop below
+ var top = this.scrollboxNode.scrollTop;
+ if(top !== this.lastTop){
+ this.grid.scrollTo(top);
+ }
+ },
+
+ setScrollTop: function(inTop){
+ // 'lastTop' is a semaphore to prevent feedback-loop with doScroll above
+ this.lastTop = inTop;
+ this.scrollboxNode.scrollTop = inTop;
+ return this.scrollboxNode.scrollTop;
+ },
+
+ // event handlers (direct from DOM)
+ doContentEvent: function(e){
+ if(this.content.decorateEvent(e)){
+ this.grid.onContentEvent(e);
+ }
+ },
+
+ doHeaderEvent: function(e){
+ if(this.header.decorateEvent(e)){
+ this.grid.onHeaderEvent(e);
+ }
+ },
+
+ // event dispatch(from Grid)
+ dispatchContentEvent: function(e){
+ return this.content.dispatchEvent(e);
+ },
+
+ dispatchHeaderEvent: function(e){
+ return this.header.dispatchEvent(e);
+ },
+
+ // column resizing
+ setColWidth: function(inIndex, inWidth){
+ this.grid.setCellWidth(inIndex, inWidth + 'px');
+ },
+
+ update: function(){
+ if(!this.domNode){
+ return;
+ }
+ this.content.update();
+ this.grid.update();
+ //get scroll after update or scroll left setting goes wrong on IE.
+ //See trac: #8040
+ var left = this.scrollboxNode.scrollLeft;
+ this.scrollboxNode.scrollLeft = left;
+ this.headerNode.scrollLeft = left;
+ }
+ });
+
+ dojo.declare("dojox.grid._GridAvatar", dojo.dnd.Avatar, {
+ construct: function(){
+ var dd = dojo.doc;
+
+ var a = dd.createElement("table");
+ a.cellPadding = a.cellSpacing = "0";
+ a.className = "dojoxGridDndAvatar";
+ a.style.position = "absolute";
+ a.style.zIndex = 1999;
+ a.style.margin = "0px"; // to avoid dojo.marginBox() problems with table's margins
+ var b = dd.createElement("tbody");
+ var tr = dd.createElement("tr");
+ var td = dd.createElement("td");
+ var img = dd.createElement("td");
+ tr.className = "dojoxGridDndAvatarItem";
+ img.className = "dojoxGridDndAvatarItemImage";
+ img.style.width = "16px";
+ var source = this.manager.source, node;
+ if(source.creator){
+ // create an avatar representation of the node
+ node = source._normalizedCreator(source.getItem(this.manager.nodes[0].id).data, "avatar").node;
+ }else{
+ // or just clone the node and hope it works
+ node = this.manager.nodes[0].cloneNode(true);
+ var table, tbody;
+ if(node.tagName.toLowerCase() == "tr"){
+ // insert extra table nodes
+ table = dd.createElement("table");
+ tbody = dd.createElement("tbody");
+ tbody.appendChild(node);
+ table.appendChild(tbody);
+ node = table;
+ }else if(node.tagName.toLowerCase() == "th"){
+ // insert extra table nodes
+ table = dd.createElement("table");
+ tbody = dd.createElement("tbody");
+ var r = dd.createElement("tr");
+ table.cellPadding = table.cellSpacing = "0";
+ r.appendChild(node);
+ tbody.appendChild(r);
+ table.appendChild(tbody);
+ node = table;
+ }
+ }
+ node.id = "";
+ td.appendChild(node);
+ tr.appendChild(img);
+ tr.appendChild(td);
+ dojo.style(tr, "opacity", 0.9);
+ b.appendChild(tr);
+
+ a.appendChild(b);
+ this.node = a;
+
+ var m = dojo.dnd.manager();
+ this.oldOffsetY = m.OFFSET_Y;
+ m.OFFSET_Y = 1;
+ },
+ destroy: function(){
+ dojo.dnd.manager().OFFSET_Y = this.oldOffsetY;
+ this.inherited(arguments);
+ }
+ });
+
+ var oldMakeAvatar = dojo.dnd.manager().makeAvatar;
+ dojo.dnd.manager().makeAvatar = function(){
+ var src = this.source;
+ if(src.viewIndex !== undefined && !dojo.hasClass(dojo.body(),"dijit_a11y")){
+ return new dojox.grid._GridAvatar(this);
+ }
+ return oldMakeAvatar.call(dojo.dnd.manager());
+ };
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid._RowSelector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._RowSelector"] = true;
+dojo.provide("dojox.grid._RowSelector");
+
+
+dojo.declare('dojox.grid._RowSelector', dojox.grid._View, {
+ // summary:
+ // Custom grid view. If used in a grid structure, provides a small selectable region for grid rows.
+ defaultWidth: "2em",
+ noscroll: true,
+ padBorderWidth: 2,
+ buildRendering: function(){
+ this.inherited('buildRendering', arguments);
+ this.scrollboxNode.style.overflow = "hidden";
+ this.headerNode.style.visibility = "hidden";
+ },
+ getWidth: function(){
+ return this.viewWidth || this.defaultWidth;
+ },
+ buildRowContent: function(inRowIndex, inRowNode){
+ var w = this.contentWidth || 0;
+ inRowNode.innerHTML = '<table class="dojoxGridRowbarTable" style="width:' + w + 'px;height:1px;" border="0" cellspacing="0" cellpadding="0" role="presentation"><tr><td class="dojoxGridRowbarInner">&nbsp;</td></tr></table>';
+ },
+ renderHeader: function(){
+ },
+ updateRow: function(){
+ },
+ resize: function(){
+ this.adaptHeight();
+ },
+ adaptWidth: function(){
+ // Only calculate this here - rather than every call to buildRowContent
+ if(!("contentWidth" in this) && this.contentNode){
+ this.contentWidth = this.contentNode.offsetWidth - this.padBorderWidth;
+ }
+ },
+ // styling
+ doStyleRowNode: function(inRowIndex, inRowNode){
+ var n = [ "dojoxGridRowbar dojoxGridNonNormalizedCell" ];
+ if(this.grid.rows.isOver(inRowIndex)){
+ n.push("dojoxGridRowbarOver");
+ }
+ if(this.grid.selection.isSelected(inRowIndex)){
+ n.push("dojoxGridRowbarSelected");
+ }
+ inRowNode.className = n.join(" ");
+ },
+ // event handlers
+ domouseover: function(e){
+ this.grid.onMouseOverRow(e);
+ },
+ domouseout: function(e){
+ if(!this.isIntraRowEvent(e)){
+ this.grid.onMouseOutRow(e);
+ }
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._Layout"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Layout"] = true;
+dojo.provide("dojox.grid._Layout");
+
+
+
+dojo.declare("dojox.grid._Layout", null, {
+ // summary:
+ // Controls grid cell layout. Owned by grid and used internally.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+ // flat array of grid cells
+ cells: [],
+ // structured array of grid cells
+ structure: null,
+ // default cell width
+ defaultWidth: '6em',
+
+ // methods
+ moveColumn: function(sourceViewIndex, destViewIndex, cellIndex, targetIndex, before){
+ var source_cells = this.structure[sourceViewIndex].cells[0];
+ var dest_cells = this.structure[destViewIndex].cells[0];
+
+ var cell = null;
+ var cell_ri = 0;
+ var target_ri = 0;
+
+ for(var i=0, c; c=source_cells[i]; i++){
+ if(c.index == cellIndex){
+ cell_ri = i;
+ break;
+ }
+ }
+ cell = source_cells.splice(cell_ri, 1)[0];
+ cell.view = this.grid.views.views[destViewIndex];
+
+ for(i=0, c=null; c=dest_cells[i]; i++){
+ if(c.index == targetIndex){
+ target_ri = i;
+ break;
+ }
+ }
+ if(!before){
+ target_ri += 1;
+ }
+ dest_cells.splice(target_ri, 0, cell);
+
+ var sortedCell = this.grid.getCell(this.grid.getSortIndex());
+ if(sortedCell){
+ sortedCell._currentlySorted = this.grid.getSortAsc();
+ }
+
+ this.cells = [];
+ cellIndex = 0;
+ var v;
+ for(i=0; v=this.structure[i]; i++){
+ for(var j=0, cs; cs=v.cells[j]; j++){
+ for(var k=0; c=cs[k]; k++){
+ c.index = cellIndex;
+ this.cells.push(c);
+ if("_currentlySorted" in c){
+ var si = cellIndex + 1;
+ si *= c._currentlySorted ? 1 : -1;
+ this.grid.sortInfo = si;
+ delete c._currentlySorted;
+ }
+ cellIndex++;
+ }
+ }
+ }
+
+ //Fix #9481 - reset idx in cell markup
+ dojo.forEach(this.cells, function(c){
+ var marks = c.markup[2].split(" ");
+ var oldIdx = parseInt(marks[1].substring(5));//get old "idx"
+ if(oldIdx != c.index){
+ marks[1] = "idx=\"" + c.index + "\"";
+ c.markup[2] = marks.join(" ");
+ }
+ });
+
+ this.grid.setupHeaderMenu();
+ //this.grid.renderOnIdle();
+ },
+
+ setColumnVisibility: function(columnIndex, visible){
+ var cell = this.cells[columnIndex];
+ if(cell.hidden == visible){
+ cell.hidden = !visible;
+ var v = cell.view, w = v.viewWidth;
+ if(w && w != "auto"){
+ v._togglingColumn = dojo.marginBox(cell.getHeaderNode()).w || 0;
+ }
+ v.update();
+ return true;
+ }else{
+ return false;
+ }
+ },
+
+ addCellDef: function(inRowIndex, inCellIndex, inDef){
+ var self = this;
+ var getCellWidth = function(inDef){
+ var w = 0;
+ if(inDef.colSpan > 1){
+ w = 0;
+ }else{
+ w = inDef.width || self._defaultCellProps.width || self.defaultWidth;
+
+ if(!isNaN(w)){
+ w = w + "em";
+ }
+ }
+ return w;
+ };
+
+ var props = {
+ grid: this.grid,
+ subrow: inRowIndex,
+ layoutIndex: inCellIndex,
+ index: this.cells.length
+ };
+
+ if(inDef && inDef instanceof dojox.grid.cells._Base){
+ var new_cell = dojo.clone(inDef);
+ props.unitWidth = getCellWidth(new_cell._props);
+ new_cell = dojo.mixin(new_cell, this._defaultCellProps, inDef._props, props);
+ return new_cell;
+ }
+
+ var cell_type = inDef.type || inDef.cellType || this._defaultCellProps.type || this._defaultCellProps.cellType || dojox.grid.cells.Cell;
+
+ props.unitWidth = getCellWidth(inDef);
+ return new cell_type(dojo.mixin({}, this._defaultCellProps, inDef, props));
+ },
+
+ addRowDef: function(inRowIndex, inDef){
+ var result = [];
+ var relSum = 0, pctSum = 0, doRel = true;
+ for(var i=0, def, cell; (def=inDef[i]); i++){
+ cell = this.addCellDef(inRowIndex, i, def);
+ result.push(cell);
+ this.cells.push(cell);
+ // Check and calculate the sum of all relative widths
+ if(doRel && cell.relWidth){
+ relSum += cell.relWidth;
+ }else if(cell.width){
+ var w = cell.width;
+ if(typeof w == "string" && w.slice(-1) == "%"){
+ pctSum += window.parseInt(w, 10);
+ }else if(w == "auto"){
+ // relative widths doesn't play nice with auto - since we
+ // don't have a way of knowing how much space the auto is
+ // supposed to take up.
+ doRel = false;
+ }
+ }
+ }
+ if(relSum && doRel){
+ // We have some kind of relWidths specified - so change them to %
+ dojo.forEach(result, function(cell){
+ if(cell.relWidth){
+ cell.width = cell.unitWidth = ((cell.relWidth / relSum) * (100 - pctSum)) + "%";
+ }
+ });
+ }
+ return result;
+
+ },
+
+ addRowsDef: function(inDef){
+ var result = [];
+ if(dojo.isArray(inDef)){
+ if(dojo.isArray(inDef[0])){
+ for(var i=0, row; inDef && (row=inDef[i]); i++){
+ result.push(this.addRowDef(i, row));
+ }
+ }else{
+ result.push(this.addRowDef(0, inDef));
+ }
+ }
+ return result;
+ },
+
+ addViewDef: function(inDef){
+ this._defaultCellProps = inDef.defaultCell || {};
+ if(inDef.width && inDef.width == "auto"){
+ delete inDef.width;
+ }
+ return dojo.mixin({}, inDef, {cells: this.addRowsDef(inDef.rows || inDef.cells)});
+ },
+
+ setStructure: function(inStructure){
+ this.fieldIndex = 0;
+ this.cells = [];
+ var s = this.structure = [];
+
+ if(this.grid.rowSelector){
+ var sel = { type: dojox._scopeName + ".grid._RowSelector" };
+
+ if(dojo.isString(this.grid.rowSelector)){
+ var width = this.grid.rowSelector;
+
+ if(width == "false"){
+ sel = null;
+ }else if(width != "true"){
+ sel['width'] = width;
+ }
+ }else{
+ if(!this.grid.rowSelector){
+ sel = null;
+ }
+ }
+
+ if(sel){
+ s.push(this.addViewDef(sel));
+ }
+ }
+
+ var isCell = function(def){
+ return ("name" in def || "field" in def || "get" in def);
+ };
+
+ var isRowDef = function(def){
+ if(dojo.isArray(def)){
+ if(dojo.isArray(def[0]) || isCell(def[0])){
+ return true;
+ }
+ }
+ return false;
+ };
+
+ var isView = function(def){
+ return (def !== null && dojo.isObject(def) &&
+ ("cells" in def || "rows" in def || ("type" in def && !isCell(def))));
+ };
+
+ if(dojo.isArray(inStructure)){
+ var hasViews = false;
+ for(var i=0, st; (st=inStructure[i]); i++){
+ if(isView(st)){
+ hasViews = true;
+ break;
+ }
+ }
+ if(!hasViews){
+ s.push(this.addViewDef({ cells: inStructure }));
+ }else{
+ for(i=0; (st=inStructure[i]); i++){
+ if(isRowDef(st)){
+ s.push(this.addViewDef({ cells: st }));
+ }else if(isView(st)){
+ s.push(this.addViewDef(st));
+ }
+ }
+ }
+ }else if(isView(inStructure)){
+ // it's a view object
+ s.push(this.addViewDef(inStructure));
+ }
+
+ this.cellCount = this.cells.length;
+ this.grid.setupHeaderMenu();
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._ViewManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._ViewManager"] = true;
+dojo.provide("dojox.grid._ViewManager");
+
+dojo.declare('dojox.grid._ViewManager', null, {
+ // summary:
+ // A collection of grid views. Owned by grid and used internally for managing grid views.
+ // description:
+ // Grid creates views automatically based on grid's layout structure.
+ // Users should typically not need to access individual views or the views collection directly.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+
+ defaultWidth: 200,
+
+ views: [],
+
+ // operations
+ resize: function(){
+ this.onEach("resize");
+ },
+
+ render: function(){
+ this.onEach("render");
+ },
+
+ // views
+ addView: function(inView){
+ inView.idx = this.views.length;
+ this.views.push(inView);
+ },
+
+ destroyViews: function(){
+ for(var i=0, v; v=this.views[i]; i++){
+ v.destroy();
+ }
+ this.views = [];
+ },
+
+ getContentNodes: function(){
+ var nodes = [];
+ for(var i=0, v; v=this.views[i]; i++){
+ nodes.push(v.contentNode);
+ }
+ return nodes;
+ },
+
+ forEach: function(inCallback){
+ for(var i=0, v; v=this.views[i]; i++){
+ inCallback(v, i);
+ }
+ },
+
+ onEach: function(inMethod, inArgs){
+ inArgs = inArgs || [];
+ for(var i=0, v; v=this.views[i]; i++){
+ if(inMethod in v){
+ v[inMethod].apply(v, inArgs);
+ }
+ }
+ },
+
+ // layout
+ normalizeHeaderNodeHeight: function(){
+ var rowNodes = [];
+ for(var i=0, v; (v=this.views[i]); i++){
+ if(v.headerContentNode.firstChild){
+ rowNodes.push(v.headerContentNode);
+ }
+ }
+ this.normalizeRowNodeHeights(rowNodes);
+ },
+
+ normalizeRowNodeHeights: function(inRowNodes){
+ var h = 0;
+ var currHeights = [];
+ if(this.grid.rowHeight){
+ h = this.grid.rowHeight;
+ }else{
+ if(inRowNodes.length <= 1){
+ // no need to normalize if we are the only one...
+ return;
+ }
+ for(var i=0, n; (n=inRowNodes[i]); i++){
+ // We only care about the height - so don't use marginBox. This
+ // depends on the container not having any margin (which it shouldn't)
+ // Also - we only look up the height if the cell doesn't have the
+ // dojoxGridNonNormalizedCell class (like for row selectors)
+ if(!dojo.hasClass(n, "dojoxGridNonNormalizedCell")){
+ currHeights[i] = n.firstChild.offsetHeight;
+ h = Math.max(h, currHeights[i]);
+ }
+ }
+ h = (h >= 0 ? h : 0);
+
+ //Work around odd FF3 rendering bug: #8864.
+ //A one px increase fixes FireFox 3's rounding bug for fractional font sizes.
+ if(dojo.isMoz && h){h++;}
+ }
+ for(i=0; (n=inRowNodes[i]); i++){
+ if(currHeights[i] != h){
+ n.firstChild.style.height = h + "px";
+ }
+ }
+ },
+
+ resetHeaderNodeHeight: function(){
+ for(var i=0, v, n; (v=this.views[i]); i++){
+ n = v.headerContentNode.firstChild;
+ if(n){
+ n.style.height = "";
+ }
+ }
+ },
+
+ renormalizeRow: function(inRowIndex){
+ var rowNodes = [];
+ for(var i=0, v, n; (v=this.views[i])&&(n=v.getRowNode(inRowIndex)); i++){
+ n.firstChild.style.height = '';
+ rowNodes.push(n);
+ }
+ this.normalizeRowNodeHeights(rowNodes);
+ },
+
+ getViewWidth: function(inIndex){
+ return this.views[inIndex].getWidth() || this.defaultWidth;
+ },
+
+ // must be called after view widths are properly set or height can be miscalculated
+ // if there are flex columns
+ measureHeader: function(){
+ // need to reset view header heights so they are properly measured.
+ this.resetHeaderNodeHeight();
+ this.forEach(function(inView){
+ inView.headerContentNode.style.height = '';
+ });
+ var h = 0;
+ // calculate maximum view header height
+ this.forEach(function(inView){
+ h = Math.max(inView.headerNode.offsetHeight, h);
+ });
+ return h;
+ },
+
+ measureContent: function(){
+ var h = 0;
+ this.forEach(function(inView){
+ h = Math.max(inView.domNode.offsetHeight, h);
+ });
+ return h;
+ },
+
+ findClient: function(inAutoWidth){
+ // try to use user defined client
+ var c = this.grid.elasticView || -1;
+ // attempt to find implicit client
+ if(c < 0){
+ for(var i=1, v; (v=this.views[i]); i++){
+ if(v.viewWidth){
+ for(i=1; (v=this.views[i]); i++){
+ if(!v.viewWidth){
+ c = i;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ // client is in the middle by default
+ if(c < 0){
+ c = Math.floor(this.views.length / 2);
+ }
+ return c;
+ },
+
+ arrange: function(l, w){
+ var i, v, vw, len = this.views.length;
+ // find the client
+ var c = (w <= 0 ? len : this.findClient());
+ // layout views
+ var setPosition = function(v, l){
+ var ds = v.domNode.style;
+ var hs = v.headerNode.style;
+
+ if(!dojo._isBodyLtr()){
+ ds.right = l + 'px';
+ // fixed rtl, the scrollbar is on the right side in FF
+ if (dojo.isMoz) {
+ hs.right = l + v.getScrollbarWidth() + 'px';
+ hs.width = parseInt(hs.width, 10) - v.getScrollbarWidth() + 'px';
+ }else{
+ hs.right = l + 'px';
+ }
+ }else{
+ ds.left = l + 'px';
+ hs.left = l + 'px';
+ }
+ ds.top = 0 + 'px';
+ hs.top = 0;
+ };
+ // for views left of the client
+ //BiDi TODO: The left and right should not appear in BIDI environment. Should be replaced with
+ //leading and tailing concept.
+ for(i=0; (v=this.views[i])&&(i<c); i++){
+ // get width
+ vw = this.getViewWidth(i);
+ // process boxes
+ v.setSize(vw, 0);
+ setPosition(v, l);
+ if(v.headerContentNode && v.headerContentNode.firstChild){
+ vw = v.getColumnsWidth()+v.getScrollbarWidth();
+ }else{
+ vw = v.domNode.offsetWidth;
+ }
+ // update position
+ l += vw;
+ }
+ // next view (is the client, i++ == c)
+ i++;
+ // start from the right edge
+ var r = w;
+ // for views right of the client (iterated from the right)
+ for(var j=len-1; (v=this.views[j])&&(i<=j); j--){
+ // get width
+ vw = this.getViewWidth(j);
+ // set size
+ v.setSize(vw, 0);
+ // measure in pixels
+ vw = v.domNode.offsetWidth;
+ // update position
+ r -= vw;
+ // set position
+ setPosition(v, r);
+ }
+ if(c<len){
+ v = this.views[c];
+ // position the client box between left and right boxes
+ vw = Math.max(1, r-l);
+ // set size
+ v.setSize(vw + 'px', 0);
+ setPosition(v, l);
+ }
+ return l;
+ },
+
+ // rendering
+ renderRow: function(inRowIndex, inNodes, skipRenorm){
+ var rowNodes = [];
+ for(var i=0, v, n, rowNode; (v=this.views[i])&&(n=inNodes[i]); i++){
+ rowNode = v.renderRow(inRowIndex);
+ n.appendChild(rowNode);
+ rowNodes.push(rowNode);
+ }
+ if(!skipRenorm){
+ this.normalizeRowNodeHeights(rowNodes);
+ }
+ },
+
+ rowRemoved: function(inRowIndex){
+ this.onEach("rowRemoved", [ inRowIndex ]);
+ },
+
+ // updating
+ updateRow: function(inRowIndex, skipRenorm){
+ for(var i=0, v; v=this.views[i]; i++){
+ v.updateRow(inRowIndex);
+ }
+ if(!skipRenorm){
+ this.renormalizeRow(inRowIndex);
+ }
+ },
+
+ updateRowStyles: function(inRowIndex){
+ this.onEach("updateRowStyles", [ inRowIndex ]);
+ },
+
+ // scrolling
+ setScrollTop: function(inTop){
+ var top = inTop;
+ for(var i=0, v; v=this.views[i]; i++){
+ top = v.setScrollTop(inTop);
+ // Work around IE not firing scroll events that cause header offset
+ // issues to occur.
+ if(dojo.isIE && v.headerNode && v.scrollboxNode){
+ v.headerNode.scrollLeft = v.scrollboxNode.scrollLeft;
+ }
+ }
+ return top;
+ //this.onEach("setScrollTop", [ inTop ]);
+ },
+
+ getFirstScrollingView: function(){
+ // summary: Returns the first grid view with a scroll bar
+ for(var i=0, v; (v=this.views[i]); i++){
+ if(v.hasHScrollbar() || v.hasVScrollbar()){
+ return v;
+ }
+ }
+ return null;
+ }
+
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._RowManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._RowManager"] = true;
+dojo.provide("dojox.grid._RowManager");
+
+(function(){
+ var setStyleText = function(inNode, inStyleText){
+ if(inNode.style.cssText == undefined){
+ inNode.setAttribute("style", inStyleText);
+ }else{
+ inNode.style.cssText = inStyleText;
+ }
+ };
+
+ dojo.declare("dojox.grid._RowManager", null, {
+ // Stores information about grid rows. Owned by grid and used internally.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+ linesToEms: 2,
+ overRow: -2,
+ // styles
+ prepareStylingRow: function(inRowIndex, inRowNode){
+ return {
+ index: inRowIndex,
+ node: inRowNode,
+ odd: Boolean(inRowIndex&1),
+ selected: !!this.grid.selection.isSelected(inRowIndex),
+ over: this.isOver(inRowIndex),
+ customStyles: "",
+ customClasses: "dojoxGridRow"
+ };
+ },
+ styleRowNode: function(inRowIndex, inRowNode){
+ var row = this.prepareStylingRow(inRowIndex, inRowNode);
+ this.grid.onStyleRow(row);
+ this.applyStyles(row);
+ },
+ applyStyles: function(inRow){
+ var i = inRow;
+
+ i.node.className = i.customClasses;
+ var h = i.node.style.height;
+ setStyleText(i.node, i.customStyles + ';' + (i.node._style||''));
+ i.node.style.height = h;
+ },
+ updateStyles: function(inRowIndex){
+ this.grid.updateRowStyles(inRowIndex);
+ },
+ // states and events
+ setOverRow: function(inRowIndex){
+ var last = this.overRow;
+ this.overRow = inRowIndex;
+ if((last!=this.overRow)&&(dojo.isString(last) || last >= 0)){
+ this.updateStyles(last);
+ }
+ this.updateStyles(this.overRow);
+ },
+ isOver: function(inRowIndex){
+ return (this.overRow == inRowIndex && !dojo.hasClass(this.grid.domNode, "dojoxGridColumnResizing"));
+ }
+ });
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid._FocusManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._FocusManager"] = true;
+dojo.provide("dojox.grid._FocusManager");
+
+
+
+// focus management
+dojo.declare("dojox.grid._FocusManager", null, {
+ // summary:
+ // Controls grid cell focus. Owned by grid and used internally for focusing.
+ // Note: grid cell actually receives keyboard input only when cell is being edited.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ this.cell = null;
+ this.rowIndex = -1;
+ this._connects = [];
+ this._headerConnects = [];
+ this.headerMenu = this.grid.headerMenu;
+ this._connects.push(dojo.connect(this.grid.domNode, "onfocus", this, "doFocus"));
+ this._connects.push(dojo.connect(this.grid.domNode, "onblur", this, "doBlur"));
+ this._connects.push(dojo.connect(this.grid.domNode, "oncontextmenu", this, "doContextMenu"));
+ this._connects.push(dojo.connect(this.grid.lastFocusNode, "onfocus", this, "doLastNodeFocus"));
+ this._connects.push(dojo.connect(this.grid.lastFocusNode, "onblur", this, "doLastNodeBlur"));
+ this._connects.push(dojo.connect(this.grid,"_onFetchComplete", this, "_delayedCellFocus"));
+ this._connects.push(dojo.connect(this.grid,"postrender", this, "_delayedHeaderFocus"));
+ },
+ destroy: function(){
+ dojo.forEach(this._connects, dojo.disconnect);
+ dojo.forEach(this._headerConnects, dojo.disconnect);
+ delete this.grid;
+ delete this.cell;
+ },
+ _colHeadNode: null,
+ _colHeadFocusIdx: null,
+ _contextMenuBindNode: null,
+ tabbingOut: false,
+ focusClass: "dojoxGridCellFocus",
+ focusView: null,
+ initFocusView: function(){
+ this.focusView = this.grid.views.getFirstScrollingView() || this.focusView || this.grid.views.views[0];
+ this._initColumnHeaders();
+ },
+ isFocusCell: function(inCell, inRowIndex){
+ // summary:
+ // states if the given cell is focused
+ // inCell: object
+ // grid cell object
+ // inRowIndex: int
+ // grid row index
+ // returns:
+ // true of the given grid cell is focused
+ return (this.cell == inCell) && (this.rowIndex == inRowIndex);
+ },
+ isLastFocusCell: function(){
+ if(this.cell){
+ return (this.rowIndex == this.grid.rowCount-1) && (this.cell.index == this.grid.layout.cellCount-1);
+ }
+ return false;
+ },
+ isFirstFocusCell: function(){
+ if(this.cell){
+ return (this.rowIndex === 0) && (this.cell.index === 0);
+ }
+ return false;
+ },
+ isNoFocusCell: function(){
+ return (this.rowIndex < 0) || !this.cell;
+ },
+ isNavHeader: function(){
+ // summary:
+ // states whether currently navigating among column headers.
+ // returns:
+ // true if focus is on a column header; false otherwise.
+ return (!!this._colHeadNode);
+ },
+ getHeaderIndex: function(){
+ // summary:
+ // if one of the column headers currently has focus, return its index.
+ // returns:
+ // index of the focused column header, or -1 if none have focus.
+ if(this._colHeadNode){
+ return dojo.indexOf(this._findHeaderCells(), this._colHeadNode);
+ }else{
+ return -1;
+ }
+ },
+ _focusifyCellNode: function(inBork){
+ var n = this.cell && this.cell.getNode(this.rowIndex);
+ if(n){
+ dojo.toggleClass(n, this.focusClass, inBork);
+ if(inBork){
+ var sl = this.scrollIntoView();
+ try{
+ if(!this.grid.edit.isEditing()){
+ dojox.grid.util.fire(n, "focus");
+ if(sl){ this.cell.view.scrollboxNode.scrollLeft = sl; }
+ }
+ }catch(e){}
+ }
+ }
+ },
+ _delayedCellFocus: function(){
+ if(this.isNavHeader()||!this.grid._focused){
+ return;
+ }
+ var n = this.cell && this.cell.getNode(this.rowIndex);
+ if(n){
+ try{
+ if(!this.grid.edit.isEditing()){
+ dojo.toggleClass(n, this.focusClass, true);
+ this.blurHeader();
+ dojox.grid.util.fire(n, "focus");
+ }
+ }
+ catch(e){}
+ }
+ },
+ _delayedHeaderFocus: function(){
+ if(this.isNavHeader()){
+ this.focusHeader();
+ this.grid.domNode.focus();
+ }
+ },
+ _initColumnHeaders: function(){
+ dojo.forEach(this._headerConnects, dojo.disconnect);
+ this._headerConnects = [];
+ var headers = this._findHeaderCells();
+ for(var i = 0; i < headers.length; i++){
+ this._headerConnects.push(dojo.connect(headers[i], "onfocus", this, "doColHeaderFocus"));
+ this._headerConnects.push(dojo.connect(headers[i], "onblur", this, "doColHeaderBlur"));
+ }
+ },
+ _findHeaderCells: function(){
+ // This should be a one liner:
+ // dojo.query("th[tabindex=-1]", this.grid.viewsHeaderNode);
+ // But there is a bug in dojo.query() for IE -- see trac #7037.
+ var allHeads = dojo.query("th", this.grid.viewsHeaderNode);
+ var headers = [];
+ for (var i = 0; i < allHeads.length; i++){
+ var aHead = allHeads[i];
+ var hasTabIdx = dojo.hasAttr(aHead, "tabIndex");
+ var tabindex = dojo.attr(aHead, "tabIndex");
+ if (hasTabIdx && tabindex < 0) {
+ headers.push(aHead);
+ }
+ }
+ return headers;
+ },
+ _setActiveColHeader: function(/*Node*/colHeaderNode, /*Integer*/colFocusIdx, /*Integer*/ prevColFocusIdx){
+ //console.log("setActiveColHeader() - colHeaderNode:colFocusIdx:prevColFocusIdx = " + colHeaderNode + ":" + colFocusIdx + ":" + prevColFocusIdx);
+ dojo.attr(this.grid.domNode, "aria-activedescendant",colHeaderNode.id);
+ if (prevColFocusIdx != null && prevColFocusIdx >= 0 && prevColFocusIdx != colFocusIdx){
+ dojo.toggleClass(this._findHeaderCells()[prevColFocusIdx],this.focusClass,false);
+ }
+ dojo.toggleClass(colHeaderNode,this.focusClass, true);
+ this._colHeadNode = colHeaderNode;
+ this._colHeadFocusIdx = colFocusIdx;
+ this._scrollHeader(this._colHeadFocusIdx);
+ },
+ scrollIntoView: function(){
+ var info = (this.cell ? this._scrollInfo(this.cell) : null);
+ if(!info || !info.s){
+ return null;
+ }
+ var rt = this.grid.scroller.findScrollTop(this.rowIndex);
+ // place cell within horizontal view
+ if(info.n && info.sr){
+ if(info.n.offsetLeft + info.n.offsetWidth > info.sr.l + info.sr.w){
+ info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w;
+ }else if(info.n.offsetLeft < info.sr.l){
+ info.s.scrollLeft = info.n.offsetLeft;
+ }
+ }
+ // place cell within vertical view
+ if(info.r && info.sr){
+ if(rt + info.r.offsetHeight > info.sr.t + info.sr.h){
+ this.grid.setScrollTop(rt + info.r.offsetHeight - info.sr.h);
+ }else if(rt < info.sr.t){
+ this.grid.setScrollTop(rt);
+ }
+ }
+
+ return info.s.scrollLeft;
+ },
+ _scrollInfo: function(cell, domNode){
+ if(cell){
+ var cl = cell,
+ sbn = cl.view.scrollboxNode,
+ sbnr = {
+ w: sbn.clientWidth,
+ l: sbn.scrollLeft,
+ t: sbn.scrollTop,
+ h: sbn.clientHeight
+ },
+ rn = cl.view.getRowNode(this.rowIndex);
+ return {
+ c: cl,
+ s: sbn,
+ sr: sbnr,
+ n: (domNode ? domNode : cell.getNode(this.rowIndex)),
+ r: rn
+ };
+ }
+ return null;
+ },
+ _scrollHeader: function(currentIdx){
+ var info = null;
+ if(this._colHeadNode){
+ var cell = this.grid.getCell(currentIdx);
+ info = this._scrollInfo(cell, cell.getNode(0));
+ }
+ if(info && info.s && info.sr && info.n){
+ // scroll horizontally as needed.
+ var scroll = info.sr.l + info.sr.w;
+ if(info.n.offsetLeft + info.n.offsetWidth > scroll){
+ info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w;
+ }else if(info.n.offsetLeft < info.sr.l){
+ info.s.scrollLeft = info.n.offsetLeft;
+ }else if(dojo.isIE <= 7 && cell && cell.view.headerNode){
+ // Trac 7158: scroll dojoxGridHeader for IE7 and lower
+ cell.view.headerNode.scrollLeft = info.s.scrollLeft;
+ }
+ }
+ },
+ _isHeaderHidden: function(){
+ // summary:
+ // determine if the grid headers are hidden
+ // relies on documented technique of setting .dojoxGridHeader { display:none; }
+ // returns: Boolean
+ // true if headers are hidden
+ // false if headers are not hidden
+
+ var curView = this.focusView;
+ if (!curView){
+ // find one so we can determine if headers are hidden
+ // there is no focusView after adding items to empty grid (test_data_grid_empty.html)
+ for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) {
+ if(cView.headerNode ){
+ curView=cView;
+ break;
+ }
+ }
+ }
+ return (curView && dojo.getComputedStyle(curView.headerNode).display == "none");
+ },
+ colSizeAdjust: function (e, colIdx, delta){ // adjust the column specified by colIdx by the specified delta px
+ var headers = this._findHeaderCells();
+ var view = this.focusView;
+ if (!view) {
+ for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) {
+ // find first view with a tableMap in order to work with empty grid
+ if(cView.header.tableMap.map ){
+ view=cView;
+ break;
+ }
+ }
+ }
+ var curHeader = headers[colIdx];
+ if (!view || (colIdx == headers.length-1 && colIdx === 0)){
+ return; // can't adjust single col. grid
+ }
+ view.content.baseDecorateEvent(e);
+ // need to adjust event with header cell info since focus is no longer on header cell
+ e.cellNode = curHeader; //this.findCellTarget(e.target, e.rowNode);
+ e.cellIndex = view.content.getCellNodeIndex(e.cellNode);
+ e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null);
+ if (view.header.canResize(e)){
+ var deltaObj = {
+ l: delta
+ };
+ var drag = view.header.colResizeSetup(e,false);
+ view.header.doResizeColumn(drag, null, deltaObj);
+ view.update();
+ }
+ },
+ styleRow: function(inRow){
+ return;
+ },
+ setFocusIndex: function(inRowIndex, inCellIndex){
+ // summary:
+ // focuses the given grid cell
+ // inRowIndex: int
+ // grid row index
+ // inCellIndex: int
+ // grid cell index
+ this.setFocusCell(this.grid.getCell(inCellIndex), inRowIndex);
+ },
+ setFocusCell: function(inCell, inRowIndex){
+ // summary:
+ // focuses the given grid cell
+ // inCell: object
+ // grid cell object
+ // inRowIndex: int
+ // grid row index
+ if(inCell && !this.isFocusCell(inCell, inRowIndex)){
+ this.tabbingOut = false;
+ if (this._colHeadNode){
+ this.blurHeader();
+ }
+ this._colHeadNode = this._colHeadFocusIdx = null;
+ this.focusGridView();
+ this._focusifyCellNode(false);
+ this.cell = inCell;
+ this.rowIndex = inRowIndex;
+ this._focusifyCellNode(true);
+ }
+ // even if this cell isFocusCell, the document focus may need to be rejiggered
+ // call opera on delay to prevent keypress from altering focus
+ if(dojo.isOpera){
+ setTimeout(dojo.hitch(this.grid, 'onCellFocus', this.cell, this.rowIndex), 1);
+ }else{
+ this.grid.onCellFocus(this.cell, this.rowIndex);
+ }
+ },
+ next: function(){
+ // summary:
+ // focus next grid cell
+ if(this.cell){
+ var row=this.rowIndex, col=this.cell.index+1, cc=this.grid.layout.cellCount-1, rc=this.grid.rowCount-1;
+ if(col > cc){
+ col = 0;
+ row++;
+ }
+ if(row > rc){
+ col = cc;
+ row = rc;
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var nextCell = this.grid.getCell(col);
+ if (!this.isLastFocusCell() && (!nextCell.editable ||
+ this.grid.canEdit && !this.grid.canEdit(nextCell, row))){
+ this.cell=nextCell;
+ this.rowIndex=row;
+ this.next();
+ return;
+ }
+ }
+ this.setFocusIndex(row, col);
+ }
+ },
+ previous: function(){
+ // summary:
+ // focus previous grid cell
+ if(this.cell){
+ var row=(this.rowIndex || 0), col=(this.cell.index || 0) - 1;
+ if(col < 0){
+ col = this.grid.layout.cellCount-1;
+ row--;
+ }
+ if(row < 0){
+ row = 0;
+ col = 0;
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var prevCell = this.grid.getCell(col);
+ if (!this.isFirstFocusCell() && !prevCell.editable){
+ this.cell=prevCell;
+ this.rowIndex=row;
+ this.previous();
+ return;
+ }
+ }
+ this.setFocusIndex(row, col);
+ }
+ },
+ move: function(inRowDelta, inColDelta) {
+ // summary:
+ // focus grid cell or simulate focus to column header based on position relative to current focus
+ // inRowDelta: int
+ // vertical distance from current focus
+ // inColDelta: int
+ // horizontal distance from current focus
+
+ var colDir = inColDelta < 0 ? -1 : 1;
+ // Handle column headers.
+ if(this.isNavHeader()){
+ var headers = this._findHeaderCells();
+ var savedIdx = currentIdx = dojo.indexOf(headers, this._colHeadNode);
+ currentIdx += inColDelta;
+ while(currentIdx >=0 && currentIdx < headers.length && headers[currentIdx].style.display == "none"){
+ // skip over hidden column headers
+ currentIdx += colDir;
+ }
+ if((currentIdx >= 0) && (currentIdx < headers.length)){
+ this._setActiveColHeader(headers[currentIdx],currentIdx, savedIdx);
+ }
+ }else{
+ if(this.cell){
+ // Handle grid proper.
+ var sc = this.grid.scroller,
+ r = this.rowIndex,
+ rc = this.grid.rowCount-1,
+ row = Math.min(rc, Math.max(0, r+inRowDelta));
+ if(inRowDelta){
+ if(inRowDelta>0){
+ if(row > sc.getLastPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r));
+ }
+ }else if(inRowDelta<0){
+ if(row <= sc.getPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row));
+ }
+ }
+ }
+ var cc = this.grid.layout.cellCount-1,
+ i = this.cell.index,
+ col = Math.min(cc, Math.max(0, i+inColDelta));
+ var cell = this.grid.getCell(col);
+ while(col>=0 && col < cc && cell && cell.hidden === true){
+ // skip hidden cells
+ col += colDir;
+ cell = this.grid.getCell(col);
+ }
+ if (!cell || cell.hidden === true){
+ // don't change col if would move to hidden
+ col = i;
+ }
+ this.setFocusIndex(row, col);
+ if(inRowDelta){
+ this.grid.updateRow(r);
+ }
+ }
+ }
+ },
+ previousKey: function(e){
+ if(this.grid.edit.isEditing()){
+ dojo.stopEvent(e);
+ this.previous();
+ }else if(!this.isNavHeader() && !this._isHeaderHidden()) {
+ this.grid.domNode.focus(); // will call doFocus and set focus into header.
+ dojo.stopEvent(e);
+ }else{
+ this.tabOut(this.grid.domNode);
+ if (this._colHeadFocusIdx != null) { // clear grid header focus
+ dojo.toggleClass(this._findHeaderCells()[this._colHeadFocusIdx], this.focusClass, false);
+ this._colHeadFocusIdx = null;
+ }
+ this._focusifyCellNode(false);
+ }
+ },
+ nextKey: function(e) {
+ var isEmpty = (this.grid.rowCount === 0);
+ if(e.target === this.grid.domNode && this._colHeadFocusIdx == null){
+ this.focusHeader();
+ dojo.stopEvent(e);
+ }else if(this.isNavHeader()){
+ // if tabbing from col header, then go to grid proper.
+ this.blurHeader();
+ if(!this.findAndFocusGridCell()){
+ this.tabOut(this.grid.lastFocusNode);
+ }
+ this._colHeadNode = this._colHeadFocusIdx= null;
+ }else if(this.grid.edit.isEditing()){
+ dojo.stopEvent(e);
+ this.next();
+ }else{
+ this.tabOut(this.grid.lastFocusNode);
+ }
+ },
+ tabOut: function(inFocusNode){
+ this.tabbingOut = true;
+ inFocusNode.focus();
+ },
+ focusGridView: function(){
+ dojox.grid.util.fire(this.focusView, "focus");
+ },
+ focusGrid: function(inSkipFocusCell){
+ this.focusGridView();
+ this._focusifyCellNode(true);
+ },
+ findAndFocusGridCell: function(){
+ // summary:
+ // find the first focusable grid cell
+ // returns: Boolean
+ // true if focus was set to a cell
+ // false if no cell found to set focus onto
+
+ var didFocus = true;
+ var isEmpty = (this.grid.rowCount === 0); // If grid is empty this.grid.rowCount == 0
+ if (this.isNoFocusCell() && !isEmpty){
+ var cellIdx = 0;
+ var cell = this.grid.getCell(cellIdx);
+ if (cell.hidden) {
+ // if first cell isn't visible, use _colHeadFocusIdx
+ // could also use a while loop to find first visible cell - not sure that is worth it
+ cellIdx = this.isNavHeader() ? this._colHeadFocusIdx : 0;
+ }
+ this.setFocusIndex(0, cellIdx);
+ }
+ else if (this.cell && !isEmpty){
+ if (this.focusView && !this.focusView.rowNodes[this.rowIndex]){
+ // if rowNode for current index is undefined (likely as a result of a sort and because of #7304)
+ // scroll to that row
+ this.grid.scrollToRow(this.rowIndex);
+ }
+ this.focusGrid();
+ }else {
+ didFocus = false;
+ }
+ this._colHeadNode = this._colHeadFocusIdx= null;
+ return didFocus;
+ },
+ focusHeader: function(){
+ var headerNodes = this._findHeaderCells();
+ var saveColHeadFocusIdx = this._colHeadFocusIdx;
+ if (this._isHeaderHidden()){
+ // grid header is hidden, focus a cell
+ this.findAndFocusGridCell();
+ }
+ else if (!this._colHeadFocusIdx) {
+ if (this.isNoFocusCell()) {
+ this._colHeadFocusIdx = 0;
+ }
+ else {
+ this._colHeadFocusIdx = this.cell.index;
+ }
+ }
+ this._colHeadNode = headerNodes[this._colHeadFocusIdx];
+ while(this._colHeadNode && this._colHeadFocusIdx >=0 && this._colHeadFocusIdx < headerNodes.length &&
+ this._colHeadNode.style.display == "none"){
+ // skip over hidden column headers
+ this._colHeadFocusIdx++;
+ this._colHeadNode = headerNodes[this._colHeadFocusIdx];
+ }
+ if(this._colHeadNode && this._colHeadNode.style.display != "none"){
+ // Column header cells know longer receive actual focus. So, for keyboard invocation of
+ // contextMenu to work, the contextMenu must be bound to the grid.domNode rather than the viewsHeaderNode.
+ // unbind the contextmenu from the viewsHeaderNode and to the grid when header cells are active. Reset
+ // the binding back to the viewsHeaderNode when header cells are no longer acive (in blurHeader) #10483
+ if (this.headerMenu && this._contextMenuBindNode != this.grid.domNode){
+ this.headerMenu.unBindDomNode(this.grid.viewsHeaderNode);
+ this.headerMenu.bindDomNode(this.grid.domNode);
+ this._contextMenuBindNode = this.grid.domNode;
+ }
+ this._setActiveColHeader(this._colHeadNode, this._colHeadFocusIdx, saveColHeadFocusIdx);
+ this._scrollHeader(this._colHeadFocusIdx);
+ this._focusifyCellNode(false);
+ }else {
+ // all col head nodes are hidden - focus the grid
+ this.findAndFocusGridCell();
+ }
+ },
+ blurHeader: function(){
+ dojo.removeClass(this._colHeadNode, this.focusClass);
+ dojo.removeAttr(this.grid.domNode,"aria-activedescendant");
+ // reset contextMenu onto viewsHeaderNode so right mouse on header will invoke (see focusHeader)
+ if (this.headerMenu && this._contextMenuBindNode == this.grid.domNode) {
+ var viewsHeader = this.grid.viewsHeaderNode;
+ this.headerMenu.unBindDomNode(this.grid.domNode);
+ this.headerMenu.bindDomNode(viewsHeader);
+ this._contextMenuBindNode = viewsHeader;
+ }
+ },
+ doFocus: function(e){
+ // trap focus only for grid dom node
+ if(e && e.target != e.currentTarget){
+ dojo.stopEvent(e);
+ return;
+ }
+ // do not focus for scrolling if grid is about to blur
+ if(!this.tabbingOut){
+ this.focusHeader();
+ }
+ this.tabbingOut = false;
+ dojo.stopEvent(e);
+ },
+ doBlur: function(e){
+ dojo.stopEvent(e); // FF2
+ },
+ doContextMenu: function(e){
+ //stop contextMenu event if no header Menu to prevent default/browser contextMenu
+ if (!this.headerMenu){
+ dojo.stopEvent(e);
+ }
+ },
+ doLastNodeFocus: function(e){
+ if (this.tabbingOut){
+ this._focusifyCellNode(false);
+ }else if(this.grid.rowCount >0){
+ if (this.isNoFocusCell()){
+ this.setFocusIndex(0,0);
+ }
+ this._focusifyCellNode(true);
+ }else {
+ this.focusHeader();
+ }
+ this.tabbingOut = false;
+ dojo.stopEvent(e); // FF2
+ },
+ doLastNodeBlur: function(e){
+ dojo.stopEvent(e); // FF2
+ },
+ doColHeaderFocus: function(e){
+ this._setActiveColHeader(e.target,dojo.attr(e.target, "idx"),this._colHeadFocusIdx);
+ this._scrollHeader(this.getHeaderIndex());
+ dojo.stopEvent(e);
+ },
+ doColHeaderBlur: function(e){
+ dojo.toggleClass(e.target, this.focusClass, false);
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._EditManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._EditManager"] = true;
+dojo.provide("dojox.grid._EditManager");
+
+
+
+dojo.declare("dojox.grid._EditManager", null, {
+ // summary:
+ // Controls grid cell editing process. Owned by grid and used internally for editing.
+ constructor: function(inGrid){
+ // inGrid: dojox.Grid
+ // The dojox.Grid this editor should be attached to
+ this.grid = inGrid;
+ if(dojo.isIE){
+ this.connections = [dojo.connect(document.body, "onfocus", dojo.hitch(this, "_boomerangFocus"))];
+ }else{
+ this.connections = [dojo.connect(this.grid, 'onBlur', this, 'apply')];
+ }
+ },
+
+ info: {},
+
+ destroy: function(){
+ dojo.forEach(this.connections,dojo.disconnect);
+ },
+
+ cellFocus: function(inCell, inRowIndex){
+ // summary:
+ // Invoke editing when cell is focused
+ // inCell: cell object
+ // Grid cell object
+ // inRowIndex: Integer
+ // Grid row index
+ if(this.grid.singleClickEdit || this.isEditRow(inRowIndex)){
+ // if same row or quick editing, edit
+ this.setEditCell(inCell, inRowIndex);
+ }else{
+ // otherwise, apply any pending row edits
+ this.apply();
+ }
+ // if dynamic or static editing...
+ if(this.isEditing() || (inCell && inCell.editable && inCell.alwaysEditing)){
+ // let the editor focus itself as needed
+ this._focusEditor(inCell, inRowIndex);
+ }
+ },
+
+ rowClick: function(e){
+ if(this.isEditing() && !this.isEditRow(e.rowIndex)){
+ this.apply();
+ }
+ },
+
+ styleRow: function(inRow){
+ if(inRow.index == this.info.rowIndex){
+ inRow.customClasses += ' dojoxGridRowEditing';
+ }
+ },
+
+ dispatchEvent: function(e){
+ var c = e.cell, ed = (c && c["editable"]) ? c : 0;
+ return ed && ed.dispatchEvent(e.dispatch, e);
+ },
+
+ // Editing
+ isEditing: function(){
+ // summary:
+ // Indicates editing state of the grid.
+ // returns: Boolean
+ // True if grid is actively editing
+ return this.info.rowIndex !== undefined;
+ },
+
+ isEditCell: function(inRowIndex, inCellIndex){
+ // summary:
+ // Indicates if the given cell is being edited.
+ // inRowIndex: Integer
+ // Grid row index
+ // inCellIndex: Integer
+ // Grid cell index
+ // returns: Boolean
+ // True if given cell is being edited
+ return (this.info.rowIndex === inRowIndex) && (this.info.cell.index == inCellIndex);
+ },
+
+ isEditRow: function(inRowIndex){
+ // summary:
+ // Indicates if the given row is being edited.
+ // inRowIndex: Integer
+ // Grid row index
+ // returns: Boolean
+ // True if given row is being edited
+ return this.info.rowIndex === inRowIndex;
+ },
+
+ setEditCell: function(inCell, inRowIndex){
+ // summary:
+ // Set the given cell to be edited
+ // inRowIndex: Integer
+ // Grid row index
+ // inCell: Object
+ // Grid cell object
+ if(!this.isEditCell(inRowIndex, inCell.index) && this.grid.canEdit && this.grid.canEdit(inCell, inRowIndex)){
+ this.start(inCell, inRowIndex, this.isEditRow(inRowIndex) || inCell.editable);
+ }
+ },
+
+ _focusEditor: function(inCell, inRowIndex){
+ dojox.grid.util.fire(inCell, "focus", [inRowIndex]);
+ },
+
+ focusEditor: function(){
+ if(this.isEditing()){
+ this._focusEditor(this.info.cell, this.info.rowIndex);
+ }
+ },
+
+ // implement fix for focus boomerang effect on IE
+ _boomerangWindow: 500,
+ _shouldCatchBoomerang: function(){
+ return this._catchBoomerang > new Date().getTime();
+ },
+ _boomerangFocus: function(){
+ //console.log("_boomerangFocus");
+ if(this._shouldCatchBoomerang()){
+ // make sure we don't utterly lose focus
+ this.grid.focus.focusGrid();
+ // let the editor focus itself as needed
+ this.focusEditor();
+ // only catch once
+ this._catchBoomerang = 0;
+ }
+ },
+ _doCatchBoomerang: function(){
+ // give ourselves a few ms to boomerang IE focus effects
+ if(dojo.isIE){this._catchBoomerang = new Date().getTime() + this._boomerangWindow;}
+ },
+ // end boomerang fix API
+
+ start: function(inCell, inRowIndex, inEditing){
+ this.grid.beginUpdate();
+ this.editorApply();
+ if(this.isEditing() && !this.isEditRow(inRowIndex)){
+ this.applyRowEdit();
+ this.grid.updateRow(inRowIndex);
+ }
+ if(inEditing){
+ this.info = { cell: inCell, rowIndex: inRowIndex };
+ this.grid.doStartEdit(inCell, inRowIndex);
+ this.grid.updateRow(inRowIndex);
+ }else{
+ this.info = {};
+ }
+ this.grid.endUpdate();
+ // make sure we don't utterly lose focus
+ this.grid.focus.focusGrid();
+ // let the editor focus itself as needed
+ this._focusEditor(inCell, inRowIndex);
+ // give ourselves a few ms to boomerang IE focus effects
+ this._doCatchBoomerang();
+ },
+
+ _editorDo: function(inMethod){
+ var c = this.info.cell;
+ //c && c.editor && c.editor[inMethod](c, this.info.rowIndex);
+ if(c && c.editable){
+ c[inMethod](this.info.rowIndex);
+ }
+ },
+
+ editorApply: function(){
+ this._editorDo("apply");
+ },
+
+ editorCancel: function(){
+ this._editorDo("cancel");
+ },
+
+ applyCellEdit: function(inValue, inCell, inRowIndex){
+ if(this.grid.canEdit(inCell, inRowIndex)){
+ this.grid.doApplyCellEdit(inValue, inRowIndex, inCell.field);
+ }
+ },
+
+ applyRowEdit: function(){
+ this.grid.doApplyEdit(this.info.rowIndex, this.info.cell.field);
+ },
+
+ apply: function(){
+ // summary:
+ // Apply a grid edit
+ if(this.isEditing()){
+ this.grid.beginUpdate();
+ this.editorApply();
+ this.applyRowEdit();
+ this.info = {};
+ this.grid.endUpdate();
+ this.grid.focus.focusGrid();
+ this._doCatchBoomerang();
+ }
+ },
+
+ cancel: function(){
+ // summary:
+ // Cancel a grid edit
+ if(this.isEditing()){
+ this.grid.beginUpdate();
+ this.editorCancel();
+ this.info = {};
+ this.grid.endUpdate();
+ this.grid.focus.focusGrid();
+ this._doCatchBoomerang();
+ }
+ },
+
+ save: function(inRowIndex, inView){
+ // summary:
+ // Save the grid editing state
+ // inRowIndex: Integer
+ // Grid row index
+ // inView: Object
+ // Grid view
+ var c = this.info.cell;
+ if(this.isEditRow(inRowIndex) && (!inView || c.view==inView) && c.editable){
+ c.save(c, this.info.rowIndex);
+ }
+ },
+
+ restore: function(inView, inRowIndex){
+ // summary:
+ // Restores the grid editing state
+ // inRowIndex: Integer
+ // Grid row index
+ // inView: Object
+ // Grid view
+ var c = this.info.cell;
+ if(this.isEditRow(inRowIndex) && c.view == inView && c.editable){
+ c.restore(c, this.info.rowIndex);
+ }
+ }
+});
+
+}
+
+if(!dojo._hasResource['dojox.grid.Selection']){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource['dojox.grid.Selection'] = true;
+dojo.provide('dojox.grid.Selection');
+
+dojo.declare("dojox.grid.Selection", null, {
+ // summary:
+ // Manages row selection for grid. Owned by grid and used internally
+ // for selection. Override to implement custom selection.
+
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ this.selected = [];
+
+ this.setMode(inGrid.selectionMode);
+ },
+
+ mode: 'extended',
+
+ selected: null,
+ updating: 0,
+ selectedIndex: -1,
+
+ setMode: function(mode){
+ if(this.selected.length){
+ this.deselectAll();
+ }
+ if(mode != 'extended' && mode != 'multiple' && mode != 'single' && mode != 'none'){
+ this.mode = 'extended';
+ }else{
+ this.mode = mode;
+ }
+ },
+
+ onCanSelect: function(inIndex){
+ return this.grid.onCanSelect(inIndex);
+ },
+
+ onCanDeselect: function(inIndex){
+ return this.grid.onCanDeselect(inIndex);
+ },
+
+ onSelected: function(inIndex){
+ },
+
+ onDeselected: function(inIndex){
+ },
+
+ //onSetSelected: function(inIndex, inSelect) { };
+ onChanging: function(){
+ },
+
+ onChanged: function(){
+ },
+
+ isSelected: function(inIndex){
+ if(this.mode == 'none'){
+ return false;
+ }
+ return this.selected[inIndex];
+ },
+
+ getFirstSelected: function(){
+ if(!this.selected.length||this.mode == 'none'){ return -1; }
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ getNextSelected: function(inPrev){
+ if(this.mode == 'none'){ return -1; }
+ for(var i=inPrev+1, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ getSelected: function(){
+ var result = [];
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ result.push(i);
+ }
+ }
+ return result;
+ },
+
+ getSelectedCount: function(){
+ var c = 0;
+ for(var i=0; i<this.selected.length; i++){
+ if(this.selected[i]){
+ c++;
+ }
+ }
+ return c;
+ },
+
+ _beginUpdate: function(){
+ if(this.updating === 0){
+ this.onChanging();
+ }
+ this.updating++;
+ },
+
+ _endUpdate: function(){
+ this.updating--;
+ if(this.updating === 0){
+ this.onChanged();
+ }
+ },
+
+ select: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(this.mode != 'multiple'){
+ this.deselectAll(inIndex);
+ this.addToSelection(inIndex);
+ }else{
+ this.toggleSelect(inIndex);
+ }
+ },
+
+ addToSelection: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(dojo.isArray(inIndex)){
+ dojo.forEach(inIndex, this.addToSelection, this);
+ return;
+ }
+ inIndex = Number(inIndex);
+ if(this.selected[inIndex]){
+ this.selectedIndex = inIndex;
+ }else{
+ if(this.onCanSelect(inIndex) !== false){
+ this.selectedIndex = inIndex;
+ var rowNode = this.grid.getRowNode(inIndex);
+ if(rowNode){
+ dojo.attr(rowNode,"aria-selected","true");
+ }
+ this._beginUpdate();
+ this.selected[inIndex] = true;
+ //this.grid.onSelected(inIndex);
+ this.onSelected(inIndex);
+ //this.onSetSelected(inIndex, true);
+ this._endUpdate();
+ }
+ }
+ },
+
+ deselect: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(dojo.isArray(inIndex)){
+ dojo.forEach(inIndex, this.deselect, this);
+ return;
+ }
+ inIndex = Number(inIndex);
+ if(this.selectedIndex == inIndex){
+ this.selectedIndex = -1;
+ }
+ if(this.selected[inIndex]){
+ if(this.onCanDeselect(inIndex) === false){
+ return;
+ }
+ var rowNode = this.grid.getRowNode(inIndex);
+ if(rowNode){
+ dojo.attr(rowNode,"aria-selected","false");
+ }
+ this._beginUpdate();
+ delete this.selected[inIndex];
+ //this.grid.onDeselected(inIndex);
+ this.onDeselected(inIndex);
+ //this.onSetSelected(inIndex, false);
+ this._endUpdate();
+ }
+ },
+
+ setSelected: function(inIndex, inSelect){
+ this[(inSelect ? 'addToSelection' : 'deselect')](inIndex);
+ },
+
+ toggleSelect: function(inIndex){
+ if(dojo.isArray(inIndex)){
+ dojo.forEach(inIndex, this.toggleSelect, this);
+ return;
+ }
+ this.setSelected(inIndex, !this.selected[inIndex]);
+ },
+
+ _range: function(inFrom, inTo, func){
+ var s = (inFrom >= 0 ? inFrom : inTo), e = inTo;
+ if(s > e){
+ e = s;
+ s = inTo;
+ }
+ for(var i=s; i<=e; i++){
+ func(i);
+ }
+ },
+
+ selectRange: function(inFrom, inTo){
+ this._range(inFrom, inTo, dojo.hitch(this, "addToSelection"));
+ },
+
+ deselectRange: function(inFrom, inTo){
+ this._range(inFrom, inTo, dojo.hitch(this, "deselect"));
+ },
+
+ insert: function(inIndex){
+ this.selected.splice(inIndex, 0, false);
+ if(this.selectedIndex >= inIndex){
+ this.selectedIndex++;
+ }
+ },
+
+ remove: function(inIndex){
+ this.selected.splice(inIndex, 1);
+ if(this.selectedIndex >= inIndex){
+ this.selectedIndex--;
+ }
+ },
+
+ deselectAll: function(inExcept){
+ for(var i in this.selected){
+ if((i!=inExcept)&&(this.selected[i]===true)){
+ this.deselect(i);
+ }
+ }
+ },
+
+ clickSelect: function(inIndex, inCtrlKey, inShiftKey){
+ if(this.mode == 'none'){ return; }
+ this._beginUpdate();
+ if(this.mode != 'extended'){
+ this.select(inIndex);
+ }else{
+ var lastSelected = this.selectedIndex;
+ if(!inCtrlKey){
+ this.deselectAll(inIndex);
+ }
+ if(inShiftKey){
+ this.selectRange(lastSelected, inIndex);
+ }else if(inCtrlKey){
+ this.toggleSelect(inIndex);
+ }else{
+ this.addToSelection(inIndex);
+ }
+ }
+ this._endUpdate();
+ },
+
+ clickSelectEvent: function(e){
+ this.clickSelect(e.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ },
+
+ clear: function(){
+ this._beginUpdate();
+ this.deselectAll();
+ this._endUpdate();
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._Events"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Events"] = true;
+dojo.provide("dojox.grid._Events");
+
+dojo.declare("dojox.grid._Events", null, {
+ // summary:
+ // _Grid mixin that provides default implementations for grid events.
+ // description:
+ // Default synthetic events dispatched for _Grid. dojo.connect to events to
+ // retain default implementation or override them for custom handling.
+
+ // cellOverClass: String
+ // css class to apply to grid cells over which the cursor is placed.
+ cellOverClass: "dojoxGridCellOver",
+
+ onKeyEvent: function(e){
+ // summary: top level handler for Key Events
+ this.dispatchKeyEvent(e);
+ },
+
+ onContentEvent: function(e){
+ // summary: Top level handler for Content events
+ this.dispatchContentEvent(e);
+ },
+
+ onHeaderEvent: function(e){
+ // summary: Top level handler for header events
+ this.dispatchHeaderEvent(e);
+ },
+
+ onStyleRow: function(inRow){
+ // summary:
+ // Perform row styling on a given row. Called whenever row styling is updated.
+ //
+ // inRow: Object
+ // Object containing row state information: selected, true if the row is selcted; over:
+ // true of the mouse is over the row; odd: true if the row is odd. Use customClasses and
+ // customStyles to control row css classes and styles; both properties are strings.
+ //
+ // example: onStyleRow({ selected: true, over:true, odd:false })
+ var i = inRow;
+ i.customClasses += (i.odd?" dojoxGridRowOdd":"") + (i.selected?" dojoxGridRowSelected":"") + (i.over?" dojoxGridRowOver":"");
+ this.focus.styleRow(inRow);
+ this.edit.styleRow(inRow);
+ },
+
+ onKeyDown: function(e){
+ // summary:
+ // Grid key event handler. By default enter begins editing and applies edits, escape cancels an edit,
+ // tab, shift-tab, and arrow keys move grid cell focus.
+ if(e.altKey || e.metaKey){
+ return;
+ }
+ var dk = dojo.keys;
+ var colIdx;
+ switch(e.keyCode){
+ case dk.ESCAPE:
+ this.edit.cancel();
+ break;
+ case dk.ENTER:
+ if(!this.edit.isEditing()){
+ colIdx = this.focus.getHeaderIndex();
+ if(colIdx >= 0) {
+ this.setSortIndex(colIdx);
+ break;
+ }else {
+ this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ }
+ dojo.stopEvent(e);
+ }
+ if(!e.shiftKey){
+ var isEditing = this.edit.isEditing();
+ this.edit.apply();
+ if(!isEditing){
+ this.edit.setEditCell(this.focus.cell, this.focus.rowIndex);
+ }
+ }
+ if (!this.edit.isEditing()){
+ var curView = this.focus.focusView || this.views.views[0]; //if no focusView than only one view
+ curView.content.decorateEvent(e);
+ this.onRowClick(e);
+ }
+ break;
+ case dk.SPACE:
+ if(!this.edit.isEditing()){
+ colIdx = this.focus.getHeaderIndex();
+ if(colIdx >= 0) {
+ this.setSortIndex(colIdx);
+ break;
+ }else {
+ this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ }
+ dojo.stopEvent(e);
+ }
+ break;
+ case dk.TAB:
+ this.focus[e.shiftKey ? 'previousKey' : 'nextKey'](e);
+ break;
+ case dk.LEFT_ARROW:
+ case dk.RIGHT_ARROW:
+ if(!this.edit.isEditing()){
+ var keyCode = e.keyCode; // IE seems to lose after stopEvent when modifier keys
+ dojo.stopEvent(e);
+ colIdx = this.focus.getHeaderIndex();
+ if (colIdx >= 0 && (e.shiftKey && e.ctrlKey)){
+ this.focus.colSizeAdjust(e, colIdx, (keyCode == dk.LEFT_ARROW ? -1 : 1)*5);
+ }
+ else{
+ var offset = (keyCode == dk.LEFT_ARROW) ? 1 : -1;
+ if(dojo._isBodyLtr()){ offset *= -1; }
+ this.focus.move(0, offset);
+ }
+ }
+ break;
+ case dk.UP_ARROW:
+ if(!this.edit.isEditing() && this.focus.rowIndex !== 0){
+ dojo.stopEvent(e);
+ this.focus.move(-1, 0);
+ }
+ break;
+ case dk.DOWN_ARROW:
+ if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){
+ dojo.stopEvent(e);
+ this.focus.move(1, 0);
+ }
+ break;
+ case dk.PAGE_UP:
+ if(!this.edit.isEditing() && this.focus.rowIndex !== 0){
+ dojo.stopEvent(e);
+ if(this.focus.rowIndex != this.scroller.firstVisibleRow+1){
+ this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex, 0);
+ }else{
+ this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1));
+ this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1, 0);
+ }
+ }
+ break;
+ case dk.PAGE_DOWN:
+ if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){
+ dojo.stopEvent(e);
+ if(this.focus.rowIndex != this.scroller.lastVisibleRow-1){
+ this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1, 0);
+ }else{
+ this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1));
+ this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1, 0);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ },
+
+ onMouseOver: function(e){
+ // summary:
+ // Event fired when mouse is over the grid.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseOver(e) : this.onCellMouseOver(e);
+ },
+
+ onMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of the grid.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseOut(e) : this.onCellMouseOut(e);
+ },
+
+ onMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down inside grid.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseDown(e) : this.onCellMouseDown(e);
+ },
+
+ onMouseOverRow: function(e){
+ // summary:
+ // Event fired when mouse is over any row (data or header).
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(!this.rows.isOver(e.rowIndex)){
+ this.rows.setOverRow(e.rowIndex);
+ e.rowIndex == -1 ? this.onHeaderMouseOver(e) : this.onRowMouseOver(e);
+ }
+ },
+ onMouseOutRow: function(e){
+ // summary:
+ // Event fired when mouse moves out of any row (data or header).
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(this.rows.isOver(-1)){
+ this.onHeaderMouseOut(e);
+ }else if(!this.rows.isOver(-2)){
+ this.rows.setOverRow(-2);
+ this.onRowMouseOut(e);
+ }
+ },
+
+ onMouseDownRow: function(e){
+ // summary:
+ // Event fired when mouse is down inside grid row
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ if(e.rowIndex != -1)
+ this.onRowMouseDown(e);
+ },
+
+ // cell events
+ onCellMouseOver: function(e){
+ // summary:
+ // Event fired when mouse is over a cell.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ dojo.addClass(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onCellMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ dojo.removeClass(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onCellMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down in a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onCellClick: function(e){
+ // summary:
+ // Event fired when a cell is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this._click[0] = this._click[1];
+ this._click[1] = e;
+ if(!this.edit.isEditCell(e.rowIndex, e.cellIndex)){
+ this.focus.setFocusCell(e.cell, e.rowIndex);
+ }
+ this.onRowClick(e);
+ },
+
+ onCellDblClick: function(e){
+ // summary:
+ // Event fired when a cell is double-clicked.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(this._click.length > 1 && dojo.isIE){
+ this.edit.setEditCell(this._click[1].cell, this._click[1].rowIndex);
+ }else if(this._click.length > 1 && this._click[0].rowIndex != this._click[1].rowIndex){
+ this.edit.setEditCell(this._click[0].cell, this._click[0].rowIndex);
+ }else{
+ this.edit.setEditCell(e.cell, e.rowIndex);
+ }
+ this.onRowDblClick(e);
+ },
+
+ onCellContextMenu: function(e){
+ // summary:
+ // Event fired when a cell context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onRowContextMenu(e);
+ },
+
+ onCellFocus: function(inCell, inRowIndex){
+ // summary:
+ // Event fired when a cell receives focus.
+ // inCell: Object
+ // Cell object containing properties of the grid column.
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.edit.cellFocus(inCell, inRowIndex);
+ },
+
+ // row events
+ onRowClick: function(e){
+ // summary:
+ // Event fired when a row is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.edit.rowClick(e);
+ this.selection.clickSelectEvent(e);
+ },
+
+ onRowDblClick: function(e){
+ // summary:
+ // Event fired when a row is double clicked.
+ // e: Event
+ // decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over a data row.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a data row.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down in a row.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowContextMenu: function(e){
+ // summary:
+ // Event fired when a row context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ dojo.stopEvent(e);
+ },
+
+ // header events
+ onHeaderMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over the grid header.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of the grid header.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ dojo.addClass(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onHeaderCellMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ dojo.removeClass(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onHeaderCellMouseDown: function(e) {
+ // summary:
+ // Event fired when mouse is down in a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderClick: function(e){
+ // summary:
+ // Event fired when the grid header is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellClick: function(e){
+ // summary:
+ // Event fired when a header cell is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.setSortIndex(e.cell.index);
+ this.onHeaderClick(e);
+ },
+
+ onHeaderDblClick: function(e){
+ // summary:
+ // Event fired when the grid header is double clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellDblClick: function(e){
+ // summary:
+ // Event fired when a header cell is double clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onHeaderDblClick(e);
+ },
+
+ onHeaderCellContextMenu: function(e){
+ // summary:
+ // Event fired when a header cell context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onHeaderContextMenu(e);
+ },
+
+ onHeaderContextMenu: function(e){
+ // summary:
+ // Event fired when the grid header context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(!this.headerMenu){
+ dojo.stopEvent(e);
+ }
+ },
+
+ // editing
+ onStartEdit: function(inCell, inRowIndex){
+ // summary:
+ // Event fired when editing is started for a given grid cell
+ // inCell: Object
+ // Cell object containing properties of the grid column.
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
+ // summary:
+ // Event fired when editing is applied for a given grid cell
+ // inValue: String
+ // Value from cell editor
+ // inRowIndex: Integer
+ // Index of the grid row
+ // inFieldIndex: Integer
+ // Index in the grid's data store
+ },
+
+ onCancelEdit: function(inRowIndex){
+ // summary:
+ // Event fired when editing is cancelled for a given grid cell
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onApplyEdit: function(inRowIndex){
+ // summary:
+ // Event fired when editing is applied for a given grid row
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onCanSelect: function(inRowIndex){
+ // summary:
+ // Event to determine if a grid row may be selected
+ // inRowIndex: Integer
+ // Index of the grid row
+ // returns: Boolean
+ // true if the row can be selected
+ return true;
+ },
+
+ onCanDeselect: function(inRowIndex){
+ // summary:
+ // Event to determine if a grid row may be deselected
+ // inRowIndex: Integer
+ // Index of the grid row
+ // returns: Boolean
+ // true if the row can be deselected
+ return true;
+ },
+
+ onSelected: function(inRowIndex){
+ // summary:
+ // Event fired when a grid row is selected
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.updateRowStyles(inRowIndex);
+ },
+
+ onDeselected: function(inRowIndex){
+ // summary:
+ // Event fired when a grid row is deselected
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.updateRowStyles(inRowIndex);
+ },
+
+ onSelectionChanged: function(){
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojo.i18n"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.i18n"] = true;
+dojo.provide("dojo.i18n");
+
+
+dojo.getObject("i18n", true, dojo);
+
+/*=====
+dojo.i18n = {
+ // summary: Utility classes to enable loading of resources for internationalization (i18n)
+};
+=====*/
+
+// when using a real AMD loader, dojo.i18n.getLocalization is already defined by dojo/lib/backCompat
+dojo.i18n.getLocalization = dojo.i18n.getLocalization || function(/*String*/packageName, /*String*/bundleName, /*String?*/locale){
+ // summary:
+ // Returns an Object containing the localization for a given resource
+ // bundle in a package, matching the specified locale.
+ // description:
+ // Returns a hash containing name/value pairs in its prototypesuch
+ // that values can be easily overridden. Throws an exception if the
+ // bundle is not found. Bundle must have already been loaded by
+ // `dojo.requireLocalization()` or by a build optimization step. NOTE:
+ // try not to call this method as part of an object property
+ // definition (`var foo = { bar: dojo.i18n.getLocalization() }`). In
+ // some loading situations, the bundle may not be available in time
+ // for the object definition. Instead, call this method inside a
+ // function that is run after all modules load or the page loads (like
+ // in `dojo.addOnLoad()`), or in a widget lifecycle method.
+ // packageName:
+ // package which is associated with this resource
+ // bundleName:
+ // the base filename of the resource bundle (without the ".js" suffix)
+ // locale:
+ // the variant to load (optional). By default, the locale defined by
+ // the host environment: dojo.locale
+
+ locale = dojo.i18n.normalizeLocale(locale);
+
+ // look for nearest locale match
+ var elements = locale.split('-');
+ var module = [packageName,"nls",bundleName].join('.');
+ var bundle = dojo._loadedModules[module];
+ if(bundle){
+ var localization;
+ for(var i = elements.length; i > 0; i--){
+ var loc = elements.slice(0, i).join('_');
+ if(bundle[loc]){
+ localization = bundle[loc];
+ break;
+ }
+ }
+ if(!localization){
+ localization = bundle.ROOT;
+ }
+
+ // make a singleton prototype so that the caller won't accidentally change the values globally
+ if(localization){
+ var clazz = function(){};
+ clazz.prototype = localization;
+ return new clazz(); // Object
+ }
+ }
+
+ throw new Error("Bundle not found: " + bundleName + " in " + packageName+" , locale=" + locale);
+};
+
+dojo.i18n.normalizeLocale = function(/*String?*/locale){
+ // summary:
+ // Returns canonical form of locale, as used by Dojo.
+ //
+ // description:
+ // All variants are case-insensitive and are separated by '-' as specified in [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
+ // If no locale is specified, the dojo.locale is returned. dojo.locale is defined by
+ // the user agent's locale unless overridden by djConfig.
+
+ var result = locale ? locale.toLowerCase() : dojo.locale;
+ if(result == "root"){
+ result = "ROOT";
+ }
+ return result; // String
+};
+
+dojo.i18n._requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String?*/availableFlatLocales){
+ // summary:
+ // See dojo.requireLocalization()
+ // description:
+ // Called by the bootstrap, but factored out so that it is only
+ // included in the build when needed.
+
+ var targetLocale = dojo.i18n.normalizeLocale(locale);
+ var bundlePackage = [moduleName, "nls", bundleName].join(".");
+ // NOTE:
+ // When loading these resources, the packaging does not match what is
+ // on disk. This is an implementation detail, as this is just a
+ // private data structure to hold the loaded resources. e.g.
+ // `tests/hello/nls/en-us/salutations.js` is loaded as the object
+ // `tests.hello.nls.salutations.en_us={...}` The structure on disk is
+ // intended to be most convenient for developers and translators, but
+ // in memory it is more logical and efficient to store in a different
+ // order. Locales cannot use dashes, since the resulting path will
+ // not evaluate as valid JS, so we translate them to underscores.
+
+ //Find the best-match locale to load if we have available flat locales.
+ var bestLocale = "";
+ if(availableFlatLocales){
+ var flatLocales = availableFlatLocales.split(",");
+ for(var i = 0; i < flatLocales.length; i++){
+ //Locale must match from start of string.
+ //Using ["indexOf"] so customBase builds do not see
+ //this as a dojo._base.array dependency.
+ if(targetLocale["indexOf"](flatLocales[i]) == 0){
+ if(flatLocales[i].length > bestLocale.length){
+ bestLocale = flatLocales[i];
+ }
+ }
+ }
+ if(!bestLocale){
+ bestLocale = "ROOT";
+ }
+ }
+
+ //See if the desired locale is already loaded.
+ var tempLocale = availableFlatLocales ? bestLocale : targetLocale;
+ var bundle = dojo._loadedModules[bundlePackage];
+ var localizedBundle = null;
+ if(bundle){
+ if(dojo.config.localizationComplete && bundle._built){return;}
+ var jsLoc = tempLocale.replace(/-/g, '_');
+ var translationPackage = bundlePackage+"."+jsLoc;
+ localizedBundle = dojo._loadedModules[translationPackage];
+ }
+
+ if(!localizedBundle){
+ bundle = dojo["provide"](bundlePackage);
+ var syms = dojo._getModuleSymbols(moduleName);
+ var modpath = syms.concat("nls").join("/");
+ var parent;
+
+ dojo.i18n._searchLocalePath(tempLocale, availableFlatLocales, function(loc){
+ var jsLoc = loc.replace(/-/g, '_');
+ var translationPackage = bundlePackage + "." + jsLoc;
+ var loaded = false;
+ if(!dojo._loadedModules[translationPackage]){
+ // Mark loaded whether it's found or not, so that further load attempts will not be made
+ dojo["provide"](translationPackage);
+ var module = [modpath];
+ if(loc != "ROOT"){module.push(loc);}
+ module.push(bundleName);
+ var filespec = module.join("/") + '.js';
+ loaded = dojo._loadPath(filespec, null, function(hash){
+ hash = hash.root || hash;
+ // Use singleton with prototype to point to parent bundle, then mix-in result from loadPath
+ var clazz = function(){};
+ clazz.prototype = parent;
+ bundle[jsLoc] = new clazz();
+ for(var j in hash){ bundle[jsLoc][j] = hash[j]; }
+ });
+ }else{
+ loaded = true;
+ }
+ if(loaded && bundle[jsLoc]){
+ parent = bundle[jsLoc];
+ }else{
+ bundle[jsLoc] = parent;
+ }
+
+ if(availableFlatLocales){
+ //Stop the locale path searching if we know the availableFlatLocales, since
+ //the first call to this function will load the only bundle that is needed.
+ return true;
+ }
+ });
+ }
+
+ //Save the best locale bundle as the target locale bundle when we know the
+ //the available bundles.
+ if(availableFlatLocales && targetLocale != bestLocale){
+ bundle[targetLocale.replace(/-/g, '_')] = bundle[bestLocale.replace(/-/g, '_')];
+ }
+};
+
+(function(){
+ // If other locales are used, dojo.requireLocalization should load them as
+ // well, by default.
+ //
+ // Override dojo.requireLocalization to do load the default bundle, then
+ // iterate through the extraLocale list and load those translations as
+ // well, unless a particular locale was requested.
+
+ var extra = dojo.config.extraLocale;
+ if(extra){
+ if(!extra instanceof Array){
+ extra = [extra];
+ }
+
+ var req = dojo.i18n._requireLocalization;
+ dojo.i18n._requireLocalization = function(m, b, locale, availableFlatLocales){
+ req(m,b,locale, availableFlatLocales);
+ if(locale){return;}
+ for(var i=0; i<extra.length; i++){
+ req(m,b,extra[i], availableFlatLocales);
+ }
+ };
+ }
+})();
+
+dojo.i18n._searchLocalePath = function(/*String*/locale, /*Boolean*/down, /*Function*/searchFunc){
+ // summary:
+ // A helper method to assist in searching for locale-based resources.
+ // Will iterate through the variants of a particular locale, either up
+ // or down, executing a callback function. For example, "en-us" and
+ // true will try "en-us" followed by "en" and finally "ROOT".
+
+ locale = dojo.i18n.normalizeLocale(locale);
+
+ var elements = locale.split('-');
+ var searchlist = [];
+ for(var i = elements.length; i > 0; i--){
+ searchlist.push(elements.slice(0, i).join('-'));
+ }
+ searchlist.push(false);
+ if(down){searchlist.reverse();}
+
+ for(var j = searchlist.length - 1; j >= 0; j--){
+ var loc = searchlist[j] || "ROOT";
+ var stop = searchFunc(loc);
+ if(stop){ break; }
+ }
+};
+
+dojo.i18n._preloadLocalizations = function(/*String*/bundlePrefix, /*Array*/localesGenerated){
+ // summary:
+ // Load built, flattened resource bundles, if available for all
+ // locales used in the page. Only called by built layer files.
+
+ function preload(locale){
+ locale = dojo.i18n.normalizeLocale(locale);
+ dojo.i18n._searchLocalePath(locale, true, function(loc){
+ for(var i=0; i<localesGenerated.length;i++){
+ if(localesGenerated[i] == loc){
+ dojo["require"](bundlePrefix+"_"+loc);
+ return true; // Boolean
+ }
+ }
+ return false; // Boolean
+ });
+ }
+ preload();
+ var extra = dojo.config.extraLocale||[];
+ for(var i=0; i<extra.length; i++){
+ preload(extra[i]);
+ }
+};
+
+}
+
+if(!dojo._hasResource["dojox.grid._Grid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Grid"] = true;
+dojo.provide("dojox.grid._Grid");
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+(function(){
+ // NOTE: this is for backwards compatibility with Dojo 1.3
+ if(!dojo.isCopyKey){
+ dojo.isCopyKey = dojo.dnd.getCopyKeyState;
+ }
+ /*=====
+ dojox.grid.__CellDef = function(){
+ // name: String?
+ // The text to use in the header of the grid for this cell.
+ // get: Function?
+ // function(rowIndex){} rowIndex is of type Integer. This
+ // function will be called when a cell requests data. Returns the
+ // unformatted data for the cell.
+ // value: String?
+ // If "get" is not specified, this is used as the data for the cell.
+ // defaultValue: String?
+ // If "get" and "value" aren't specified or if "get" returns an undefined
+ // value, this is used as the data for the cell. "formatter" is not run
+ // on this if "get" returns an undefined value.
+ // formatter: Function?
+ // function(data, rowIndex){} data is of type anything, rowIndex
+ // is of type Integer. This function will be called after the cell
+ // has its data but before it passes it back to the grid to render.
+ // Returns the formatted version of the cell's data.
+ // type: dojox.grid.cells._Base|Function?
+ // TODO
+ // editable: Boolean?
+ // Whether this cell should be editable or not.
+ // hidden: Boolean?
+ // If true, the cell will not be displayed.
+ // noresize: Boolean?
+ // If true, the cell will not be able to be resized.
+ // width: Integer|String?
+ // A CSS size. If it's an Integer, the width will be in em's.
+ // colSpan: Integer?
+ // How many columns to span this cell. Will not work in the first
+ // sub-row of cells.
+ // rowSpan: Integer?
+ // How many sub-rows to span this cell.
+ // styles: String?
+ // A string of styles to apply to both the header cell and main
+ // grid cells. Must end in a ';'.
+ // headerStyles: String?
+ // A string of styles to apply to just the header cell. Must end
+ // in a ';'
+ // cellStyles: String?
+ // A string of styles to apply to just the main grid cells. Must
+ // end in a ';'
+ // classes: String?
+ // A space separated list of classes to apply to both the header
+ // cell and the main grid cells.
+ // headerClasses: String?
+ // A space separated list of classes to apply to just the header
+ // cell.
+ // cellClasses: String?
+ // A space separated list of classes to apply to just the main
+ // grid cells.
+ // attrs: String?
+ // A space separated string of attribute='value' pairs to add to
+ // the header cell element and main grid cell elements.
+ this.name = name;
+ this.value = value;
+ this.get = get;
+ this.formatter = formatter;
+ this.type = type;
+ this.editable = editable;
+ this.hidden = hidden;
+ this.width = width;
+ this.colSpan = colSpan;
+ this.rowSpan = rowSpan;
+ this.styles = styles;
+ this.headerStyles = headerStyles;
+ this.cellStyles = cellStyles;
+ this.classes = classes;
+ this.headerClasses = headerClasses;
+ this.cellClasses = cellClasses;
+ this.attrs = attrs;
+ }
+ =====*/
+
+ /*=====
+ dojox.grid.__ViewDef = function(){
+ // noscroll: Boolean?
+ // If true, no scrollbars will be rendered without scrollbars.
+ // width: Integer|String?
+ // A CSS size. If it's an Integer, the width will be in em's. If
+ // "noscroll" is true, this value is ignored.
+ // cells: dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]?
+ // The structure of the cells within this grid.
+ // type: String?
+ // A string containing the constructor of a subclass of
+ // dojox.grid._View. If this is not specified, dojox.grid._View
+ // is used.
+ // defaultCell: dojox.grid.__CellDef?
+ // A cell definition with default values for all cells in this view. If
+ // a property is defined in a cell definition in the "cells" array and
+ // this property, the cell definition's property will override this
+ // property's property.
+ // onBeforeRow: Function?
+ // function(rowIndex, cells){} rowIndex is of type Integer, cells
+ // is of type Array[dojox.grid.__CellDef[]]. This function is called
+ // before each row of data is rendered. Before the header is
+ // rendered, rowIndex will be -1. "cells" is a reference to the
+ // internal structure of this view's cells so any changes you make to
+ // it will persist between calls.
+ // onAfterRow: Function?
+ // function(rowIndex, cells, rowNode){} rowIndex is of type Integer, cells
+ // is of type Array[dojox.grid.__CellDef[]], rowNode is of type DOMNode.
+ // This function is called after each row of data is rendered. After the
+ // header is rendered, rowIndex will be -1. "cells" is a reference to the
+ // internal structure of this view's cells so any changes you make to
+ // it will persist between calls.
+ this.noscroll = noscroll;
+ this.width = width;
+ this.cells = cells;
+ this.type = type;
+ this.defaultCell = defaultCell;
+ this.onBeforeRow = onBeforeRow;
+ this.onAfterRow = onAfterRow;
+ }
+ =====*/
+
+ dojo.declare('dojox.grid._Grid',
+ [ dijit._Widget, dijit._Templated, dojox.grid._Events ],
+ {
+ // summary:
+ // A grid widget with virtual scrolling, cell editing, complex rows,
+ // sorting, fixed columns, sizeable columns, etc.
+ //
+ // description:
+ // _Grid provides the full set of grid features without any
+ // direct connection to a data store.
+ //
+ // The grid exposes a get function for the grid, or optionally
+ // individual columns, to populate cell contents.
+ //
+ // The grid is rendered based on its structure, an object describing
+ // column and cell layout.
+ //
+ // example:
+ // A quick sample:
+ //
+ // define a get function
+ // | function get(inRowIndex){ // called in cell context
+ // | return [this.index, inRowIndex].join(', ');
+ // | }
+ //
+ // define the grid structure:
+ // | var structure = [ // array of view objects
+ // | { cells: [// array of rows, a row is an array of cells
+ // | [
+ // | { name: "Alpha", width: 6 },
+ // | { name: "Beta" },
+ // | { name: "Gamma", get: get }]
+ // | ]}
+ // | ];
+ //
+ // | <div id="grid"
+ // | rowCount="100" get="get"
+ // | structure="structure"
+ // | dojoType="dojox.grid._Grid"></div>
+
+ templateString:"<div hidefocus=\"hidefocus\" role=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\r\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" role=\"presentation\"></div>\r\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" role=\"presentation\"></div>\r\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\r\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\r\n</div>\r\n",
+
+ // classTag: String
+ // CSS class applied to the grid's domNode
+ classTag: 'dojoxGrid',
+
+ // settings
+ // rowCount: Integer
+ // Number of rows to display.
+ rowCount: 5,
+
+ // keepRows: Integer
+ // Number of rows to keep in the rendering cache.
+ keepRows: 75,
+
+ // rowsPerPage: Integer
+ // Number of rows to render at a time.
+ rowsPerPage: 25,
+
+ // autoWidth: Boolean
+ // If autoWidth is true, grid width is automatically set to fit the data.
+ autoWidth: false,
+
+ // initialWidth: String
+ // A css string to use to set our initial width (only used if autoWidth
+ // is true). The first rendering of the grid will be this width, any
+ // resizing of columns, etc will result in the grid switching to
+ // autoWidth mode. Note, this width will override any styling in a
+ // stylesheet or directly on the node.
+ initialWidth: "",
+
+ // autoHeight: Boolean|Integer
+ // If autoHeight is true, grid height is automatically set to fit the data.
+ // If it is an integer, the height will be automatically set to fit the data
+ // if there are fewer than that many rows - and the height will be set to show
+ // that many rows if there are more
+ autoHeight: '',
+
+ // rowHeight: Integer
+ // If rowHeight is set to a positive number, it will define the height of the rows
+ // in pixels. This can provide a significant performance advantage, since it
+ // eliminates the need to measure row sizes during rendering, which is one
+ // the primary bottlenecks in the DataGrid's performance.
+ rowHeight: 0,
+
+ // autoRender: Boolean
+ // If autoRender is true, grid will render itself after initialization.
+ autoRender: true,
+
+ // defaultHeight: String
+ // default height of the grid, measured in any valid css unit.
+ defaultHeight: '15em',
+
+ // height: String
+ // explicit height of the grid, measured in any valid css unit. This will be populated (and overridden)
+ // if the height: css attribute exists on the source node.
+ height: '',
+
+ // structure: dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]
+ // View layout defintion.
+ structure: null,
+
+ // elasticView: Integer
+ // Override defaults and make the indexed grid view elastic, thus filling available horizontal space.
+ elasticView: -1,
+
+ // singleClickEdit: boolean
+ // Single-click starts editing. Default is double-click
+ singleClickEdit: false,
+
+ // selectionMode: String
+ // Set the selection mode of grid's Selection. Value must be 'single', 'multiple',
+ // or 'extended'. Default is 'extended'.
+ selectionMode: 'extended',
+
+ // rowSelector: Boolean|String
+ // If set to true, will add a row selector view to this grid. If set to a CSS width, will add
+ // a row selector of that width to this grid.
+ rowSelector: '',
+
+ // columnReordering: Boolean
+ // If set to true, will add drag and drop reordering to views with one row of columns.
+ columnReordering: false,
+
+ // headerMenu: dijit.Menu
+ // If set to a dijit.Menu, will use this as a context menu for the grid headers.
+ headerMenu: null,
+
+ // placeholderLabel: String
+ // Label of placeholders to search for in the header menu to replace with column toggling
+ // menu items.
+ placeholderLabel: "GridColumns",
+
+ // selectable: Boolean
+ // Set to true if you want to be able to select the text within the grid.
+ selectable: false,
+
+ // Used to store the last two clicks, to ensure double-clicking occurs based on the intended row
+ _click: null,
+
+ // loadingMessage: String
+ // Message that shows while the grid is loading
+ loadingMessage: "<span class='dojoxGridLoading'>${loadingState}</span>",
+
+ // errorMessage: String
+ // Message that shows when the grid encounters an error loading
+ errorMessage: "<span class='dojoxGridError'>${errorState}</span>",
+
+ // noDataMessage: String
+ // Message that shows if the grid has no data - wrap it in a
+ // span with class 'dojoxGridNoData' if you want it to be
+ // styled similar to the loading and error messages
+ noDataMessage: "",
+
+ // escapeHTMLInData: Boolean
+ // This will escape HTML brackets from the data to prevent HTML from
+ // user-inputted data being rendered with may contain JavaScript and result in
+ // XSS attacks. This is true by default, and it is recommended that it remain
+ // true. Setting this to false will allow data to be displayed in the grid without
+ // filtering, and should be only used if it is known that the data won't contain
+ // malicious scripts. If HTML is needed in grid cells, it is recommended that
+ // you use the formatter function to generate the HTML (the output of
+ // formatter functions is not filtered, even with escapeHTMLInData set to true).
+ escapeHTMLInData: true,
+
+ // formatterScope: Object
+ // An object to execute format functions within. If not set, the
+ // format functions will execute within the scope of the cell that
+ // has a format function.
+ formatterScope: null,
+
+ // editable: boolean
+ // indicates if the grid contains editable cells, default is false
+ // set to true if editable cell encountered during rendering
+ editable: false,
+
+ // private
+ sortInfo: 0,
+ themeable: true,
+ _placeholders: null,
+
+ // _layoutClass: Object
+ // The class to use for our layout - can be overridden by grid subclasses
+ _layoutClass: dojox.grid._Layout,
+
+ // initialization
+ buildRendering: function(){
+ this.inherited(arguments);
+ if(!this.domNode.getAttribute('tabIndex')){
+ this.domNode.tabIndex = "0";
+ }
+ this.createScroller();
+ this.createLayout();
+ this.createViews();
+ this.createManagers();
+
+ this.createSelection();
+
+ this.connect(this.selection, "onSelected", "onSelected");
+ this.connect(this.selection, "onDeselected", "onDeselected");
+ this.connect(this.selection, "onChanged", "onSelectionChanged");
+
+ dojox.html.metrics.initOnFontResize();
+ this.connect(dojox.html.metrics, "onFontResize", "textSizeChanged");
+ dojox.grid.util.funnelEvents(this.domNode, this, 'doKeyEvent', dojox.grid.util.keyEvents);
+ if (this.selectionMode != "none") {
+ dojo.attr(this.domNode, "aria-multiselectable", this.selectionMode == "single" ? "false" : "true");
+ }
+
+ dojo.addClass(this.domNode, this.classTag);
+ if(!this.isLeftToRight()){
+ dojo.addClass(this.domNode, this.classTag+"Rtl");
+ }
+ },
+
+ postMixInProperties: function(){
+ this.inherited(arguments);
+ var messages = dojo.i18n.getLocalization("dijit", "loading", this.lang);
+ this.loadingMessage = dojo.string.substitute(this.loadingMessage, messages);
+ this.errorMessage = dojo.string.substitute(this.errorMessage, messages);
+ if(this.srcNodeRef && this.srcNodeRef.style.height){
+ this.height = this.srcNodeRef.style.height;
+ }
+ // Call this to update our autoheight to start out
+ this._setAutoHeightAttr(this.autoHeight, true);
+ this.lastScrollTop = this.scrollTop = 0;
+ },
+
+ postCreate: function(){
+ this._placeholders = [];
+ this._setHeaderMenuAttr(this.headerMenu);
+ this._setStructureAttr(this.structure);
+ this._click = [];
+ this.inherited(arguments);
+ if(this.domNode && this.autoWidth && this.initialWidth){
+ this.domNode.style.width = this.initialWidth;
+ }
+ if (this.domNode && !this.editable){
+ // default value for aria-readonly is false, set to true if grid is not editable
+ dojo.attr(this.domNode,"aria-readonly", "true");
+ }
+ },
+
+ destroy: function(){
+ this.domNode.onReveal = null;
+ this.domNode.onSizeChange = null;
+
+ // Fixes IE domNode leak
+ delete this._click;
+
+ this.edit.destroy();
+ delete this.edit;
+
+ this.views.destroyViews();
+ if(this.scroller){
+ this.scroller.destroy();
+ delete this.scroller;
+ }
+ if(this.focus){
+ this.focus.destroy();
+ delete this.focus;
+ }
+ if(this.headerMenu&&this._placeholders.length){
+ dojo.forEach(this._placeholders, function(p){ p.unReplace(true); });
+ this.headerMenu.unBindDomNode(this.viewsHeaderNode);
+ }
+ this.inherited(arguments);
+ },
+
+ _setAutoHeightAttr: function(ah, skipRender){
+ // Calculate our autoheight - turn it into a boolean or an integer
+ if(typeof ah == "string"){
+ if(!ah || ah == "false"){
+ ah = false;
+ }else if (ah == "true"){
+ ah = true;
+ }else{
+ ah = window.parseInt(ah, 10);
+ }
+ }
+ if(typeof ah == "number"){
+ if(isNaN(ah)){
+ ah = false;
+ }
+ // Autoheight must be at least 1, if it's a number. If it's
+ // less than 0, we'll take that to mean "all" rows (same as
+ // autoHeight=true - if it is equal to zero, we'll take that
+ // to mean autoHeight=false
+ if(ah < 0){
+ ah = true;
+ }else if (ah === 0){
+ ah = false;
+ }
+ }
+ this.autoHeight = ah;
+ if(typeof ah == "boolean"){
+ this._autoHeight = ah;
+ }else if(typeof ah == "number"){
+ this._autoHeight = (ah >= this.get('rowCount'));
+ }else{
+ this._autoHeight = false;
+ }
+ if(this._started && !skipRender){
+ this.render();
+ }
+ },
+
+ _getRowCountAttr: function(){
+ return this.updating && this.invalidated && this.invalidated.rowCount != undefined ?
+ this.invalidated.rowCount : this.rowCount;
+ },
+
+ textSizeChanged: function(){
+ this.render();
+ },
+
+ sizeChange: function(){
+ this.update();
+ },
+
+ createManagers: function(){
+ // summary:
+ // create grid managers for various tasks including rows, focus, selection, editing
+
+ // row manager
+ this.rows = new dojox.grid._RowManager(this);
+ // focus manager
+ this.focus = new dojox.grid._FocusManager(this);
+ // edit manager
+ this.edit = new dojox.grid._EditManager(this);
+ },
+
+ createSelection: function(){
+ // summary: Creates a new Grid selection manager.
+
+ // selection manager
+ this.selection = new dojox.grid.Selection(this);
+ },
+
+ createScroller: function(){
+ // summary: Creates a new virtual scroller
+ this.scroller = new dojox.grid._Scroller();
+ this.scroller.grid = this;
+ this.scroller.renderRow = dojo.hitch(this, "renderRow");
+ this.scroller.removeRow = dojo.hitch(this, "rowRemoved");
+ },
+
+ createLayout: function(){
+ // summary: Creates a new Grid layout
+ this.layout = new this._layoutClass(this);
+ this.connect(this.layout, "moveColumn", "onMoveColumn");
+ },
+
+ onMoveColumn: function(){
+ this.render();
+ },
+
+ onResizeColumn: function(/*int*/ cellIdx){
+ // Called when a column is resized.
+ },
+
+ // views
+ createViews: function(){
+ this.views = new dojox.grid._ViewManager(this);
+ this.views.createView = dojo.hitch(this, "createView");
+ },
+
+ createView: function(inClass, idx){
+ var c = dojo.getObject(inClass);
+ var view = new c({ grid: this, index: idx });
+ this.viewsNode.appendChild(view.domNode);
+ this.viewsHeaderNode.appendChild(view.headerNode);
+ this.views.addView(view);
+ dojo.attr(this.domNode, "align", dojo._isBodyLtr() ? 'left' : 'right');
+ return view;
+ },
+
+ buildViews: function(){
+ for(var i=0, vs; (vs=this.layout.structure[i]); i++){
+ this.createView(vs.type || dojox._scopeName + ".grid._View", i).setStructure(vs);
+ }
+ this.scroller.setContentNodes(this.views.getContentNodes());
+ },
+
+ _setStructureAttr: function(structure){
+ var s = structure;
+ if(s && dojo.isString(s)){
+ dojo.deprecated("dojox.grid._Grid.set('structure', 'objVar')", "use dojox.grid._Grid.set('structure', objVar) instead", "2.0");
+ s=dojo.getObject(s);
+ }
+ this.structure = s;
+ if(!s){
+ if(this.layout.structure){
+ s = this.layout.structure;
+ }else{
+ return;
+ }
+ }
+ this.views.destroyViews();
+ if(s !== this.layout.structure){
+ this.layout.setStructure(s);
+ }
+ this._structureChanged();
+ },
+
+ setStructure: function(/* dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]] */ inStructure){
+ // summary:
+ // Install a new structure and rebuild the grid.
+ dojo.deprecated("dojox.grid._Grid.setStructure(obj)", "use dojox.grid._Grid.set('structure', obj) instead.", "2.0");
+ this._setStructureAttr(inStructure);
+ },
+
+ getColumnTogglingItems: function(){
+ // Summary: returns an array of dijit.CheckedMenuItem widgets that can be
+ // added to a menu for toggling columns on and off.
+ return dojo.map(this.layout.cells, function(cell){
+ if(!cell.menuItems){ cell.menuItems = []; }
+
+ var self = this;
+ var item = new dijit.CheckedMenuItem({
+ label: cell.name,
+ checked: !cell.hidden,
+ _gridCell: cell,
+ onChange: function(checked){
+ if(self.layout.setColumnVisibility(this._gridCell.index, checked)){
+ var items = this._gridCell.menuItems;
+ if(items.length > 1){
+ dojo.forEach(items, function(item){
+ if(item !== this){
+ item.setAttribute("checked", checked);
+ }
+ }, this);
+ }
+ checked = dojo.filter(self.layout.cells, function(c){
+ if(c.menuItems.length > 1){
+ dojo.forEach(c.menuItems, "item.set('disabled', false);");
+ }else{
+ c.menuItems[0].set('disabled', false);
+ }
+ return !c.hidden;
+ });
+ if(checked.length == 1){
+ dojo.forEach(checked[0].menuItems, "item.set('disabled', true);");
+ }
+ }
+ },
+ destroy: function(){
+ var index = dojo.indexOf(this._gridCell.menuItems, this);
+ this._gridCell.menuItems.splice(index, 1);
+ delete this._gridCell;
+ dijit.CheckedMenuItem.prototype.destroy.apply(this, arguments);
+ }
+ });
+ cell.menuItems.push(item);
+ return item;
+ }, this); // dijit.CheckedMenuItem[]
+ },
+
+ _setHeaderMenuAttr: function(menu){
+ if(this._placeholders && this._placeholders.length){
+ dojo.forEach(this._placeholders, function(p){
+ p.unReplace(true);
+ });
+ this._placeholders = [];
+ }
+ if(this.headerMenu){
+ this.headerMenu.unBindDomNode(this.viewsHeaderNode);
+ }
+ this.headerMenu = menu;
+ if(!menu){ return; }
+
+ this.headerMenu.bindDomNode(this.viewsHeaderNode);
+ if(this.headerMenu.getPlaceholders){
+ this._placeholders = this.headerMenu.getPlaceholders(this.placeholderLabel);
+ }
+ },
+
+ setHeaderMenu: function(/* dijit.Menu */ menu){
+ dojo.deprecated("dojox.grid._Grid.setHeaderMenu(obj)", "use dojox.grid._Grid.set('headerMenu', obj) instead.", "2.0");
+ this._setHeaderMenuAttr(menu);
+ },
+
+ setupHeaderMenu: function(){
+ if(this._placeholders && this._placeholders.length){
+ dojo.forEach(this._placeholders, function(p){
+ if(p._replaced){
+ p.unReplace(true);
+ }
+ p.replace(this.getColumnTogglingItems());
+ }, this);
+ }
+ },
+
+ _fetch: function(start){
+ this.setScrollTop(0);
+ },
+
+ getItem: function(inRowIndex){
+ return null;
+ },
+
+ showMessage: function(message){
+ if(message){
+ this.messagesNode.innerHTML = message;
+ this.messagesNode.style.display = "";
+ }else{
+ this.messagesNode.innerHTML = "";
+ this.messagesNode.style.display = "none";
+ }
+ },
+
+ _structureChanged: function() {
+ this.buildViews();
+ if(this.autoRender && this._started){
+ this.render();
+ }
+ },
+
+ hasLayout: function() {
+ return this.layout.cells.length;
+ },
+
+ // sizing
+ resize: function(changeSize, resultSize){
+ // summary:
+ // Update the grid's rendering dimensions and resize it
+
+ // Calling sizeChange calls update() which calls _resize...so let's
+ // save our input values, if any, and use them there when it gets
+ // called. This saves us an extra call to _resize(), which can
+ // get kind of heavy.
+ this._pendingChangeSize = changeSize;
+ this._pendingResultSize = resultSize;
+ this.sizeChange();
+ },
+
+ _getPadBorder: function() {
+ this._padBorder = this._padBorder || dojo._getPadBorderExtents(this.domNode);
+ return this._padBorder;
+ },
+
+ _getHeaderHeight: function(){
+ var vns = this.viewsHeaderNode.style, t = vns.display == "none" ? 0 : this.views.measureHeader();
+ vns.height = t + 'px';
+ // header heights are reset during measuring so must be normalized after measuring.
+ this.views.normalizeHeaderNodeHeight();
+ return t;
+ },
+
+ _resize: function(changeSize, resultSize){
+ // Restore our pending values, if any
+ changeSize = changeSize || this._pendingChangeSize;
+ resultSize = resultSize || this._pendingResultSize;
+ delete this._pendingChangeSize;
+ delete this._pendingResultSize;
+ // if we have set up everything except the DOM, we cannot resize
+ if(!this.domNode){ return; }
+ var pn = this.domNode.parentNode;
+ if(!pn || pn.nodeType != 1 || !this.hasLayout() || pn.style.visibility == "hidden" || pn.style.display == "none"){
+ return;
+ }
+ // useful measurement
+ var padBorder = this._getPadBorder();
+ var hh = undefined;
+ var h;
+ // grid height
+ if(this._autoHeight){
+ this.domNode.style.height = 'auto';
+ }else if(typeof this.autoHeight == "number"){
+ h = hh = this._getHeaderHeight();
+ h += (this.scroller.averageRowHeight * this.autoHeight);
+ this.domNode.style.height = h + "px";
+ }else if(this.domNode.clientHeight <= padBorder.h){
+ if(pn == document.body){
+ this.domNode.style.height = this.defaultHeight;
+ }else if(this.height){
+ this.domNode.style.height = this.height;
+ }else{
+ this.fitTo = "parent";
+ }
+ }
+ // if we are given dimensions, size the grid's domNode to those dimensions
+ if(resultSize){
+ changeSize = resultSize;
+ }
+ if(changeSize){
+ dojo.marginBox(this.domNode, changeSize);
+ this.height = this.domNode.style.height;
+ delete this.fitTo;
+ }else if(this.fitTo == "parent"){
+ h = this._parentContentBoxHeight = this._parentContentBoxHeight || dojo._getContentBox(pn).h;
+ this.domNode.style.height = Math.max(0, h) + "px";
+ }
+
+ var hasFlex = dojo.some(this.views.views, function(v){ return v.flexCells; });
+
+ if(!this._autoHeight && (h || dojo._getContentBox(this.domNode).h) === 0){
+ // We need to hide the header, since the Grid is essentially hidden.
+ this.viewsHeaderNode.style.display = "none";
+ }else{
+ // Otherwise, show the header and give it an appropriate height.
+ this.viewsHeaderNode.style.display = "block";
+ if(!hasFlex && hh === undefined){
+ hh = this._getHeaderHeight();
+ }
+ }
+ if(hasFlex){
+ hh = undefined;
+ }
+
+ // NOTE: it is essential that width be applied before height
+ // Header height can only be calculated properly after view widths have been set.
+ // This is because flex column width is naturally 0 in Firefox.
+ // Therefore prior to width sizing flex columns with spaces are maximally wrapped
+ // and calculated to be too tall.
+ this.adaptWidth();
+ this.adaptHeight(hh);
+
+ this.postresize();
+ },
+
+ adaptWidth: function() {
+ // private: sets width and position for views and update grid width if necessary
+ var doAutoWidth = (!this.initialWidth && this.autoWidth);
+ var w = doAutoWidth ? 0 : this.domNode.clientWidth || (this.domNode.offsetWidth - this._getPadBorder().w),
+ vw = this.views.arrange(1, w);
+ this.views.onEach("adaptWidth");
+ if(doAutoWidth){
+ this.domNode.style.width = vw + "px";
+ }
+ },
+
+ adaptHeight: function(inHeaderHeight){
+ // private: measures and normalizes header height, then sets view heights, and then updates scroller
+ // content extent
+ var t = inHeaderHeight === undefined ? this._getHeaderHeight() : inHeaderHeight;
+ var h = (this._autoHeight ? -1 : Math.max(this.domNode.clientHeight - t, 0) || 0);
+ this.views.onEach('setSize', [0, h]);
+ this.views.onEach('adaptHeight');
+ if(!this._autoHeight){
+ var numScroll = 0, numNoScroll = 0;
+ var noScrolls = dojo.filter(this.views.views, function(v){
+ var has = v.hasHScrollbar();
+ if(has){ numScroll++; }else{ numNoScroll++; }
+ return (!has);
+ });
+ if(numScroll > 0 && numNoScroll > 0){
+ dojo.forEach(noScrolls, function(v){
+ v.adaptHeight(true);
+ });
+ }
+ }
+ if(this.autoHeight === true || h != -1 || (typeof this.autoHeight == "number" && this.autoHeight >= this.get('rowCount'))){
+ this.scroller.windowHeight = h;
+ }else{
+ this.scroller.windowHeight = Math.max(this.domNode.clientHeight - t, 0);
+ }
+ },
+
+ // startup
+ startup: function(){
+ if(this._started){return;}
+ this.inherited(arguments);
+ if(this.autoRender){
+ this.render();
+ }
+ },
+
+ // render
+ render: function(){
+ // summary:
+ // Render the grid, headers, and views. Edit and scrolling states are reset. To retain edit and
+ // scrolling states, see Update.
+
+ if(!this.domNode){return;}
+ if(!this._started){return;}
+
+ if(!this.hasLayout()) {
+ this.scroller.init(0, this.keepRows, this.rowsPerPage);
+ return;
+ }
+ //
+ this.update = this.defaultUpdate;
+ this._render();
+ },
+
+ _render: function(){
+ this.scroller.init(this.get('rowCount'), this.keepRows, this.rowsPerPage);
+ this.prerender();
+ this.setScrollTop(0);
+ this.postrender();
+ },
+
+ prerender: function(){
+ // if autoHeight, make sure scroller knows not to virtualize; everything must be rendered.
+ this.keepRows = this._autoHeight ? 0 : this.keepRows;
+ this.scroller.setKeepInfo(this.keepRows);
+ this.views.render();
+ this._resize();
+ },
+
+ postrender: function(){
+ this.postresize();
+ this.focus.initFocusView();
+ // make rows unselectable
+ dojo.setSelectable(this.domNode, this.selectable);
+ },
+
+ postresize: function(){
+ // views are position absolute, so they do not inflate the parent
+ if(this._autoHeight){
+ var size = Math.max(this.views.measureContent()) + 'px';
+
+ this.viewsNode.style.height = size;
+ }
+ },
+
+ renderRow: function(inRowIndex, inNodes){
+ // summary: private, used internally to render rows
+ this.views.renderRow(inRowIndex, inNodes, this._skipRowRenormalize);
+ },
+
+ rowRemoved: function(inRowIndex){
+ // summary: private, used internally to remove rows
+ this.views.rowRemoved(inRowIndex);
+ },
+
+ invalidated: null,
+
+ updating: false,
+
+ beginUpdate: function(){
+ // summary:
+ // Use to make multiple changes to rows while queueing row updating.
+ // NOTE: not currently supporting nested begin/endUpdate calls
+ this.invalidated = [];
+ this.updating = true;
+ },
+
+ endUpdate: function(){
+ // summary:
+ // Use after calling beginUpdate to render any changes made to rows.
+ this.updating = false;
+ var i = this.invalidated, r;
+ if(i.all){
+ this.update();
+ }else if(i.rowCount != undefined){
+ this.updateRowCount(i.rowCount);
+ }else{
+ for(r in i){
+ this.updateRow(Number(r));
+ }
+ }
+ this.invalidated = [];
+ },
+
+ // update
+ defaultUpdate: function(){
+ // note: initial update calls render and subsequently this function.
+ if(!this.domNode){return;}
+ if(this.updating){
+ this.invalidated.all = true;
+ return;
+ }
+ //this.edit.saveState(inRowIndex);
+ this.lastScrollTop = this.scrollTop;
+ this.prerender();
+ this.scroller.invalidateNodes();
+ this.setScrollTop(this.lastScrollTop);
+ this.postrender();
+ //this.edit.restoreState(inRowIndex);
+ },
+
+ update: function(){
+ // summary:
+ // Update the grid, retaining edit and scrolling states.
+ this.render();
+ },
+
+ updateRow: function(inRowIndex){
+ // summary:
+ // Render a single row.
+ // inRowIndex: Integer
+ // Index of the row to render
+ inRowIndex = Number(inRowIndex);
+ if(this.updating){
+ this.invalidated[inRowIndex]=true;
+ }else{
+ this.views.updateRow(inRowIndex);
+ this.scroller.rowHeightChanged(inRowIndex);
+ }
+ },
+
+ updateRows: function(startIndex, howMany){
+ // summary:
+ // Render consecutive rows at once.
+ // startIndex: Integer
+ // Index of the starting row to render
+ // howMany: Integer
+ // How many rows to update.
+ startIndex = Number(startIndex);
+ howMany = Number(howMany);
+ var i;
+ if(this.updating){
+ for(i=0; i<howMany; i++){
+ this.invalidated[i+startIndex]=true;
+ }
+ }else{
+ for(i=0; i<howMany; i++){
+ this.views.updateRow(i+startIndex, this._skipRowRenormalize);
+ }
+ this.scroller.rowHeightChanged(startIndex);
+ }
+ },
+
+ updateRowCount: function(inRowCount){
+ //summary:
+ // Change the number of rows.
+ // inRowCount: int
+ // Number of rows in the grid.
+ if(this.updating){
+ this.invalidated.rowCount = inRowCount;
+ }else{
+ this.rowCount = inRowCount;
+ this._setAutoHeightAttr(this.autoHeight, true);
+ if(this.layout.cells.length){
+ this.scroller.updateRowCount(inRowCount);
+ }
+ this._resize();
+ if(this.layout.cells.length){
+ this.setScrollTop(this.scrollTop);
+ }
+ }
+ },
+
+ updateRowStyles: function(inRowIndex){
+ // summary:
+ // Update the styles for a row after it's state has changed.
+ this.views.updateRowStyles(inRowIndex);
+ },
+ getRowNode: function(inRowIndex){
+ // summary:
+ // find the rowNode that is not a rowSelector
+ if (this.focus.focusView && !(this.focus.focusView instanceof dojox.grid._RowSelector)){
+ return this.focus.focusView.rowNodes[inRowIndex];
+ }else{ // search through views
+ for (var i = 0, cView; (cView = this.views.views[i]); i++) {
+ if (!(cView instanceof dojox.grid._RowSelector)) {
+ return cView.rowNodes[inRowIndex];
+ }
+ }
+ }
+ return null;
+ },
+ rowHeightChanged: function(inRowIndex){
+ // summary:
+ // Update grid when the height of a row has changed. Row height is handled automatically as rows
+ // are rendered. Use this function only to update a row's height outside the normal rendering process.
+ // inRowIndex: Integer
+ // index of the row that has changed height
+
+ this.views.renormalizeRow(inRowIndex);
+ this.scroller.rowHeightChanged(inRowIndex);
+ },
+
+ // fastScroll: Boolean
+ // flag modifies vertical scrolling behavior. Defaults to true but set to false for slower
+ // scroll performance but more immediate scrolling feedback
+ fastScroll: true,
+
+ delayScroll: false,
+
+ // scrollRedrawThreshold: int
+ // pixel distance a user must scroll vertically to trigger grid scrolling.
+ scrollRedrawThreshold: (dojo.isIE ? 100 : 50),
+
+ // scroll methods
+ scrollTo: function(inTop){
+ // summary:
+ // Vertically scroll the grid to a given pixel position
+ // inTop: Integer
+ // vertical position of the grid in pixels
+ if(!this.fastScroll){
+ this.setScrollTop(inTop);
+ return;
+ }
+ var delta = Math.abs(this.lastScrollTop - inTop);
+ this.lastScrollTop = inTop;
+ if(delta > this.scrollRedrawThreshold || this.delayScroll){
+ this.delayScroll = true;
+ this.scrollTop = inTop;
+ this.views.setScrollTop(inTop);
+ if(this._pendingScroll){
+ window.clearTimeout(this._pendingScroll);
+ }
+ var _this = this;
+ this._pendingScroll = window.setTimeout(function(){
+ delete _this._pendingScroll;
+ _this.finishScrollJob();
+ }, 200);
+ }else{
+ this.setScrollTop(inTop);
+ }
+ },
+
+ finishScrollJob: function(){
+ this.delayScroll = false;
+ this.setScrollTop(this.scrollTop);
+ },
+
+ setScrollTop: function(inTop){
+ this.scroller.scroll(this.views.setScrollTop(inTop));
+ },
+
+ scrollToRow: function(inRowIndex){
+ // summary:
+ // Scroll the grid to a specific row.
+ // inRowIndex: Integer
+ // grid row index
+ this.setScrollTop(this.scroller.findScrollTop(inRowIndex) + 1);
+ },
+
+ // styling (private, used internally to style individual parts of a row)
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ this.rows.styleRowNode(inRowIndex, inRowNode);
+ }
+ },
+
+ // called when the mouse leaves the grid so we can deselect all hover rows
+ _mouseOut: function(e){
+ this.rows.setOverRow(-2);
+ },
+
+ // cells
+ getCell: function(inIndex){
+ // summary:
+ // Retrieves the cell object for a given grid column.
+ // inIndex: Integer
+ // Grid column index of cell to retrieve
+ // returns:
+ // a grid cell
+ return this.layout.cells[inIndex];
+ },
+
+ setCellWidth: function(inIndex, inUnitWidth){
+ this.getCell(inIndex).unitWidth = inUnitWidth;
+ },
+
+ getCellName: function(inCell){
+ // summary: Returns the cell name of a passed cell
+ return "Cell " + inCell.index; // String
+ },
+
+ // sorting
+ canSort: function(inSortInfo){
+ // summary:
+ // Determines if the grid can be sorted
+ // inSortInfo: Integer
+ // Sort information, 1-based index of column on which to sort, positive for an ascending sort
+ // and negative for a descending sort
+ // returns: Boolean
+ // True if grid can be sorted on the given column in the given direction
+ },
+
+ sort: function(){
+ },
+
+ getSortAsc: function(inSortInfo){
+ // summary:
+ // Returns true if grid is sorted in an ascending direction.
+ inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo;
+ return Boolean(inSortInfo > 0); // Boolean
+ },
+
+ getSortIndex: function(inSortInfo){
+ // summary:
+ // Returns the index of the column on which the grid is sorted
+ inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo;
+ return Math.abs(inSortInfo) - 1; // Integer
+ },
+
+ setSortIndex: function(inIndex, inAsc){
+ // summary:
+ // Sort the grid on a column in a specified direction
+ // inIndex: Integer
+ // Column index on which to sort.
+ // inAsc: Boolean
+ // If true, sort the grid in ascending order, otherwise in descending order
+ var si = inIndex +1;
+ if(inAsc != undefined){
+ si *= (inAsc ? 1 : -1);
+ } else if(this.getSortIndex() == inIndex){
+ si = -this.sortInfo;
+ }
+ this.setSortInfo(si);
+ },
+
+ setSortInfo: function(inSortInfo){
+ if(this.canSort(inSortInfo)){
+ this.sortInfo = inSortInfo;
+ this.sort();
+ this.update();
+ }
+ },
+
+ // DOM event handler
+ doKeyEvent: function(e){
+ e.dispatch = 'do' + e.type;
+ this.onKeyEvent(e);
+ },
+
+ // event dispatch
+ //: protected
+ _dispatch: function(m, e){
+ if(m in this){
+ return this[m](e);
+ }
+ return false;
+ },
+
+ dispatchKeyEvent: function(e){
+ this._dispatch(e.dispatch, e);
+ },
+
+ dispatchContentEvent: function(e){
+ this.edit.dispatchEvent(e) || e.sourceView.dispatchContentEvent(e) || this._dispatch(e.dispatch, e);
+ },
+
+ dispatchHeaderEvent: function(e){
+ e.sourceView.dispatchHeaderEvent(e) || this._dispatch('doheader' + e.type, e);
+ },
+
+ dokeydown: function(e){
+ this.onKeyDown(e);
+ },
+
+ doclick: function(e){
+ if(e.cellNode){
+ this.onCellClick(e);
+ }else{
+ this.onRowClick(e);
+ }
+ },
+
+ dodblclick: function(e){
+ if(e.cellNode){
+ this.onCellDblClick(e);
+ }else{
+ this.onRowDblClick(e);
+ }
+ },
+
+ docontextmenu: function(e){
+ if(e.cellNode){
+ this.onCellContextMenu(e);
+ }else{
+ this.onRowContextMenu(e);
+ }
+ },
+
+ doheaderclick: function(e){
+ if(e.cellNode){
+ this.onHeaderCellClick(e);
+ }else{
+ this.onHeaderClick(e);
+ }
+ },
+
+ doheaderdblclick: function(e){
+ if(e.cellNode){
+ this.onHeaderCellDblClick(e);
+ }else{
+ this.onHeaderDblClick(e);
+ }
+ },
+
+ doheadercontextmenu: function(e){
+ if(e.cellNode){
+ this.onHeaderCellContextMenu(e);
+ }else{
+ this.onHeaderContextMenu(e);
+ }
+ },
+
+ // override to modify editing process
+ doStartEdit: function(inCell, inRowIndex){
+ this.onStartEdit(inCell, inRowIndex);
+ },
+
+ doApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
+ this.onApplyCellEdit(inValue, inRowIndex, inFieldIndex);
+ },
+
+ doCancelEdit: function(inRowIndex){
+ this.onCancelEdit(inRowIndex);
+ },
+
+ doApplyEdit: function(inRowIndex){
+ this.onApplyEdit(inRowIndex);
+ },
+
+ // row editing
+ addRow: function(){
+ // summary:
+ // Add a row to the grid.
+ this.updateRowCount(this.get('rowCount')+1);
+ },
+
+ removeSelectedRows: function(){
+ // summary:
+ // Remove the selected rows from the grid.
+ if(this.allItemsSelected){
+ this.updateRowCount(0);
+ }else{
+ this.updateRowCount(Math.max(0, this.get('rowCount') - this.selection.getSelected().length));
+ }
+ this.selection.clear();
+ }
+
+ });
+
+ dojox.grid._Grid.markupFactory = function(props, node, ctor, cellFunc){
+ var d = dojo;
+ var widthFromAttr = function(n){
+ var w = d.attr(n, "width")||"auto";
+ if((w != "auto")&&(w.slice(-2) != "em")&&(w.slice(-1) != "%")){
+ w = parseInt(w, 10)+"px";
+ }
+ return w;
+ };
+ // if(!props.store){ console.debug("no store!"); }
+ // if a structure isn't referenced, do we have enough
+ // data to try to build one automatically?
+ if( !props.structure &&
+ node.nodeName.toLowerCase() == "table"){
+
+ // try to discover a structure
+ props.structure = d.query("> colgroup", node).map(function(cg){
+ var sv = d.attr(cg, "span");
+ var v = {
+ noscroll: (d.attr(cg, "noscroll") == "true") ? true : false,
+ __span: (!!sv ? parseInt(sv, 10) : 1),
+ cells: []
+ };
+ if(d.hasAttr(cg, "width")){
+ v.width = widthFromAttr(cg);
+ }
+ return v; // for vendetta
+ });
+ if(!props.structure.length){
+ props.structure.push({
+ __span: Infinity,
+ cells: [] // catch-all view
+ });
+ }
+ // check to see if we're gonna have more than one view
+
+ // for each tr in our th, create a row of cells
+ d.query("thead > tr", node).forEach(function(tr, tr_idx){
+ var cellCount = 0;
+ var viewIdx = 0;
+ var lastViewIdx;
+ var cView = null;
+ d.query("> th", tr).map(function(th){
+ // what view will this cell go into?
+
+ // NOTE:
+ // to prevent extraneous iteration, we start counters over
+ // for each row, incrementing over the surface area of the
+ // structure that colgroup processing generates and
+ // creating cell objects for each <th> to place into those
+ // cell groups. There's a lot of state-keepking logic
+ // here, but it is what it has to be.
+ if(!cView){ // current view book keeping
+ lastViewIdx = 0;
+ cView = props.structure[0];
+ }else if(cellCount >= (lastViewIdx+cView.__span)){
+ viewIdx++;
+ // move to allocating things into the next view
+ lastViewIdx += cView.__span;
+ var lastView = cView;
+ cView = props.structure[viewIdx];
+ }
+
+ // actually define the cell from what markup hands us
+ var cell = {
+ name: d.trim(d.attr(th, "name")||th.innerHTML),
+ colSpan: parseInt(d.attr(th, "colspan")||1, 10),
+ type: d.trim(d.attr(th, "cellType")||""),
+ id: d.trim(d.attr(th,"id")||"")
+ };
+ cellCount += cell.colSpan;
+ var rowSpan = d.attr(th, "rowspan");
+ if(rowSpan){
+ cell.rowSpan = rowSpan;
+ }
+ if(d.hasAttr(th, "width")){
+ cell.width = widthFromAttr(th);
+ }
+ if(d.hasAttr(th, "relWidth")){
+ cell.relWidth = window.parseInt(dojo.attr(th, "relWidth"), 10);
+ }
+ if(d.hasAttr(th, "hidden")){
+ cell.hidden = (d.attr(th, "hidden") == "true" || d.attr(th, "hidden") === true/*always boolean true in Chrome*/);
+ }
+
+ if(cellFunc){
+ cellFunc(th, cell);
+ }
+
+ cell.type = cell.type ? dojo.getObject(cell.type) : dojox.grid.cells.Cell;
+
+ if(cell.type && cell.type.markupFactory){
+ cell.type.markupFactory(th, cell);
+ }
+
+ if(!cView.cells[tr_idx]){
+ cView.cells[tr_idx] = [];
+ }
+ cView.cells[tr_idx].push(cell);
+ });
+ });
+ }
+
+ return new ctor(props, node);
+ };
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid.DataSelection"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.DataSelection"] = true;
+dojo.provide("dojox.grid.DataSelection");
+
+
+dojo.declare("dojox.grid.DataSelection", dojox.grid.Selection, {
+ getFirstSelected: function(){
+ var idx = dojox.grid.Selection.prototype.getFirstSelected.call(this);
+
+ if(idx == -1){ return null; }
+ return this.grid.getItem(idx);
+ },
+
+ getNextSelected: function(inPrev){
+ var old_idx = this.grid.getItemIndex(inPrev);
+ var idx = dojox.grid.Selection.prototype.getNextSelected.call(this, old_idx);
+
+ if(idx == -1){ return null; }
+ return this.grid.getItem(idx);
+ },
+
+ getSelected: function(){
+ var result = [];
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ result.push(this.grid.getItem(i));
+ }
+ }
+ return result;
+ },
+
+ addToSelection: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ dojox.grid.Selection.prototype.addToSelection.call(this, idx);
+ },
+
+ deselect: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ dojox.grid.Selection.prototype.deselect.call(this, idx);
+ },
+
+ deselectAll: function(inItemOrIndex){
+ var idx = null;
+ if(inItemOrIndex || typeof inItemOrIndex == "number"){
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ dojox.grid.Selection.prototype.deselectAll.call(this, idx);
+ }else{
+ this.inherited(arguments);
+ }
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid.DataGrid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.DataGrid"] = true;
+dojo.provide("dojox.grid.DataGrid");
+
+
+
+
+/*=====
+dojo.declare("dojox.grid.__DataCellDef", dojox.grid.__CellDef, {
+ constructor: function(){
+ // field: String?
+ // The attribute to read from the dojo.data item for the row.
+ // fields: String[]?
+ // An array of fields to grab the values of and pass as an array to the grid
+ // get: Function?
+ // function(rowIndex, item?){} rowIndex is of type Integer, item is of type
+ // Object. This function will be called when a cell requests data. Returns
+ // the unformatted data for the cell.
+ }
+});
+=====*/
+
+/*=====
+dojo.declare("dojox.grid.__DataViewDef", dojox.grid.__ViewDef, {
+ constructor: function(){
+ // cells: dojox.grid.__DataCellDef[]|Array[dojox.grid.__DataCellDef[]]?
+ // The structure of the cells within this grid.
+ // defaultCell: dojox.grid.__DataCellDef?
+ // A cell definition with default values for all cells in this view. If
+ // a property is defined in a cell definition in the "cells" array and
+ // this property, the cell definition's property will override this
+ // property's property.
+ }
+});
+=====*/
+
+dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
+ store: null,
+ query: null,
+ queryOptions: null,
+ fetchText: '...',
+ sortFields: null,
+
+ // updateDelay: int
+ // Time, in milliseconds, to delay updates automatically so that multiple
+ // calls to onSet/onNew/onDelete don't keep rerendering the grid. Set
+ // to 0 to immediately cause updates. A higher value will result in
+ // better performance at the expense of responsiveness of the grid.
+ updateDelay: 1,
+
+/*=====
+ // structure: dojox.grid.__DataViewDef|dojox.grid.__DataViewDef[]|dojox.grid.__DataCellDef[]|Array[dojox.grid.__DataCellDef[]]
+ // View layout defintion.
+ structure: '',
+=====*/
+
+ // You can specify items instead of a query, if you like. They do not need
+ // to be loaded - but the must be items in the store
+ items: null,
+
+ _store_connects: null,
+ _by_idty: null,
+ _by_idx: null,
+ _cache: null,
+ _pages: null,
+ _pending_requests: null,
+ _bop: -1,
+ _eop: -1,
+ _requests: 0,
+ rowCount: 0,
+
+ _isLoaded: false,
+ _isLoading: false,
+
+ postCreate: function(){
+ this._pages = [];
+ this._store_connects = [];
+ this._by_idty = {};
+ this._by_idx = [];
+ this._cache = [];
+ this._pending_requests = {};
+
+ this._setStore(this.store);
+ this.inherited(arguments);
+ },
+
+ createSelection: function(){
+ this.selection = new dojox.grid.DataSelection(this);
+ },
+
+ get: function(inRowIndex, inItem){
+ // summary: Default data getter.
+ // description:
+ // Provides data to display in a grid cell. Called in grid cell context.
+ // So this.cell.index is the column index.
+ // inRowIndex: Integer
+ // Row for which to provide data
+ // returns:
+ // Data to display for a given grid cell.
+
+ if(inItem && this.field == "_item" && !this.fields){
+ return inItem;
+ }else if(inItem && this.fields){
+ var ret = [];
+ var s = this.grid.store;
+ dojo.forEach(this.fields, function(f){
+ ret = ret.concat(s.getValues(inItem, f));
+ });
+ return ret;
+ }else if(!inItem && typeof inRowIndex === "string"){
+ return this.inherited(arguments);
+ }
+ return (!inItem ? this.defaultValue : (!this.field ? this.value : (this.field == "_item" ? inItem : this.grid.store.getValue(inItem, this.field))));
+ },
+
+ _checkUpdateStatus: function(){
+ if(this.updateDelay > 0){
+ var iStarted = false;
+ if(this._endUpdateDelay){
+ clearTimeout(this._endUpdateDelay);
+ delete this._endUpdateDelay;
+ iStarted = true;
+ }
+ if(!this.updating){
+ this.beginUpdate();
+ iStarted = true;
+ }
+ if(iStarted){
+ var _this = this;
+ this._endUpdateDelay = setTimeout(function(){
+ delete _this._endUpdateDelay;
+ _this.endUpdate();
+ }, this.updateDelay);
+ }
+ }
+ },
+
+ _onSet: function(item, attribute, oldValue, newValue){
+ this._checkUpdateStatus();
+ var idx = this.getItemIndex(item);
+ if(idx>-1){
+ this.updateRow(idx);
+ }
+ },
+
+ _createItem: function(item, index){
+ var idty = this._hasIdentity ? this.store.getIdentity(item) : dojo.toJson(this.query) + ":idx:" + index + ":sort:" + dojo.toJson(this.getSortProps());
+ var o = this._by_idty[idty] = { idty: idty, item: item };
+ return o;
+ },
+
+ _addItem: function(item, index, noUpdate){
+ this._by_idx[index] = this._createItem(item, index);
+ if(!noUpdate){
+ this.updateRow(index);
+ }
+ },
+
+ _onNew: function(item, parentInfo){
+ this._checkUpdateStatus();
+ var rowCount = this.get('rowCount');
+ this._addingItem = true;
+ this.updateRowCount(rowCount+1);
+ this._addingItem = false;
+ this._addItem(item, rowCount);
+ this.showMessage();
+ },
+
+ _onDelete: function(item){
+ this._checkUpdateStatus();
+ var idx = this._getItemIndex(item, true);
+
+ if(idx >= 0){
+ // When a row is deleted, all rest rows are shifted down,
+ // and migrate from page to page. If some page is not
+ // loaded yet empty rows can migrate to initialized pages
+ // without refreshing. It causes empty rows in some pages, see:
+ // http://bugs.dojotoolkit.org/ticket/6818
+ // this code fix this problem by reseting loaded page info
+ this._pages = [];
+ this._bop = -1;
+ this._eop = -1;
+
+ var o = this._by_idx[idx];
+ this._by_idx.splice(idx, 1);
+ delete this._by_idty[o.idty];
+ this.updateRowCount(this.get('rowCount')-1);
+ if(this.get('rowCount') === 0){
+ this.showMessage(this.noDataMessage);
+ }
+ }
+ },
+
+ _onRevert: function(){
+ this._refresh();
+ },
+
+ setStore: function(store, query, queryOptions){
+ this._setQuery(query, queryOptions);
+ this._setStore(store);
+ this._refresh(true);
+ },
+
+ setQuery: function(query, queryOptions){
+ this._setQuery(query, queryOptions);
+ this._refresh(true);
+ },
+
+ setItems: function(items){
+ this.items = items;
+ this._setStore(this.store);
+ this._refresh(true);
+ },
+
+ _setQuery: function(query, queryOptions){
+ this.query = query;
+ this.queryOptions = queryOptions || this.queryOptions;
+ },
+
+ _setStore: function(store){
+ if(this.store && this._store_connects){
+ dojo.forEach(this._store_connects, this.disconnect, this);
+ }
+ this.store = store;
+
+ if(this.store){
+ var f = this.store.getFeatures();
+ var h = [];
+
+ this._canEdit = !!f["dojo.data.api.Write"] && !!f["dojo.data.api.Identity"];
+ this._hasIdentity = !!f["dojo.data.api.Identity"];
+
+ if(!!f["dojo.data.api.Notification"] && !this.items){
+ h.push(this.connect(this.store, "onSet", "_onSet"));
+ h.push(this.connect(this.store, "onNew", "_onNew"));
+ h.push(this.connect(this.store, "onDelete", "_onDelete"));
+ }
+ if(this._canEdit){
+ h.push(this.connect(this.store, "revert", "_onRevert"));
+ }
+
+ this._store_connects = h;
+ }
+ },
+
+ _onFetchBegin: function(size, req){
+ if(!this.scroller){ return; }
+ if(this.rowCount != size){
+ if(req.isRender){
+ this.scroller.init(size, this.keepRows, this.rowsPerPage);
+ this.rowCount = size;
+ this._setAutoHeightAttr(this.autoHeight, true);
+ this._skipRowRenormalize = true;
+ this.prerender();
+ this._skipRowRenormalize = false;
+ }else{
+ this.updateRowCount(size);
+ }
+ }
+ if(!size){
+ this.views.render();
+ this._resize();
+ this.showMessage(this.noDataMessage);
+ this.focus.initFocusView();
+ }else{
+ this.showMessage();
+ }
+ },
+
+ _onFetchComplete: function(items, req){
+ if(!this.scroller){ return; }
+ if(items && items.length > 0){
+ //console.log(items);
+ dojo.forEach(items, function(item, idx){
+ this._addItem(item, req.start+idx, true);
+ }, this);
+ this.updateRows(req.start, items.length);
+ if(req.isRender){
+ this.setScrollTop(0);
+ this.postrender();
+ }else if(this._lastScrollTop){
+ this.setScrollTop(this._lastScrollTop);
+ }
+ }
+ delete this._lastScrollTop;
+ if(!this._isLoaded){
+ this._isLoading = false;
+ this._isLoaded = true;
+ }
+ this._pending_requests[req.start] = false;
+ },
+
+ _onFetchError: function(err, req){
+ console.log(err);
+ delete this._lastScrollTop;
+ if(!this._isLoaded){
+ this._isLoading = false;
+ this._isLoaded = true;
+ this.showMessage(this.errorMessage);
+ }
+ this._pending_requests[req.start] = false;
+ this.onFetchError(err, req);
+ },
+
+ onFetchError: function(err, req){
+ },
+
+ _fetch: function(start, isRender){
+ start = start || 0;
+ if(this.store && !this._pending_requests[start]){
+ if(!this._isLoaded && !this._isLoading){
+ this._isLoading = true;
+ this.showMessage(this.loadingMessage);
+ }
+ this._pending_requests[start] = true;
+ //console.log("fetch: ", start);
+ try{
+ if(this.items){
+ var items = this.items;
+ var store = this.store;
+ this.rowsPerPage = items.length;
+ var req = {
+ start: start,
+ count: this.rowsPerPage,
+ isRender: isRender
+ };
+ this._onFetchBegin(items.length, req);
+
+ // Load them if we need to
+ var waitCount = 0;
+ dojo.forEach(items, function(i){
+ if(!store.isItemLoaded(i)){ waitCount++; }
+ });
+ if(waitCount === 0){
+ this._onFetchComplete(items, req);
+ }else{
+ var onItem = function(item){
+ waitCount--;
+ if(waitCount === 0){
+ this._onFetchComplete(items, req);
+ }
+ };
+ dojo.forEach(items, function(i){
+ if(!store.isItemLoaded(i)){
+ store.loadItem({item: i, onItem: onItem, scope: this});
+ }
+ }, this);
+ }
+ }else{
+ this.store.fetch({
+ start: start,
+ count: this.rowsPerPage,
+ query: this.query,
+ sort: this.getSortProps(),
+ queryOptions: this.queryOptions,
+ isRender: isRender,
+ onBegin: dojo.hitch(this, "_onFetchBegin"),
+ onComplete: dojo.hitch(this, "_onFetchComplete"),
+ onError: dojo.hitch(this, "_onFetchError")
+ });
+ }
+ }catch(e){
+ this._onFetchError(e, {start: start, count: this.rowsPerPage});
+ }
+ }
+ },
+
+ _clearData: function(){
+ this.updateRowCount(0);
+ this._by_idty = {};
+ this._by_idx = [];
+ this._pages = [];
+ this._bop = this._eop = -1;
+ this._isLoaded = false;
+ this._isLoading = false;
+ },
+
+ getItem: function(idx){
+ var data = this._by_idx[idx];
+ if(!data||(data&&!data.item)){
+ this._preparePage(idx);
+ return null;
+ }
+ return data.item;
+ },
+
+ getItemIndex: function(item){
+ return this._getItemIndex(item, false);
+ },
+
+ _getItemIndex: function(item, isDeleted){
+ if(!isDeleted && !this.store.isItem(item)){
+ return -1;
+ }
+
+ var idty = this._hasIdentity ? this.store.getIdentity(item) : null;
+
+ for(var i=0, l=this._by_idx.length; i<l; i++){
+ var d = this._by_idx[i];
+ if(d && ((idty && d.idty == idty) || (d.item === item))){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ filter: function(query, reRender){
+ this.query = query;
+ if(reRender){
+ this._clearData();
+ }
+ this._fetch();
+ },
+
+ _getItemAttr: function(idx, attr){
+ var item = this.getItem(idx);
+ return (!item ? this.fetchText : this.store.getValue(item, attr));
+ },
+
+ // rendering
+ _render: function(){
+ if(this.domNode.parentNode){
+ this.scroller.init(this.get('rowCount'), this.keepRows, this.rowsPerPage);
+ this.prerender();
+ this._fetch(0, true);
+ }
+ },
+
+ // paging
+ _requestsPending: function(inRowIndex){
+ return this._pending_requests[inRowIndex];
+ },
+
+ _rowToPage: function(inRowIndex){
+ return (this.rowsPerPage ? Math.floor(inRowIndex / this.rowsPerPage) : inRowIndex);
+ },
+
+ _pageToRow: function(inPageIndex){
+ return (this.rowsPerPage ? this.rowsPerPage * inPageIndex : inPageIndex);
+ },
+
+ _preparePage: function(inRowIndex){
+ if((inRowIndex < this._bop || inRowIndex >= this._eop) && !this._addingItem){
+ var pageIndex = this._rowToPage(inRowIndex);
+ this._needPage(pageIndex);
+ this._bop = pageIndex * this.rowsPerPage;
+ this._eop = this._bop + (this.rowsPerPage || this.get('rowCount'));
+ }
+ },
+
+ _needPage: function(inPageIndex){
+ if(!this._pages[inPageIndex]){
+ this._pages[inPageIndex] = true;
+ this._requestPage(inPageIndex);
+ }
+ },
+
+ _requestPage: function(inPageIndex){
+ var row = this._pageToRow(inPageIndex);
+ var count = Math.min(this.rowsPerPage, this.get('rowCount') - row);
+ if(count > 0){
+ this._requests++;
+ if(!this._requestsPending(row)){
+ setTimeout(dojo.hitch(this, "_fetch", row, false), 1);
+ //this.requestRows(row, count);
+ }
+ }
+ },
+
+ getCellName: function(inCell){
+ return inCell.field;
+ //console.log(inCell);
+ },
+
+ _refresh: function(isRender){
+ this._clearData();
+ this._fetch(0, isRender);
+ },
+
+ sort: function(){
+ this.edit.apply();
+ this._lastScrollTop = this.scrollTop;
+ this._refresh();
+ },
+
+ canSort: function(){
+ return (!this._isLoading);
+ },
+
+ getSortProps: function(){
+ var c = this.getCell(this.getSortIndex());
+ if(!c){
+ if(this.sortFields){
+ return this.sortFields;
+ }
+ return null;
+ }else{
+ var desc = c["sortDesc"];
+ var si = !(this.sortInfo>0);
+ if(typeof desc == "undefined"){
+ desc = si;
+ }else{
+ desc = si ? !desc : desc;
+ }
+ return [{ attribute: c.field, descending: desc }];
+ }
+ },
+
+ styleRowState: function(inRow){
+ // summary: Perform row styling
+ if(this.store && this.store.getState){
+ var states=this.store.getState(inRow.index), c='';
+ for(var i=0, ss=["inflight", "error", "inserting"], s; s=ss[i]; i++){
+ if(states[s]){
+ c = ' dojoxGridRow-' + s;
+ break;
+ }
+ }
+ inRow.customClasses += c;
+ }
+ },
+
+ onStyleRow: function(inRow){
+ this.styleRowState(inRow);
+ this.inherited(arguments);
+ },
+
+ // editing
+ canEdit: function(inCell, inRowIndex){
+ return this._canEdit;
+ },
+
+ _copyAttr: function(idx, attr){
+ var row = {};
+ var backstop = {};
+ var src = this.getItem(idx);
+ return this.store.getValue(src, attr);
+ },
+
+ doStartEdit: function(inCell, inRowIndex){
+ if(!this._cache[inRowIndex]){
+ this._cache[inRowIndex] = this._copyAttr(inRowIndex, inCell.field);
+ }
+ this.onStartEdit(inCell, inRowIndex);
+ },
+
+ doApplyCellEdit: function(inValue, inRowIndex, inAttrName){
+ this.store.fetchItemByIdentity({
+ identity: this._by_idx[inRowIndex].idty,
+ onItem: dojo.hitch(this, function(item){
+ var oldValue = this.store.getValue(item, inAttrName);
+ if(typeof oldValue == 'number'){
+ inValue = isNaN(inValue) ? inValue : parseFloat(inValue);
+ }else if(typeof oldValue == 'boolean'){
+ inValue = inValue == 'true' ? true : inValue == 'false' ? false : inValue;
+ }else if(oldValue instanceof Date){
+ var asDate = new Date(inValue);
+ inValue = isNaN(asDate.getTime()) ? inValue : asDate;
+ }
+ this.store.setValue(item, inAttrName, inValue);
+ this.onApplyCellEdit(inValue, inRowIndex, inAttrName);
+ })
+ });
+ },
+
+ doCancelEdit: function(inRowIndex){
+ var cache = this._cache[inRowIndex];
+ if(cache){
+ this.updateRow(inRowIndex);
+ delete this._cache[inRowIndex];
+ }
+ this.onCancelEdit.apply(this, arguments);
+ },
+
+ doApplyEdit: function(inRowIndex, inDataAttr){
+ var cache = this._cache[inRowIndex];
+ /*if(cache){
+ var data = this.getItem(inRowIndex);
+ if(this.store.getValue(data, inDataAttr) != cache){
+ this.update(cache, data, inRowIndex);
+ }
+ delete this._cache[inRowIndex];
+ }*/
+ this.onApplyEdit(inRowIndex);
+ },
+
+ removeSelectedRows: function(){
+ // summary:
+ // Remove the selected rows from the grid.
+ if(this._canEdit){
+ this.edit.apply();
+ var fx = dojo.hitch(this, function(items){
+ if(items.length){
+ dojo.forEach(items, this.store.deleteItem, this.store);
+ this.selection.clear();
+ }
+ });
+ if(this.allItemsSelected){
+ this.store.fetch({
+ query: this.query,
+ queryOptions: this.queryOptions,
+ onComplete: fx});
+ }else{
+ fx(this.selection.getSelected());
+ }
+ }
+ }
+});
+
+dojox.grid.DataGrid.cell_markupFactory = function(cellFunc, node, cellDef){
+ var field = dojo.trim(dojo.attr(node, "field")||"");
+ if(field){
+ cellDef.field = field;
+ }
+ cellDef.field = cellDef.field||cellDef.name;
+ var fields = dojo.trim(dojo.attr(node, "fields")||"");
+ if(fields){
+ cellDef.fields = fields.split(",");
+ }
+ if(cellFunc){
+ cellFunc(node, cellDef);
+ }
+};
+
+dojox.grid.DataGrid.markupFactory = function(props, node, ctor, cellFunc){
+ return dojox.grid._Grid.markupFactory(props, node, ctor,
+ dojo.partial(dojox.grid.DataGrid.cell_markupFactory, cellFunc));
+};
+
+}
+
+
+dojo.i18n._preloadLocalizations("dojox.grid.nls.DataGrid", ["ROOT","ar","ca","cs","da","de","de-de","el","en","en-gb","en-us","es","es-es","fi","fi-fi","fr","fr-fr","he","he-il","hu","it","it-it","ja","ja-jp","ko","ko-kr","nb","nl","nl-nl","pl","pt","pt-br","pt-pt","ru","sk","sl","sv","th","tr","xx","zh","zh-cn","zh-tw"]);
diff --git a/js/dojo-1.6/dojox/grid/DataGrid.xd.js b/js/dojo-1.6/dojox/grid/DataGrid.xd.js
new file mode 100644
index 0000000..f67fdb0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/DataGrid.xd.js
@@ -0,0 +1,14 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+/*
+ This is an optimized version of Dojo, built for deployment and not for
+ development. To get sources and documentation, please visit:
+
+ http://dojotoolkit.org
+*/
+
+dojo._xdResourceLoaded(function(_1,_2,_3){return {depends:[["provide","dojo.window"],["provide","dijit._base.manager"],["provide","dijit._base.focus"],["provide","dojo.AdapterRegistry"],["provide","dijit._base.place"],["provide","dijit._base.window"],["provide","dijit._base.popup"],["provide","dijit._base.scroll"],["provide","dojo.uacss"],["provide","dijit._base.sniff"],["provide","dijit._base.typematic"],["provide","dijit._base.wai"],["provide","dijit._base"],["provide","dojo.date.stamp"],["provide","dojo.parser"],["provide","dojo.Stateful"],["provide","dijit._WidgetBase"],["provide","dijit._Widget"],["provide","dojo.string"],["provide","dojo.cache"],["provide","dijit._Templated"],["provide","dijit._Container"],["provide","dijit._Contained"],["provide","dijit.layout._LayoutWidget"],["provide","dijit._CssStateMixin"],["provide","dijit.form._FormWidget"],["provide","dijit.dijit"],["provide","dijit._KeyNavContainer"],["provide","dijit.MenuItem"],["provide","dijit.PopupMenuItem"],["provide","dijit.CheckedMenuItem"],["provide","dijit.MenuSeparator"],["provide","dijit.Menu"],["provide","dojox.html.metrics"],["provide","dojox.grid.util"],["provide","dojox.grid._Scroller"],["provide","dojox.grid.cells._base"],["provide","dojox.grid.cells"],["provide","dojo.dnd.common"],["provide","dojo.dnd.autoscroll"],["provide","dojo.dnd.Mover"],["provide","dojo.dnd.Moveable"],["provide","dojox.grid._Builder"],["provide","dojo.dnd.Container"],["provide","dojo.dnd.Selector"],["provide","dojo.dnd.Avatar"],["provide","dojo.dnd.Manager"],["provide","dojo.dnd.Source"],["provide","dojox.grid._View"],["provide","dojox.grid._RowSelector"],["provide","dojox.grid._Layout"],["provide","dojox.grid._ViewManager"],["provide","dojox.grid._RowManager"],["provide","dojox.grid._FocusManager"],["provide","dojox.grid._EditManager"],["provide","dojox.grid.Selection"],["provide","dojox.grid._Events"],["provide","dojox.grid._Grid"],["provide","dojox.grid.DataSelection"],["provide","dojox.grid.DataGrid"],["i18n._preloadLocalizations","dojox.grid.nls.DataGrid",["ROOT","ar","ca","cs","da","de","de-de","el","en","en-gb","en-us","es","es-es","fi","fi-fi","fr","fr-fr","he","he-il","hu","it","it-it","ja","ja-jp","ko","ko-kr","nb","nl","nl-nl","pl","pt","pt-br","pt-pt","ru","sk","sl","sv","th","tr","xx","zh","zh-cn","zh-tw"]]],defineResource:function(_4,_5,_6){if(!_4._hasResource["dojo.window"]){_4._hasResource["dojo.window"]=true;_4.provide("dojo.window");_4.getObject("window",true,_4);_4.window.getBox=function(){var _7=(_4.doc.compatMode=="BackCompat")?_4.body():_4.doc.documentElement;var _8=_4._docScroll();return {w:_7.clientWidth,h:_7.clientHeight,l:_8.x,t:_8.y};};_4.window.get=function(_9){if(_4.isIE&&window!==document.parentWindow){_9.parentWindow.execScript("document._parentWindow = window;","Javascript");var _a=_9._parentWindow;_9._parentWindow=null;return _a;}return _9.parentWindow||_9.defaultView;};_4.window.scrollIntoView=function(_b,_c){try{_b=_4.byId(_b);var _d=_b.ownerDocument||_4.doc,_e=_d.body||_4.body(),_f=_d.documentElement||_e.parentNode,_10=_4.isIE,_11=_4.isWebKit;if((!(_4.isMoz||_10||_11||_4.isOpera)||_b==_e||_b==_f)&&(typeof _b.scrollIntoView!="undefined")){_b.scrollIntoView(false);return;}var _12=_d.compatMode=="BackCompat",_13=_12?_e:_f,_14=_11?_e:_13,_15=_13.clientWidth,_16=_13.clientHeight,rtl=!_4._isBodyLtr(),_17=_c||_4.position(_b),el=_b.parentNode,_18=function(el){return ((_10<=6||(_10&&_12))?false:(_4.style(el,"position").toLowerCase()=="fixed"));};if(_18(_b)){return;}while(el){if(el==_e){el=_14;}var _19=_4.position(el),_1a=_18(el);if(el==_14){_19.w=_15;_19.h=_16;if(_14==_f&&_10&&rtl){_19.x+=_14.offsetWidth-_19.w;}if(_19.x<0||!_10){_19.x=0;}if(_19.y<0||!_10){_19.y=0;}}else{var pb=_4._getPadBorderExtents(el);_19.w-=pb.w;_19.h-=pb.h;_19.x+=pb.l;_19.y+=pb.t;}if(el!=_14){var _1b=el.clientWidth,_1c=_19.w-_1b;if(_1b>0&&_1c>0){_19.w=_1b;if(_10&&rtl){_19.x+=_1c;}}_1b=el.clientHeight;_1c=_19.h-_1b;if(_1b>0&&_1c>0){_19.h=_1b;}}if(_1a){if(_19.y<0){_19.h+=_19.y;_19.y=0;}if(_19.x<0){_19.w+=_19.x;_19.x=0;}if(_19.y+_19.h>_16){_19.h=_16-_19.y;}if(_19.x+_19.w>_15){_19.w=_15-_19.x;}}var l=_17.x-_19.x,t=_17.y-Math.max(_19.y,0),r=l+_17.w-_19.w,bot=t+_17.h-_19.h;if(r*l>0){var s=Math[l<0?"max":"min"](l,r);_17.x+=el.scrollLeft;el.scrollLeft+=(_10>=8&&!_12&&rtl)?-s:s;_17.x-=el.scrollLeft;}if(bot*t>0){_17.y+=el.scrollTop;el.scrollTop+=Math[t<0?"max":"min"](t,bot);_17.y-=el.scrollTop;}el=(el!=_14)&&!_1a&&el.parentNode;}}catch(error){console.error("scrollIntoView: "+error);_b.scrollIntoView(false);}};}if(!_4._hasResource["dijit._base.manager"]){_4._hasResource["dijit._base.manager"]=true;_4.provide("dijit._base.manager");_4.declare("dijit.WidgetSet",null,{constructor:function(){this._hash={};this.length=0;},add:function(_1d){if(this._hash[_1d.id]){throw new Error("Tried to register widget with id=="+_1d.id+" but that id is already registered");}this._hash[_1d.id]=_1d;this.length++;},remove:function(id){if(this._hash[id]){delete this._hash[id];this.length--;}},forEach:function(_1e,_1f){_1f=_1f||_4.global;var i=0,id;for(id in this._hash){_1e.call(_1f,this._hash[id],i++,this._hash);}return this;},filter:function(_20,_21){_21=_21||_4.global;var res=new _5.WidgetSet(),i=0,id;for(id in this._hash){var w=this._hash[id];if(_20.call(_21,w,i++,this._hash)){res.add(w);}}return res;},byId:function(id){return this._hash[id];},byClass:function(cls){var res=new _5.WidgetSet(),id,_22;for(id in this._hash){_22=this._hash[id];if(_22.declaredClass==cls){res.add(_22);}}return res;},toArray:function(){var ar=[];for(var id in this._hash){ar.push(this._hash[id]);}return ar;},map:function(_23,_24){return _4.map(this.toArray(),_23,_24);},every:function(_25,_26){_26=_26||_4.global;var x=0,i;for(i in this._hash){if(!_25.call(_26,this._hash[i],x++,this._hash)){return false;}}return true;},some:function(_27,_28){_28=_28||_4.global;var x=0,i;for(i in this._hash){if(_27.call(_28,this._hash[i],x++,this._hash)){return true;}}return false;}});(function(){_5.registry=new _5.WidgetSet();var _29=_5.registry._hash,_2a=_4.attr,_2b=_4.hasAttr,_2c=_4.style;_5.byId=function(id){return typeof id=="string"?_29[id]:id;};var _2d={};_5.getUniqueId=function(_2e){var id;do{id=_2e+"_"+(_2e in _2d?++_2d[_2e]:_2d[_2e]=0);}while(_29[id]);return _5._scopeName=="dijit"?id:_5._scopeName+"_"+id;};_5.findWidgets=function(_2f){var _30=[];function _31(_32){for(var _33=_32.firstChild;_33;_33=_33.nextSibling){if(_33.nodeType==1){var _34=_33.getAttribute("widgetId");if(_34){var _35=_29[_34];if(_35){_30.push(_35);}}else{_31(_33);}}}};_31(_2f);return _30;};_5._destroyAll=function(){_5._curFocus=null;_5._prevFocus=null;_5._activeStack=[];_4.forEach(_5.findWidgets(_4.body()),function(_36){if(!_36._destroyed){if(_36.destroyRecursive){_36.destroyRecursive();}else{if(_36.destroy){_36.destroy();}}}});};if(_4.isIE){_4.addOnWindowUnload(function(){_5._destroyAll();});}_5.byNode=function(_37){return _29[_37.getAttribute("widgetId")];};_5.getEnclosingWidget=function(_38){while(_38){var id=_38.getAttribute&&_38.getAttribute("widgetId");if(id){return _29[id];}_38=_38.parentNode;}return null;};var _39=(_5._isElementShown=function(_3a){var s=_2c(_3a);return (s.visibility!="hidden")&&(s.visibility!="collapsed")&&(s.display!="none")&&(_2a(_3a,"type")!="hidden");});_5.hasDefaultTabStop=function(_3b){switch(_3b.nodeName.toLowerCase()){case "a":return _2b(_3b,"href");case "area":case "button":case "input":case "object":case "select":case "textarea":return true;case "iframe":var _3c;try{var _3d=_3b.contentDocument;if("designMode" in _3d&&_3d.designMode=="on"){return true;}_3c=_3d.body;}catch(e1){try{_3c=_3b.contentWindow.document.body;}catch(e2){return false;}}return _3c.contentEditable=="true"||(_3c.firstChild&&_3c.firstChild.contentEditable=="true");default:return _3b.contentEditable=="true";}};var _3e=(_5.isTabNavigable=function(_3f){if(_2a(_3f,"disabled")){return false;}else{if(_2b(_3f,"tabIndex")){return _2a(_3f,"tabIndex")>=0;}else{return _5.hasDefaultTabStop(_3f);}}});_5._getTabNavigable=function(_40){var _41,_42,_43,_44,_45,_46,_47={};function _48(_49){return _49&&_49.tagName.toLowerCase()=="input"&&_49.type&&_49.type.toLowerCase()=="radio"&&_49.name&&_49.name.toLowerCase();};var _4a=function(_4b){_4.query("> *",_4b).forEach(function(_4c){if((_4.isIE&&_4c.scopeName!=="HTML")||!_39(_4c)){return;}if(_3e(_4c)){var _4d=_2a(_4c,"tabIndex");if(!_2b(_4c,"tabIndex")||_4d==0){if(!_41){_41=_4c;}_42=_4c;}else{if(_4d>0){if(!_43||_4d<_44){_44=_4d;_43=_4c;}if(!_45||_4d>=_46){_46=_4d;_45=_4c;}}}var rn=_48(_4c);if(_4.attr(_4c,"checked")&&rn){_47[rn]=_4c;}}if(_4c.nodeName.toUpperCase()!="SELECT"){_4a(_4c);}});};if(_39(_40)){_4a(_40);}function rs(_4e){return _47[_48(_4e)]||_4e;};return {first:rs(_41),last:rs(_42),lowest:rs(_43),highest:rs(_45)};};_5.getFirstInTabbingOrder=function(_4f){var _50=_5._getTabNavigable(_4.byId(_4f));return _50.lowest?_50.lowest:_50.first;};_5.getLastInTabbingOrder=function(_51){var _52=_5._getTabNavigable(_4.byId(_51));return _52.last?_52.last:_52.highest;};_5.defaultDuration=_4.config["defaultDuration"]||200;})();}if(!_4._hasResource["dijit._base.focus"]){_4._hasResource["dijit._base.focus"]=true;_4.provide("dijit._base.focus");_4.mixin(_5,{_curFocus:null,_prevFocus:null,isCollapsed:function(){return _5.getBookmark().isCollapsed;},getBookmark:function(){var bm,rg,tg,sel=_4.doc.selection,cf=_5._curFocus;if(_4.global.getSelection){sel=_4.global.getSelection();if(sel){if(sel.isCollapsed){tg=cf?cf.tagName:"";if(tg){tg=tg.toLowerCase();if(tg=="textarea"||(tg=="input"&&(!cf.type||cf.type.toLowerCase()=="text"))){sel={start:cf.selectionStart,end:cf.selectionEnd,node:cf,pRange:true};return {isCollapsed:(sel.end<=sel.start),mark:sel};}}bm={isCollapsed:true};}else{rg=sel.getRangeAt(0);bm={isCollapsed:false,mark:rg.cloneRange()};}}}else{if(sel){tg=cf?cf.tagName:"";tg=tg.toLowerCase();if(cf&&tg&&(tg=="button"||tg=="textarea"||tg=="input")){if(sel.type&&sel.type.toLowerCase()=="none"){return {isCollapsed:true,mark:null};}else{rg=sel.createRange();return {isCollapsed:rg.text&&rg.text.length?false:true,mark:{range:rg,pRange:true}};}}bm={};try{rg=sel.createRange();bm.isCollapsed=!(sel.type=="Text"?rg.htmlText.length:rg.length);}catch(e){bm.isCollapsed=true;return bm;}if(sel.type.toUpperCase()=="CONTROL"){if(rg.length){bm.mark=[];var i=0,len=rg.length;while(i<len){bm.mark.push(rg.item(i++));}}else{bm.isCollapsed=true;bm.mark=null;}}else{bm.mark=rg.getBookmark();}}else{console.warn("No idea how to store the current selection for this browser!");}}return bm;},moveToBookmark:function(_53){var _54=_4.doc,_55=_53.mark;if(_55){if(_4.global.getSelection){var sel=_4.global.getSelection();if(sel&&sel.removeAllRanges){if(_55.pRange){var r=_55;var n=r.node;n.selectionStart=r.start;n.selectionEnd=r.end;}else{sel.removeAllRanges();sel.addRange(_55);}}else{console.warn("No idea how to restore selection for this browser!");}}else{if(_54.selection&&_55){var rg;if(_55.pRange){rg=_55.range;}else{if(_4.isArray(_55)){rg=_54.body.createControlRange();_4.forEach(_55,function(n){rg.addElement(n);});}else{rg=_54.body.createTextRange();rg.moveToBookmark(_55);}}rg.select();}}}},getFocus:function(_56,_57){var _58=!_5._curFocus||(_56&&_4.isDescendant(_5._curFocus,_56.domNode))?_5._prevFocus:_5._curFocus;return {node:_58,bookmark:(_58==_5._curFocus)&&_4.withGlobal(_57||_4.global,_5.getBookmark),openedForWindow:_57};},focus:function(_59){if(!_59){return;}var _5a="node" in _59?_59.node:_59,_5b=_59.bookmark,_5c=_59.openedForWindow,_5d=_5b?_5b.isCollapsed:false;if(_5a){var _5e=(_5a.tagName.toLowerCase()=="iframe")?_5a.contentWindow:_5a;if(_5e&&_5e.focus){try{_5e.focus();}catch(e){}}_5._onFocusNode(_5a);}if(_5b&&_4.withGlobal(_5c||_4.global,_5.isCollapsed)&&!_5d){if(_5c){_5c.focus();}try{_4.withGlobal(_5c||_4.global,_5.moveToBookmark,null,[_5b]);}catch(e2){}}},_activeStack:[],registerIframe:function(_5f){return _5.registerWin(_5f.contentWindow,_5f);},unregisterIframe:function(_60){_5.unregisterWin(_60);},registerWin:function(_61,_62){var _63=function(evt){_5._justMouseDowned=true;setTimeout(function(){_5._justMouseDowned=false;},0);if(_4.isIE&&evt&&evt.srcElement&&evt.srcElement.parentNode==null){return;}_5._onTouchNode(_62||evt.target||evt.srcElement,"mouse");};var doc=_4.isIE?_61.document.documentElement:_61.document;if(doc){if(_4.isIE){_61.document.body.attachEvent("onmousedown",_63);var _64=function(evt){if(evt.srcElement.tagName.toLowerCase()!="#document"&&_5.isTabNavigable(evt.srcElement)){_5._onFocusNode(_62||evt.srcElement);}else{_5._onTouchNode(_62||evt.srcElement);}};doc.attachEvent("onactivate",_64);var _65=function(evt){_5._onBlurNode(_62||evt.srcElement);};doc.attachEvent("ondeactivate",_65);return function(){_61.document.detachEvent("onmousedown",_63);doc.detachEvent("onactivate",_64);doc.detachEvent("ondeactivate",_65);doc=null;};}else{doc.body.addEventListener("mousedown",_63,true);var _66=function(evt){_5._onFocusNode(_62||evt.target);};doc.addEventListener("focus",_66,true);var _67=function(evt){_5._onBlurNode(_62||evt.target);};doc.addEventListener("blur",_67,true);return function(){doc.body.removeEventListener("mousedown",_63,true);doc.removeEventListener("focus",_66,true);doc.removeEventListener("blur",_67,true);doc=null;};}}},unregisterWin:function(_68){_68&&_68();},_onBlurNode:function(_69){_5._prevFocus=_5._curFocus;_5._curFocus=null;if(_5._justMouseDowned){return;}if(_5._clearActiveWidgetsTimer){clearTimeout(_5._clearActiveWidgetsTimer);}_5._clearActiveWidgetsTimer=setTimeout(function(){delete _5._clearActiveWidgetsTimer;_5._setStack([]);_5._prevFocus=null;},100);},_onTouchNode:function(_6a,by){if(_5._clearActiveWidgetsTimer){clearTimeout(_5._clearActiveWidgetsTimer);delete _5._clearActiveWidgetsTimer;}var _6b=[];try{while(_6a){var _6c=_4.attr(_6a,"dijitPopupParent");if(_6c){_6a=_5.byId(_6c).domNode;}else{if(_6a.tagName&&_6a.tagName.toLowerCase()=="body"){if(_6a===_4.body()){break;}_6a=_4.window.get(_6a.ownerDocument).frameElement;}else{var id=_6a.getAttribute&&_6a.getAttribute("widgetId"),_6d=id&&_5.byId(id);if(_6d&&!(by=="mouse"&&_6d.get("disabled"))){_6b.unshift(id);}_6a=_6a.parentNode;}}}}catch(e){}_5._setStack(_6b,by);},_onFocusNode:function(_6e){if(!_6e){return;}if(_6e.nodeType==9){return;}_5._onTouchNode(_6e);if(_6e==_5._curFocus){return;}if(_5._curFocus){_5._prevFocus=_5._curFocus;}_5._curFocus=_6e;_4.publish("focusNode",[_6e]);},_setStack:function(_6f,by){var _70=_5._activeStack;_5._activeStack=_6f;for(var _71=0;_71<Math.min(_70.length,_6f.length);_71++){if(_70[_71]!=_6f[_71]){break;}}var _72;for(var i=_70.length-1;i>=_71;i--){_72=_5.byId(_70[i]);if(_72){_72._focused=false;_72.set("focused",false);_72._hasBeenBlurred=true;if(_72._onBlur){_72._onBlur(by);}_4.publish("widgetBlur",[_72,by]);}}for(i=_71;i<_6f.length;i++){_72=_5.byId(_6f[i]);if(_72){_72._focused=true;_72.set("focused",true);if(_72._onFocus){_72._onFocus(by);}_4.publish("widgetFocus",[_72,by]);}}}});_4.addOnLoad(function(){var _73=_5.registerWin(window);if(_4.isIE){_4.addOnWindowUnload(function(){_5.unregisterWin(_73);_73=null;});}});}if(!_4._hasResource["dojo.AdapterRegistry"]){_4._hasResource["dojo.AdapterRegistry"]=true;_4.provide("dojo.AdapterRegistry");_4.AdapterRegistry=function(_74){this.pairs=[];this.returnWrappers=_74||false;};_4.extend(_4.AdapterRegistry,{register:function(_75,_76,_77,_78,_79){this.pairs[((_79)?"unshift":"push")]([_75,_76,_77,_78]);},match:function(){for(var i=0;i<this.pairs.length;i++){var _7a=this.pairs[i];if(_7a[1].apply(this,arguments)){if((_7a[3])||(this.returnWrappers)){return _7a[2];}else{return _7a[2].apply(this,arguments);}}}throw new Error("No match found");},unregister:function(_7b){for(var i=0;i<this.pairs.length;i++){var _7c=this.pairs[i];if(_7c[0]==_7b){this.pairs.splice(i,1);return true;}}return false;}});}if(!_4._hasResource["dijit._base.place"]){_4._hasResource["dijit._base.place"]=true;_4.provide("dijit._base.place");_5.getViewport=function(){return _4.window.getBox();};_5.placeOnScreen=function(_7d,pos,_7e,_7f){var _80=_4.map(_7e,function(_81){var c={corner:_81,pos:{x:pos.x,y:pos.y}};if(_7f){c.pos.x+=_81.charAt(1)=="L"?_7f.x:-_7f.x;c.pos.y+=_81.charAt(0)=="T"?_7f.y:-_7f.y;}return c;});return _5._place(_7d,_80);};_5._place=function(_82,_83,_84,_85){var _86=_4.window.getBox();if(!_82.parentNode||String(_82.parentNode.tagName).toLowerCase()!="body"){_4.body().appendChild(_82);}var _87=null;_4.some(_83,function(_88){var _89=_88.corner;var pos=_88.pos;var _8a=0;var _8b={w:_89.charAt(1)=="L"?(_86.l+_86.w)-pos.x:pos.x-_86.l,h:_89.charAt(1)=="T"?(_86.t+_86.h)-pos.y:pos.y-_86.t};if(_84){var res=_84(_82,_88.aroundCorner,_89,_8b,_85);_8a=typeof res=="undefined"?0:res;}var _8c=_82.style;var _8d=_8c.display;var _8e=_8c.visibility;_8c.visibility="hidden";_8c.display="";var mb=_4.marginBox(_82);_8c.display=_8d;_8c.visibility=_8e;var _8f=Math.max(_86.l,_89.charAt(1)=="L"?pos.x:(pos.x-mb.w)),_90=Math.max(_86.t,_89.charAt(0)=="T"?pos.y:(pos.y-mb.h)),_91=Math.min(_86.l+_86.w,_89.charAt(1)=="L"?(_8f+mb.w):pos.x),_92=Math.min(_86.t+_86.h,_89.charAt(0)=="T"?(_90+mb.h):pos.y),_93=_91-_8f,_94=_92-_90;_8a+=(mb.w-_93)+(mb.h-_94);if(_87==null||_8a<_87.overflow){_87={corner:_89,aroundCorner:_88.aroundCorner,x:_8f,y:_90,w:_93,h:_94,overflow:_8a,spaceAvailable:_8b};}return !_8a;});if(_87.overflow&&_84){_84(_82,_87.aroundCorner,_87.corner,_87.spaceAvailable,_85);}var l=_4._isBodyLtr(),s=_82.style;s.top=_87.y+"px";s[l?"left":"right"]=(l?_87.x:_86.w-_87.x-_87.w)+"px";return _87;};_5.placeOnScreenAroundNode=function(_95,_96,_97,_98){_96=_4.byId(_96);var _99=_4.position(_96,true);return _5._placeOnScreenAroundRect(_95,_99.x,_99.y,_99.w,_99.h,_97,_98);};_5.placeOnScreenAroundRectangle=function(_9a,_9b,_9c,_9d){return _5._placeOnScreenAroundRect(_9a,_9b.x,_9b.y,_9b.width,_9b.height,_9c,_9d);};_5._placeOnScreenAroundRect=function(_9e,x,y,_9f,_a0,_a1,_a2){var _a3=[];for(var _a4 in _a1){_a3.push({aroundCorner:_a4,corner:_a1[_a4],pos:{x:x+(_a4.charAt(1)=="L"?0:_9f),y:y+(_a4.charAt(0)=="T"?0:_a0)}});}return _5._place(_9e,_a3,_a2,{w:_9f,h:_a0});};_5.placementRegistry=new _4.AdapterRegistry();_5.placementRegistry.register("node",function(n,x){return typeof x=="object"&&typeof x.offsetWidth!="undefined"&&typeof x.offsetHeight!="undefined";},_5.placeOnScreenAroundNode);_5.placementRegistry.register("rect",function(n,x){return typeof x=="object"&&"x" in x&&"y" in x&&"width" in x&&"height" in x;},_5.placeOnScreenAroundRectangle);_5.placeOnScreenAroundElement=function(_a5,_a6,_a7,_a8){return _5.placementRegistry.match.apply(_5.placementRegistry,arguments);};_5.getPopupAroundAlignment=function(_a9,_aa){var _ab={};_4.forEach(_a9,function(pos){switch(pos){case "after":_ab[_aa?"BR":"BL"]=_aa?"BL":"BR";break;case "before":_ab[_aa?"BL":"BR"]=_aa?"BR":"BL";break;case "below-alt":_aa=!_aa;case "below":_ab[_aa?"BL":"BR"]=_aa?"TL":"TR";_ab[_aa?"BR":"BL"]=_aa?"TR":"TL";break;case "above-alt":_aa=!_aa;case "above":default:_ab[_aa?"TL":"TR"]=_aa?"BL":"BR";_ab[_aa?"TR":"TL"]=_aa?"BR":"BL";break;}});return _ab;};}if(!_4._hasResource["dijit._base.window"]){_4._hasResource["dijit._base.window"]=true;_4.provide("dijit._base.window");_5.getDocumentWindow=function(doc){return _4.window.get(doc);};}if(!_4._hasResource["dijit._base.popup"]){_4._hasResource["dijit._base.popup"]=true;_4.provide("dijit._base.popup");_5.popup={_stack:[],_beginZIndex:1000,_idGen:1,_createWrapper:function(_ac){var _ad=_ac.declaredClass?_ac._popupWrapper:(_4.hasClass(_ac.parentNode,"dijitPopup")&&_ac.parentNode),_ae=_ac.domNode||_ac;if(!_ad){_ad=_4.create("div",{"class":"dijitPopup",style:{display:"none"},role:"presentation"},_4.body());_ad.appendChild(_ae);var s=_ae.style;s.display="";s.visibility="";s.position="";s.top="0px";if(_ac.declaredClass){_ac._popupWrapper=_ad;_4.connect(_ac,"destroy",function(){_4.destroy(_ad);delete _ac._popupWrapper;});}}return _ad;},moveOffScreen:function(_af){var _b0=this._createWrapper(_af);_4.style(_b0,{visibility:"hidden",top:"-9999px",display:""});},hide:function(_b1){var _b2=this._createWrapper(_b1);_4.style(_b2,"display","none");},getTopPopup:function(){var _b3=this._stack;for(var pi=_b3.length-1;pi>0&&_b3[pi].parent===_b3[pi-1].widget;pi--){}return _b3[pi];},open:function(_b4){var _b5=this._stack,_b6=_b4.popup,_b7=_b4.orient||((_b4.parent?_b4.parent.isLeftToRight():_4._isBodyLtr())?{"BL":"TL","BR":"TR","TL":"BL","TR":"BR"}:{"BR":"TR","BL":"TL","TR":"BR","TL":"BL"}),_b8=_b4.around,id=(_b4.around&&_b4.around.id)?(_b4.around.id+"_dropdown"):("popup_"+this._idGen++);while(_b5.length&&(!_b4.parent||!_4.isDescendant(_b4.parent.domNode,_b5[_b5.length-1].widget.domNode))){_5.popup.close(_b5[_b5.length-1].widget);}var _b9=this._createWrapper(_b6);_4.attr(_b9,{id:id,style:{zIndex:this._beginZIndex+_b5.length},"class":"dijitPopup "+(_b6.baseClass||_b6["class"]||"").split(" ")[0]+"Popup",dijitPopupParent:_b4.parent?_b4.parent.id:""});if(_4.isIE||_4.isMoz){if(!_b6.bgIframe){_b6.bgIframe=new _5.BackgroundIframe(_b9);}}var _ba=_b8?_5.placeOnScreenAroundElement(_b9,_b8,_b7,_b6.orient?_4.hitch(_b6,"orient"):null):_5.placeOnScreen(_b9,_b4,_b7=="R"?["TR","BR","TL","BL"]:["TL","BL","TR","BR"],_b4.padding);_b9.style.display="";_b9.style.visibility="visible";_b6.domNode.style.visibility="visible";var _bb=[];_bb.push(_4.connect(_b9,"onkeypress",this,function(evt){if(evt.charOrCode==_4.keys.ESCAPE&&_b4.onCancel){_4.stopEvent(evt);_b4.onCancel();}else{if(evt.charOrCode===_4.keys.TAB){_4.stopEvent(evt);var _bc=this.getTopPopup();if(_bc&&_bc.onCancel){_bc.onCancel();}}}}));if(_b6.onCancel){_bb.push(_4.connect(_b6,"onCancel",_b4.onCancel));}_bb.push(_4.connect(_b6,_b6.onExecute?"onExecute":"onChange",this,function(){var _bd=this.getTopPopup();if(_bd&&_bd.onExecute){_bd.onExecute();}}));_b5.push({widget:_b6,parent:_b4.parent,onExecute:_b4.onExecute,onCancel:_b4.onCancel,onClose:_b4.onClose,handlers:_bb});if(_b6.onOpen){_b6.onOpen(_ba);}return _ba;},close:function(_be){var _bf=this._stack;while((_be&&_4.some(_bf,function(_c0){return _c0.widget==_be;}))||(!_be&&_bf.length)){var top=_bf.pop(),_c1=top.widget,_c2=top.onClose;if(_c1.onClose){_c1.onClose();}_4.forEach(top.handlers,_4.disconnect);if(_c1&&_c1.domNode){this.hide(_c1);}if(_c2){_c2();}}}};_5._frames=new function(){var _c3=[];this.pop=function(){var _c4;if(_c3.length){_c4=_c3.pop();_c4.style.display="";}else{if(_4.isIE<9){var _c5=_4.config["dojoBlankHtmlUrl"]||(_4.moduleUrl("dojo","resources/blank.html")+"")||"javascript:\"\"";var _c6="<iframe src='"+_c5+"'"+" style='position: absolute; left: 0px; top: 0px;"+"z-index: -1; filter:Alpha(Opacity=\"0\");'>";_c4=_4.doc.createElement(_c6);}else{_c4=_4.create("iframe");_c4.src="javascript:\"\"";_c4.className="dijitBackgroundIframe";_4.style(_c4,"opacity",0.1);}_c4.tabIndex=-1;_5.setWaiRole(_c4,"presentation");}return _c4;};this.push=function(_c7){_c7.style.display="none";_c3.push(_c7);};}();_5.BackgroundIframe=function(_c8){if(!_c8.id){throw new Error("no id");}if(_4.isIE||_4.isMoz){var _c9=(this.iframe=_5._frames.pop());_c8.appendChild(_c9);if(_4.isIE<7||_4.isQuirks){this.resize(_c8);this._conn=_4.connect(_c8,"onresize",this,function(){this.resize(_c8);});}else{_4.style(_c9,{width:"100%",height:"100%"});}}};_4.extend(_5.BackgroundIframe,{resize:function(_ca){if(this.iframe){_4.style(this.iframe,{width:_ca.offsetWidth+"px",height:_ca.offsetHeight+"px"});}},destroy:function(){if(this._conn){_4.disconnect(this._conn);this._conn=null;}if(this.iframe){_5._frames.push(this.iframe);delete this.iframe;}}});}if(!_4._hasResource["dijit._base.scroll"]){_4._hasResource["dijit._base.scroll"]=true;_4.provide("dijit._base.scroll");_5.scrollIntoView=function(_cb,pos){_4.window.scrollIntoView(_cb,pos);};}if(!_4._hasResource["dojo.uacss"]){_4._hasResource["dojo.uacss"]=true;_4.provide("dojo.uacss");(function(){var d=_4,_cc=d.doc.documentElement,ie=d.isIE,_cd=d.isOpera,maj=Math.floor,ff=d.isFF,_ce=d.boxModel.replace(/-/,""),_cf={dj_ie:ie,dj_ie6:maj(ie)==6,dj_ie7:maj(ie)==7,dj_ie8:maj(ie)==8,dj_ie9:maj(ie)==9,dj_quirks:d.isQuirks,dj_iequirks:ie&&d.isQuirks,dj_opera:_cd,dj_khtml:d.isKhtml,dj_webkit:d.isWebKit,dj_safari:d.isSafari,dj_chrome:d.isChrome,dj_gecko:d.isMozilla,dj_ff3:maj(ff)==3};_cf["dj_"+_ce]=true;var _d0="";for(var clz in _cf){if(_cf[clz]){_d0+=clz+" ";}}_cc.className=d.trim(_cc.className+" "+_d0);_4._loaders.unshift(function(){if(!_4._isBodyLtr()){var _d1="dj_rtl dijitRtl "+_d0.replace(/ /g,"-rtl ");_cc.className=d.trim(_cc.className+" "+_d1);}});})();}if(!_4._hasResource["dijit._base.sniff"]){_4._hasResource["dijit._base.sniff"]=true;_4.provide("dijit._base.sniff");}if(!_4._hasResource["dijit._base.typematic"]){_4._hasResource["dijit._base.typematic"]=true;_4.provide("dijit._base.typematic");_5.typematic={_fireEventAndReload:function(){this._timer=null;this._callback(++this._count,this._node,this._evt);this._currentTimeout=Math.max(this._currentTimeout<0?this._initialDelay:(this._subsequentDelay>1?this._subsequentDelay:Math.round(this._currentTimeout*this._subsequentDelay)),this._minDelay);this._timer=setTimeout(_4.hitch(this,"_fireEventAndReload"),this._currentTimeout);},trigger:function(evt,_d2,_d3,_d4,obj,_d5,_d6,_d7){if(obj!=this._obj){this.stop();this._initialDelay=_d6||500;this._subsequentDelay=_d5||0.9;this._minDelay=_d7||10;this._obj=obj;this._evt=evt;this._node=_d3;this._currentTimeout=-1;this._count=-1;this._callback=_4.hitch(_d2,_d4);this._fireEventAndReload();this._evt=_4.mixin({faux:true},evt);}},stop:function(){if(this._timer){clearTimeout(this._timer);this._timer=null;}if(this._obj){this._callback(-1,this._node,this._evt);this._obj=null;}},addKeyListener:function(_d8,_d9,_da,_db,_dc,_dd,_de){if(_d9.keyCode){_d9.charOrCode=_d9.keyCode;_4.deprecated("keyCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.","","2.0");}else{if(_d9.charCode){_d9.charOrCode=String.fromCharCode(_d9.charCode);_4.deprecated("charCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.","","2.0");}}return [_4.connect(_d8,"onkeypress",this,function(evt){if(evt.charOrCode==_d9.charOrCode&&(_d9.ctrlKey===undefined||_d9.ctrlKey==evt.ctrlKey)&&(_d9.altKey===undefined||_d9.altKey==evt.altKey)&&(_d9.metaKey===undefined||_d9.metaKey==(evt.metaKey||false))&&(_d9.shiftKey===undefined||_d9.shiftKey==evt.shiftKey)){_4.stopEvent(evt);_5.typematic.trigger(evt,_da,_d8,_db,_d9,_dc,_dd,_de);}else{if(_5.typematic._obj==_d9){_5.typematic.stop();}}}),_4.connect(_d8,"onkeyup",this,function(evt){if(_5.typematic._obj==_d9){_5.typematic.stop();}})];},addMouseListener:function(_df,_e0,_e1,_e2,_e3,_e4){var dc=_4.connect;return [dc(_df,"mousedown",this,function(evt){_4.stopEvent(evt);_5.typematic.trigger(evt,_e0,_df,_e1,_df,_e2,_e3,_e4);}),dc(_df,"mouseup",this,function(evt){_4.stopEvent(evt);_5.typematic.stop();}),dc(_df,"mouseout",this,function(evt){_4.stopEvent(evt);_5.typematic.stop();}),dc(_df,"mousemove",this,function(evt){evt.preventDefault();}),dc(_df,"dblclick",this,function(evt){_4.stopEvent(evt);if(_4.isIE){_5.typematic.trigger(evt,_e0,_df,_e1,_df,_e2,_e3,_e4);setTimeout(_4.hitch(this,_5.typematic.stop),50);}})];},addListener:function(_e5,_e6,_e7,_e8,_e9,_ea,_eb,_ec){return this.addKeyListener(_e6,_e7,_e8,_e9,_ea,_eb,_ec).concat(this.addMouseListener(_e5,_e8,_e9,_ea,_eb,_ec));}};}if(!_4._hasResource["dijit._base.wai"]){_4._hasResource["dijit._base.wai"]=true;_4.provide("dijit._base.wai");_5.wai={onload:function(){var div=_4.create("div",{id:"a11yTestNode",style:{cssText:"border: 1px solid;"+"border-color:red green;"+"position: absolute;"+"height: 5px;"+"top: -999px;"+"background-image: url(\""+(_4.config.blankGif||_4.moduleUrl("dojo","resources/blank.gif"))+"\");"}},_4.body());var cs=_4.getComputedStyle(div);if(cs){var _ed=cs.backgroundImage;var _ee=(cs.borderTopColor==cs.borderRightColor)||(_ed!=null&&(_ed=="none"||_ed=="url(invalid-url:)"));_4[_ee?"addClass":"removeClass"](_4.body(),"dijit_a11y");if(_4.isIE){div.outerHTML="";}else{_4.body().removeChild(div);}}}};if(_4.isIE||_4.isMoz){_4._loaders.unshift(_5.wai.onload);}_4.mixin(_5,{hasWaiRole:function(_ef,_f0){var _f1=this.getWaiRole(_ef);return _f0?(_f1.indexOf(_f0)>-1):(_f1.length>0);},getWaiRole:function(_f2){return _4.trim((_4.attr(_f2,"role")||"").replace("wairole:",""));},setWaiRole:function(_f3,_f4){_4.attr(_f3,"role",_f4);},removeWaiRole:function(_f5,_f6){var _f7=_4.attr(_f5,"role");if(!_f7){return;}if(_f6){var t=_4.trim((" "+_f7+" ").replace(" "+_f6+" "," "));_4.attr(_f5,"role",t);}else{_f5.removeAttribute("role");}},hasWaiState:function(_f8,_f9){return _f8.hasAttribute?_f8.hasAttribute("aria-"+_f9):!!_f8.getAttribute("aria-"+_f9);},getWaiState:function(_fa,_fb){return _fa.getAttribute("aria-"+_fb)||"";},setWaiState:function(_fc,_fd,_fe){_fc.setAttribute("aria-"+_fd,_fe);},removeWaiState:function(_ff,_100){_ff.removeAttribute("aria-"+_100);}});}if(!_4._hasResource["dijit._base"]){_4._hasResource["dijit._base"]=true;_4.provide("dijit._base");}if(!_4._hasResource["dojo.date.stamp"]){_4._hasResource["dojo.date.stamp"]=true;_4.provide("dojo.date.stamp");_4.getObject("date.stamp",true,_4);_4.date.stamp.fromISOString=function(_101,_102){if(!_4.date.stamp._isoRegExp){_4.date.stamp._isoRegExp=/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(.\d+)?)?((?:[+-](\d{2}):(\d{2}))|Z)?)?$/;}var _103=_4.date.stamp._isoRegExp.exec(_101),_104=null;if(_103){_103.shift();if(_103[1]){_103[1]--;}if(_103[6]){_103[6]*=1000;}if(_102){_102=new Date(_102);_4.forEach(_4.map(["FullYear","Month","Date","Hours","Minutes","Seconds","Milliseconds"],function(prop){return _102["get"+prop]();}),function(_105,_106){_103[_106]=_103[_106]||_105;});}_104=new Date(_103[0]||1970,_103[1]||0,_103[2]||1,_103[3]||0,_103[4]||0,_103[5]||0,_103[6]||0);if(_103[0]<100){_104.setFullYear(_103[0]||1970);}var _107=0,_108=_103[7]&&_103[7].charAt(0);if(_108!="Z"){_107=((_103[8]||0)*60)+(Number(_103[9])||0);if(_108!="-"){_107*=-1;}}if(_108){_107-=_104.getTimezoneOffset();}if(_107){_104.setTime(_104.getTime()+_107*60000);}}return _104;};_4.date.stamp.toISOString=function(_109,_10a){var _10b=function(n){return (n<10)?"0"+n:n;};_10a=_10a||{};var _10c=[],_10d=_10a.zulu?"getUTC":"get",date="";if(_10a.selector!="time"){var year=_109[_10d+"FullYear"]();date=["0000".substr((year+"").length)+year,_10b(_109[_10d+"Month"]()+1),_10b(_109[_10d+"Date"]())].join("-");}_10c.push(date);if(_10a.selector!="date"){var time=[_10b(_109[_10d+"Hours"]()),_10b(_109[_10d+"Minutes"]()),_10b(_109[_10d+"Seconds"]())].join(":");var _10e=_109[_10d+"Milliseconds"]();if(_10a.milliseconds){time+="."+(_10e<100?"0":"")+_10b(_10e);}if(_10a.zulu){time+="Z";}else{if(_10a.selector!="time"){var _10f=_109.getTimezoneOffset();var _110=Math.abs(_10f);time+=(_10f>0?"-":"+")+_10b(Math.floor(_110/60))+":"+_10b(_110%60);}}_10c.push(time);}return _10c.join("T");};}if(!_4._hasResource["dojo.parser"]){_4._hasResource["dojo.parser"]=true;_4.provide("dojo.parser");new Date("X");_4.parser=new function(){var d=_4;function _111(_112){if(d.isString(_112)){return "string";}if(typeof _112=="number"){return "number";}if(typeof _112=="boolean"){return "boolean";}if(d.isFunction(_112)){return "function";}if(d.isArray(_112)){return "array";}if(_112 instanceof Date){return "date";}if(_112 instanceof d._Url){return "url";}return "object";};function _113(_114,type){switch(type){case "string":return _114;case "number":return _114.length?Number(_114):NaN;case "boolean":return typeof _114=="boolean"?_114:!(_114.toLowerCase()=="false");case "function":if(d.isFunction(_114)){_114=_114.toString();_114=d.trim(_114.substring(_114.indexOf("{")+1,_114.length-1));}try{if(_114===""||_114.search(/[^\w\.]+/i)!=-1){return new Function(_114);}else{return d.getObject(_114,false)||new Function(_114);}}catch(e){return new Function();}case "array":return _114?_114.split(/\s*,\s*/):[];case "date":switch(_114){case "":return new Date("");case "now":return new Date();default:return d.date.stamp.fromISOString(_114);}case "url":return d.baseUrl+_114;default:return d.fromJson(_114);}};var _115={},_116={};d.connect(d,"extend",function(){_116={};});function _117(cls,_118){for(var name in cls){if(name.charAt(0)=="_"){continue;}if(name in _115){continue;}_118[name]=_111(cls[name]);}return _118;};function _119(_11a,_11b){var c=_116[_11a];if(!c){var cls=d.getObject(_11a),_11c=null;if(!cls){return null;}if(!_11b){_11c=_117(cls.prototype,{});}c={cls:cls,params:_11c};}else{if(!_11b&&!c.params){c.params=_117(c.cls.prototype,{});}}return c;};this._functionFromScript=function(_11d,_11e){var _11f="";var _120="";var _121=(_11d.getAttribute(_11e+"args")||_11d.getAttribute("args"));if(_121){d.forEach(_121.split(/\s*,\s*/),function(part,idx){_11f+="var "+part+" = arguments["+idx+"]; ";});}var _122=_11d.getAttribute("with");if(_122&&_122.length){d.forEach(_122.split(/\s*,\s*/),function(part){_11f+="with("+part+"){";_120+="}";});}return new Function(_11f+_11d.innerHTML+_120);};this.instantiate=function(_123,_124,args){var _125=[],_124=_124||{};args=args||{};var _126=(args.scope||d._scopeName)+"Type",_127="data-"+(args.scope||d._scopeName)+"-";d.forEach(_123,function(obj){if(!obj){return;}var node,type,_128,_129,_12a,_12b;if(obj.node){node=obj.node;type=obj.type;_12b=obj.fastpath;_128=obj.clsInfo||(type&&_119(type,_12b));_129=_128&&_128.cls;_12a=obj.scripts;}else{node=obj;type=_126 in _124?_124[_126]:node.getAttribute(_126);_128=type&&_119(type);_129=_128&&_128.cls;_12a=(_129&&(_129._noScript||_129.prototype._noScript)?[]:d.query("> script[type^='dojo/']",node));}if(!_128){throw new Error("Could not load class '"+type);}var _12c={};if(args.defaults){d._mixin(_12c,args.defaults);}if(obj.inherited){d._mixin(_12c,obj.inherited);}if(_12b){var _12d=node.getAttribute(_127+"props");if(_12d&&_12d.length){try{_12d=d.fromJson.call(args.propsThis,"{"+_12d+"}");d._mixin(_12c,_12d);}catch(e){throw new Error(e.toString()+" in data-dojo-props='"+_12d+"'");}}var _12e=node.getAttribute(_127+"attach-point");if(_12e){_12c.dojoAttachPoint=_12e;}var _12f=node.getAttribute(_127+"attach-event");if(_12f){_12c.dojoAttachEvent=_12f;}_4.mixin(_12c,_124);}else{var _130=node.attributes;for(var name in _128.params){var item=name in _124?{value:_124[name],specified:true}:_130.getNamedItem(name);if(!item||(!item.specified&&(!_4.isIE||name.toLowerCase()!="value"))){continue;}var _131=item.value;switch(name){case "class":_131="className" in _124?_124.className:node.className;break;case "style":_131="style" in _124?_124.style:(node.style&&node.style.cssText);}var _132=_128.params[name];if(typeof _131=="string"){_12c[name]=_113(_131,_132);}else{_12c[name]=_131;}}}var _133=[],_134=[];d.forEach(_12a,function(_135){node.removeChild(_135);var _136=(_135.getAttribute(_127+"event")||_135.getAttribute("event")),type=_135.getAttribute("type"),nf=d.parser._functionFromScript(_135,_127);if(_136){if(type=="dojo/connect"){_133.push({event:_136,func:nf});}else{_12c[_136]=nf;}}else{_134.push(nf);}});var _137=_129.markupFactory||_129.prototype&&_129.prototype.markupFactory;var _138=_137?_137(_12c,node,_129):new _129(_12c,node);_125.push(_138);var _139=(node.getAttribute(_127+"id")||node.getAttribute("jsId"));if(_139){d.setObject(_139,_138);}d.forEach(_133,function(_13a){d.connect(_138,_13a.event,null,_13a.func);});d.forEach(_134,function(func){func.call(_138);});});if(!_124._started){d.forEach(_125,function(_13b){if(!args.noStart&&_13b&&_4.isFunction(_13b.startup)&&!_13b._started&&(!_13b.getParent||!_13b.getParent())){_13b.startup();}});}return _125;};this.parse=function(_13c,args){var root;if(!args&&_13c&&_13c.rootNode){args=_13c;root=args.rootNode;}else{root=_13c;}args=args||{};var _13d=(args.scope||d._scopeName)+"Type",_13e="data-"+(args.scope||d._scopeName)+"-";function scan(_13f,list){var _140=_4.clone(_13f.inherited);_4.forEach(["dir","lang"],function(name){var val=_13f.node.getAttribute(name);if(val){_140[name]=val;}});var _141=_13f.clsInfo&&!_13f.clsInfo.cls.prototype._noScript?_13f.scripts:null;var _142=(!_13f.clsInfo||!_13f.clsInfo.cls.prototype.stopParser)||(args&&args.template);for(var _143=_13f.node.firstChild;_143;_143=_143.nextSibling){if(_143.nodeType==1){var type,_144=_142&&_143.getAttribute(_13e+"type");if(_144){type=_144;}else{type=_142&&_143.getAttribute(_13d);}var _145=_144==type;if(type){var _146={"type":type,fastpath:_145,clsInfo:_119(type,_145),node:_143,scripts:[],inherited:_140};list.push(_146);scan(_146,list);}else{if(_141&&_143.nodeName.toLowerCase()=="script"){type=_143.getAttribute("type");if(type&&/^dojo\/\w/i.test(type)){_141.push(_143);}}else{if(_142){scan({node:_143,inherited:_140},list);}}}}}};var list=[];scan({node:root?_4.byId(root):_4.body(),inherited:(args&&args.inherited)||{dir:_4._isBodyLtr()?"ltr":"rtl"}},list);var _147=args&&args.template?{template:true}:null;return this.instantiate(list,_147,args);};}();(function(){var _148=function(){if(_4.config.parseOnLoad){_4.parser.parse();}};if(_4.getObject("dijit.wai.onload")===_4._loaders[0]){_4._loaders.splice(1,0,_148);}else{_4._loaders.unshift(_148);}})();}if(!_4._hasResource["dojo.Stateful"]){_4._hasResource["dojo.Stateful"]=true;_4.provide("dojo.Stateful");_4.declare("dojo.Stateful",null,{postscript:function(_149){if(_149){_4.mixin(this,_149);}},get:function(name){return this[name];},set:function(name,_14a){if(typeof name==="object"){for(var x in name){this.set(x,name[x]);}return this;}var _14b=this[name];this[name]=_14a;if(this._watchCallbacks){this._watchCallbacks(name,_14b,_14a);}return this;},watch:function(name,_14c){var _14d=this._watchCallbacks;if(!_14d){var self=this;_14d=this._watchCallbacks=function(name,_14e,_14f,_150){var _151=function(_152){if(_152){_152=_152.slice();for(var i=0,l=_152.length;i<l;i++){try{_152[i].call(self,name,_14e,_14f);}catch(e){console.error(e);}}}};_151(_14d["_"+name]);if(!_150){_151(_14d["*"]);}};}if(!_14c&&typeof name==="function"){_14c=name;name="*";}else{name="_"+name;}var _153=_14d[name];if(typeof _153!=="object"){_153=_14d[name]=[];}_153.push(_14c);return {unwatch:function(){_153.splice(_4.indexOf(_153,_14c),1);}};}});}if(!_4._hasResource["dijit._WidgetBase"]){_4._hasResource["dijit._WidgetBase"]=true;_4.provide("dijit._WidgetBase");(function(){_4.declare("dijit._WidgetBase",_4.Stateful,{id:"",lang:"",dir:"","class":"",style:"",title:"",tooltip:"",baseClass:"",srcNodeRef:null,domNode:null,containerNode:null,attributeMap:{id:"",dir:"",lang:"","class":"",style:"",title:""},_blankGif:(_4.config.blankGif||_4.moduleUrl("dojo","resources/blank.gif")).toString(),postscript:function(_154,_155){this.create(_154,_155);},create:function(_156,_157){this.srcNodeRef=_4.byId(_157);this._connects=[];this._subscribes=[];if(this.srcNodeRef&&(typeof this.srcNodeRef.id=="string")){this.id=this.srcNodeRef.id;}if(_156){this.params=_156;_4._mixin(this,_156);}this.postMixInProperties();if(!this.id){this.id=_5.getUniqueId(this.declaredClass.replace(/\./g,"_"));}_5.registry.add(this);this.buildRendering();if(this.domNode){this._applyAttributes();var _158=this.srcNodeRef;if(_158&&_158.parentNode&&this.domNode!==_158){_158.parentNode.replaceChild(this.domNode,_158);}}if(this.domNode){this.domNode.setAttribute("widgetId",this.id);}this.postCreate();if(this.srcNodeRef&&!this.srcNodeRef.parentNode){delete this.srcNodeRef;}this._created=true;},_applyAttributes:function(){var _159=function(attr,_15a){if((_15a.params&&attr in _15a.params)||_15a[attr]){_15a.set(attr,_15a[attr]);}};for(var attr in this.attributeMap){_159(attr,this);}_4.forEach(this._getSetterAttributes(),function(a){if(!(a in this.attributeMap)){_159(a,this);}},this);},_getSetterAttributes:function(){var ctor=this.constructor;if(!ctor._setterAttrs){var r=(ctor._setterAttrs=[]),_15b,_15c=ctor.prototype;for(var _15d in _15c){if(_4.isFunction(_15c[_15d])&&(_15b=_15d.match(/^_set([a-zA-Z]*)Attr$/))&&_15b[1]){r.push(_15b[1].charAt(0).toLowerCase()+_15b[1].substr(1));}}}return ctor._setterAttrs;},postMixInProperties:function(){},buildRendering:function(){if(!this.domNode){this.domNode=this.srcNodeRef||_4.create("div");}if(this.baseClass){var _15e=this.baseClass.split(" ");if(!this.isLeftToRight()){_15e=_15e.concat(_4.map(_15e,function(name){return name+"Rtl";}));}_4.addClass(this.domNode,_15e);}},postCreate:function(){},startup:function(){this._started=true;},destroyRecursive:function(_15f){this._beingDestroyed=true;this.destroyDescendants(_15f);this.destroy(_15f);},destroy:function(_160){this._beingDestroyed=true;this.uninitialize();var d=_4,dfe=d.forEach,dun=d.unsubscribe;dfe(this._connects,function(_161){dfe(_161,d.disconnect);});dfe(this._subscribes,function(_162){dun(_162);});dfe(this._supportingWidgets||[],function(w){if(w.destroyRecursive){w.destroyRecursive();}else{if(w.destroy){w.destroy();}}});this.destroyRendering(_160);_5.registry.remove(this.id);this._destroyed=true;},destroyRendering:function(_163){if(this.bgIframe){this.bgIframe.destroy(_163);delete this.bgIframe;}if(this.domNode){if(_163){_4.removeAttr(this.domNode,"widgetId");}else{_4.destroy(this.domNode);}delete this.domNode;}if(this.srcNodeRef){if(!_163){_4.destroy(this.srcNodeRef);}delete this.srcNodeRef;}},destroyDescendants:function(_164){_4.forEach(this.getChildren(),function(_165){if(_165.destroyRecursive){_165.destroyRecursive(_164);}});},uninitialize:function(){return false;},_setClassAttr:function(_166){var _167=this[this.attributeMap["class"]||"domNode"];_4.replaceClass(_167,_166,this["class"]);this._set("class",_166);},_setStyleAttr:function(_168){var _169=this[this.attributeMap.style||"domNode"];if(_4.isObject(_168)){_4.style(_169,_168);}else{if(_169.style.cssText){_169.style.cssText+="; "+_168;}else{_169.style.cssText=_168;}}this._set("style",_168);},_attrToDom:function(attr,_16a){var _16b=this.attributeMap[attr];_4.forEach(_4.isArray(_16b)?_16b:[_16b],function(_16c){var _16d=this[_16c.node||_16c||"domNode"];var type=_16c.type||"attribute";switch(type){case "attribute":if(_4.isFunction(_16a)){_16a=_4.hitch(this,_16a);}var _16e=_16c.attribute?_16c.attribute:(/^on[A-Z][a-zA-Z]*$/.test(attr)?attr.toLowerCase():attr);_4.attr(_16d,_16e,_16a);break;case "innerText":_16d.innerHTML="";_16d.appendChild(_4.doc.createTextNode(_16a));break;case "innerHTML":_16d.innerHTML=_16a;break;case "class":_4.replaceClass(_16d,_16a,this[attr]);break;}},this);},get:function(name){var _16f=this._getAttrNames(name);return this[_16f.g]?this[_16f.g]():this[name];},set:function(name,_170){if(typeof name==="object"){for(var x in name){this.set(x,name[x]);}return this;}var _171=this._getAttrNames(name);if(this[_171.s]){var _172=this[_171.s].apply(this,Array.prototype.slice.call(arguments,1));}else{if(name in this.attributeMap){this._attrToDom(name,_170);}this._set(name,_170);}return _172||this;},_attrPairNames:{},_getAttrNames:function(name){var apn=this._attrPairNames;if(apn[name]){return apn[name];}var uc=name.charAt(0).toUpperCase()+name.substr(1);return (apn[name]={n:name+"Node",s:"_set"+uc+"Attr",g:"_get"+uc+"Attr"});},_set:function(name,_173){var _174=this[name];this[name]=_173;if(this._watchCallbacks&&this._created&&_173!==_174){this._watchCallbacks(name,_174,_173);}},toString:function(){return "[Widget "+this.declaredClass+", "+(this.id||"NO ID")+"]";},getDescendants:function(){return this.containerNode?_4.query("[widgetId]",this.containerNode).map(_5.byNode):[];},getChildren:function(){return this.containerNode?_5.findWidgets(this.containerNode):[];},connect:function(obj,_175,_176){var _177=[_4._connect(obj,_175,this,_176)];this._connects.push(_177);return _177;},disconnect:function(_178){for(var i=0;i<this._connects.length;i++){if(this._connects[i]==_178){_4.forEach(_178,_4.disconnect);this._connects.splice(i,1);return;}}},subscribe:function(_179,_17a){var _17b=_4.subscribe(_179,this,_17a);this._subscribes.push(_17b);return _17b;},unsubscribe:function(_17c){for(var i=0;i<this._subscribes.length;i++){if(this._subscribes[i]==_17c){_4.unsubscribe(_17c);this._subscribes.splice(i,1);return;}}},isLeftToRight:function(){return this.dir?(this.dir=="ltr"):_4._isBodyLtr();},placeAt:function(_17d,_17e){if(_17d.declaredClass&&_17d.addChild){_17d.addChild(this,_17e);}else{_4.place(this.domNode,_17d,_17e);}return this;}});})();}if(!_4._hasResource["dijit._Widget"]){_4._hasResource["dijit._Widget"]=true;_4.provide("dijit._Widget");_4.connect(_4,"_connect",function(_17f,_180){if(_17f&&_4.isFunction(_17f._onConnect)){_17f._onConnect(_180);}});_5._connectOnUseEventHandler=function(_181){};_5._lastKeyDownNode=null;if(_4.isIE){(function(){var _182=function(evt){_5._lastKeyDownNode=evt.srcElement;};_4.doc.attachEvent("onkeydown",_182);_4.addOnWindowUnload(function(){_4.doc.detachEvent("onkeydown",_182);});})();}else{_4.doc.addEventListener("keydown",function(evt){_5._lastKeyDownNode=evt.target;},true);}(function(){_4.declare("dijit._Widget",_5._WidgetBase,{_deferredConnects:{onClick:"",onDblClick:"",onKeyDown:"",onKeyPress:"",onKeyUp:"",onMouseMove:"",onMouseDown:"",onMouseOut:"",onMouseOver:"",onMouseLeave:"",onMouseEnter:"",onMouseUp:""},onClick:_5._connectOnUseEventHandler,onDblClick:_5._connectOnUseEventHandler,onKeyDown:_5._connectOnUseEventHandler,onKeyPress:_5._connectOnUseEventHandler,onKeyUp:_5._connectOnUseEventHandler,onMouseDown:_5._connectOnUseEventHandler,onMouseMove:_5._connectOnUseEventHandler,onMouseOut:_5._connectOnUseEventHandler,onMouseOver:_5._connectOnUseEventHandler,onMouseLeave:_5._connectOnUseEventHandler,onMouseEnter:_5._connectOnUseEventHandler,onMouseUp:_5._connectOnUseEventHandler,create:function(_183,_184){this._deferredConnects=_4.clone(this._deferredConnects);for(var attr in this.attributeMap){delete this._deferredConnects[attr];}for(attr in this._deferredConnects){if(this[attr]!==_5._connectOnUseEventHandler){delete this._deferredConnects[attr];}}this.inherited(arguments);if(this.domNode){for(attr in this.params){this._onConnect(attr);}}},_onConnect:function(_185){if(_185 in this._deferredConnects){var _186=this[this._deferredConnects[_185]||"domNode"];this.connect(_186,_185.toLowerCase(),_185);delete this._deferredConnects[_185];}},focused:false,isFocusable:function(){return this.focus&&(_4.style(this.domNode,"display")!="none");},onFocus:function(){},onBlur:function(){},_onFocus:function(e){this.onFocus();},_onBlur:function(){this.onBlur();},setAttribute:function(attr,_187){_4.deprecated(this.declaredClass+"::setAttribute(attr, value) is deprecated. Use set() instead.","","2.0");this.set(attr,_187);},attr:function(name,_188){if(_4.config.isDebug){var _189=arguments.callee._ach||(arguments.callee._ach={}),_18a=(arguments.callee.caller||"unknown caller").toString();if(!_189[_18a]){_4.deprecated(this.declaredClass+"::attr() is deprecated. Use get() or set() instead, called from "+_18a,"","2.0");_189[_18a]=true;}}var args=arguments.length;if(args>=2||typeof name==="object"){return this.set.apply(this,arguments);}else{return this.get(name);}},nodesWithKeyClick:["input","button"],connect:function(obj,_18b,_18c){var d=_4,dc=d._connect,_18d=this.inherited(arguments,[obj,_18b=="ondijitclick"?"onclick":_18b,_18c]);if(_18b=="ondijitclick"){if(d.indexOf(this.nodesWithKeyClick,obj.nodeName.toLowerCase())==-1){var m=d.hitch(this,_18c);_18d.push(dc(obj,"onkeydown",this,function(e){if((e.keyCode==d.keys.ENTER||e.keyCode==d.keys.SPACE)&&!e.ctrlKey&&!e.shiftKey&&!e.altKey&&!e.metaKey){_5._lastKeyDownNode=e.target;if(!("openDropDown" in this&&obj==this._buttonNode)){e.preventDefault();}}}),dc(obj,"onkeyup",this,function(e){if((e.keyCode==d.keys.ENTER||e.keyCode==d.keys.SPACE)&&e.target==_5._lastKeyDownNode&&!e.ctrlKey&&!e.shiftKey&&!e.altKey&&!e.metaKey){_5._lastKeyDownNode=null;return m(e);}}));}}return _18d;},_onShow:function(){this.onShow();},onShow:function(){},onHide:function(){},onClose:function(){return true;}});})();}if(!_4._hasResource["dojo.string"]){_4._hasResource["dojo.string"]=true;_4.provide("dojo.string");_4.getObject("string",true,_4);_4.string.rep=function(str,num){if(num<=0||!str){return "";}var buf=[];for(;;){if(num&1){buf.push(str);}if(!(num>>=1)){break;}str+=str;}return buf.join("");};_4.string.pad=function(text,size,ch,end){if(!ch){ch="0";}var out=String(text),pad=_4.string.rep(ch,Math.ceil((size-out.length)/ch.length));return end?out+pad:pad+out;};_4.string.substitute=function(_18e,map,_18f,_190){_190=_190||_4.global;_18f=_18f?_4.hitch(_190,_18f):function(v){return v;};return _18e.replace(/\$\{([^\s\:\}]+)(?:\:([^\s\:\}]+))?\}/g,function(_191,key,_192){var _193=_4.getObject(key,false,map);if(_192){_193=_4.getObject(_192,false,_190).call(_190,_193,key);}return _18f(_193,key).toString();});};_4.string.trim=String.prototype.trim?_4.trim:function(str){str=str.replace(/^\s+/,"");for(var i=str.length-1;i>=0;i--){if(/\S/.test(str.charAt(i))){str=str.substring(0,i+1);break;}}return str;};}if(!_4._hasResource["dojo.cache"]){_4._hasResource["dojo.cache"]=true;_4.provide("dojo.cache");var _194={};_4.cache=function(_195,url,_196){if(typeof _195=="string"){var _197=_4.moduleUrl(_195,url);}else{_197=_195;_196=url;}var key=_197.toString();var val=_196;if(_196!=undefined&&!_4.isString(_196)){val=("value" in _196?_196.value:undefined);}var _198=_196&&_196.sanitize?true:false;if(typeof val=="string"){val=_194[key]=_198?_4.cache._sanitize(val):val;}else{if(val===null){delete _194[key];}else{if(!(key in _194)){val=_4._getText(key);_194[key]=_198?_4.cache._sanitize(val):val;}val=_194[key];}}return val;};_4.cache._sanitize=function(val){if(val){val=val.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,"");var _199=val.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);if(_199){val=_199[1];}}else{val="";}return val;};}if(!_4._hasResource["dijit._Templated"]){_4._hasResource["dijit._Templated"]=true;_4.provide("dijit._Templated");_4.declare("dijit._Templated",null,{templateString:null,templatePath:null,widgetsInTemplate:false,_skipNodeCache:false,_earlyTemplatedStartup:false,constructor:function(){this._attachPoints=[];this._attachEvents=[];},_stringRepl:function(tmpl){var _19a=this.declaredClass,_19b=this;return _4.string.substitute(tmpl,this,function(_19c,key){if(key.charAt(0)=="!"){_19c=_4.getObject(key.substr(1),false,_19b);}if(typeof _19c=="undefined"){throw new Error(_19a+" template:"+key);}if(_19c==null){return "";}return key.charAt(0)=="!"?_19c:_19c.toString().replace(/"/g,"&quot;");},this);},buildRendering:function(){var _19d=_5._Templated.getCachedTemplate(this.templatePath,this.templateString,this._skipNodeCache);var node;if(_4.isString(_19d)){node=_4._toDom(this._stringRepl(_19d));if(node.nodeType!=1){throw new Error("Invalid template: "+_19d);}}else{node=_19d.cloneNode(true);}this.domNode=node;this.inherited(arguments);this._attachTemplateNodes(node);if(this.widgetsInTemplate){var cw=(this._startupWidgets=_4.parser.parse(node,{noStart:!this._earlyTemplatedStartup,template:true,inherited:{dir:this.dir,lang:this.lang},propsThis:this,scope:"dojo"}));this._supportingWidgets=_5.findWidgets(node);this._attachTemplateNodes(cw,function(n,p){return n[p];});}this._fillContent(this.srcNodeRef);},_fillContent:function(_19e){var dest=this.containerNode;if(_19e&&dest){while(_19e.hasChildNodes()){dest.appendChild(_19e.firstChild);}}},_attachTemplateNodes:function(_19f,_1a0){_1a0=_1a0||function(n,p){return n.getAttribute(p);};var _1a1=_4.isArray(_19f)?_19f:(_19f.all||_19f.getElementsByTagName("*"));var x=_4.isArray(_19f)?0:-1;for(;x<_1a1.length;x++){var _1a2=(x==-1)?_19f:_1a1[x];if(this.widgetsInTemplate&&(_1a0(_1a2,"dojoType")||_1a0(_1a2,"data-dojo-type"))){continue;}var _1a3=_1a0(_1a2,"dojoAttachPoint")||_1a0(_1a2,"data-dojo-attach-point");if(_1a3){var _1a4,_1a5=_1a3.split(/\s*,\s*/);while((_1a4=_1a5.shift())){if(_4.isArray(this[_1a4])){this[_1a4].push(_1a2);}else{this[_1a4]=_1a2;}this._attachPoints.push(_1a4);}}var _1a6=_1a0(_1a2,"dojoAttachEvent")||_1a0(_1a2,"data-dojo-attach-event");if(_1a6){var _1a7,_1a8=_1a6.split(/\s*,\s*/);var trim=_4.trim;while((_1a7=_1a8.shift())){if(_1a7){var _1a9=null;if(_1a7.indexOf(":")!=-1){var _1aa=_1a7.split(":");_1a7=trim(_1aa[0]);_1a9=trim(_1aa[1]);}else{_1a7=trim(_1a7);}if(!_1a9){_1a9=_1a7;}this._attachEvents.push(this.connect(_1a2,_1a7,_1a9));}}}var role=_1a0(_1a2,"waiRole");if(role){_5.setWaiRole(_1a2,role);}var _1ab=_1a0(_1a2,"waiState");if(_1ab){_4.forEach(_1ab.split(/\s*,\s*/),function(_1ac){if(_1ac.indexOf("-")!=-1){var pair=_1ac.split("-");_5.setWaiState(_1a2,pair[0],pair[1]);}});}}},startup:function(){_4.forEach(this._startupWidgets,function(w){if(w&&!w._started&&w.startup){w.startup();}});this.inherited(arguments);},destroyRendering:function(){_4.forEach(this._attachPoints,function(_1ad){delete this[_1ad];},this);this._attachPoints=[];_4.forEach(this._attachEvents,this.disconnect,this);this._attachEvents=[];this.inherited(arguments);}});_5._Templated._templateCache={};_5._Templated.getCachedTemplate=function(_1ae,_1af,_1b0){var _1b1=_5._Templated._templateCache;var key=_1af||_1ae;var _1b2=_1b1[key];if(_1b2){try{if(!_1b2.ownerDocument||_1b2.ownerDocument==_4.doc){return _1b2;}}catch(e){}_4.destroy(_1b2);}if(!_1af){_1af=_4.cache(_1ae,{sanitize:true});}_1af=_4.string.trim(_1af);if(_1b0||_1af.match(/\$\{([^\}]+)\}/g)){return (_1b1[key]=_1af);}else{var node=_4._toDom(_1af);if(node.nodeType!=1){throw new Error("Invalid template: "+_1af);}return (_1b1[key]=node);}};if(_4.isIE){_4.addOnWindowUnload(function(){var _1b3=_5._Templated._templateCache;for(var key in _1b3){var _1b4=_1b3[key];if(typeof _1b4=="object"){_4.destroy(_1b4);}delete _1b3[key];}});}_4.extend(_5._Widget,{dojoAttachEvent:"",dojoAttachPoint:"",waiRole:"",waiState:""});}if(!_4._hasResource["dijit._Container"]){_4._hasResource["dijit._Container"]=true;_4.provide("dijit._Container");_4.declare("dijit._Container",null,{isContainer:true,buildRendering:function(){this.inherited(arguments);if(!this.containerNode){this.containerNode=this.domNode;}},addChild:function(_1b5,_1b6){var _1b7=this.containerNode;if(_1b6&&typeof _1b6=="number"){var _1b8=this.getChildren();if(_1b8&&_1b8.length>=_1b6){_1b7=_1b8[_1b6-1].domNode;_1b6="after";}}_4.place(_1b5.domNode,_1b7,_1b6);if(this._started&&!_1b5._started){_1b5.startup();}},removeChild:function(_1b9){if(typeof _1b9=="number"){_1b9=this.getChildren()[_1b9];}if(_1b9){var node=_1b9.domNode;if(node&&node.parentNode){node.parentNode.removeChild(node);}}},hasChildren:function(){return this.getChildren().length>0;},destroyDescendants:function(_1ba){_4.forEach(this.getChildren(),function(_1bb){_1bb.destroyRecursive(_1ba);});},_getSiblingOfChild:function(_1bc,dir){var node=_1bc.domNode,_1bd=(dir>0?"nextSibling":"previousSibling");do{node=node[_1bd];}while(node&&(node.nodeType!=1||!_5.byNode(node)));return node&&_5.byNode(node);},getIndexOfChild:function(_1be){return _4.indexOf(this.getChildren(),_1be);},startup:function(){if(this._started){return;}_4.forEach(this.getChildren(),function(_1bf){_1bf.startup();});this.inherited(arguments);}});}if(!_4._hasResource["dijit._Contained"]){_4._hasResource["dijit._Contained"]=true;_4.provide("dijit._Contained");_4.declare("dijit._Contained",null,{getParent:function(){var _1c0=_5.getEnclosingWidget(this.domNode.parentNode);return _1c0&&_1c0.isContainer?_1c0:null;},_getSibling:function(_1c1){var node=this.domNode;do{node=node[_1c1+"Sibling"];}while(node&&node.nodeType!=1);return node&&_5.byNode(node);},getPreviousSibling:function(){return this._getSibling("previous");},getNextSibling:function(){return this._getSibling("next");},getIndexInParent:function(){var p=this.getParent();if(!p||!p.getIndexOfChild){return -1;}return p.getIndexOfChild(this);}});}if(!_4._hasResource["dijit.layout._LayoutWidget"]){_4._hasResource["dijit.layout._LayoutWidget"]=true;_4.provide("dijit.layout._LayoutWidget");_4.declare("dijit.layout._LayoutWidget",[_5._Widget,_5._Container,_5._Contained],{baseClass:"dijitLayoutContainer",isLayoutContainer:true,buildRendering:function(){this.inherited(arguments);_4.addClass(this.domNode,"dijitContainer");},startup:function(){if(this._started){return;}this.inherited(arguments);var _1c2=this.getParent&&this.getParent();if(!(_1c2&&_1c2.isLayoutContainer)){this.resize();this.connect(_4.isIE?this.domNode:_4.global,"onresize",function(){this.resize();});}},resize:function(_1c3,_1c4){var node=this.domNode;if(_1c3){_4.marginBox(node,_1c3);if(_1c3.t){node.style.top=_1c3.t+"px";}if(_1c3.l){node.style.left=_1c3.l+"px";}}var mb=_1c4||{};_4.mixin(mb,_1c3||{});if(!("h" in mb)||!("w" in mb)){mb=_4.mixin(_4.marginBox(node),mb);}var cs=_4.getComputedStyle(node);var me=_4._getMarginExtents(node,cs);var be=_4._getBorderExtents(node,cs);var bb=(this._borderBox={w:mb.w-(me.w+be.w),h:mb.h-(me.h+be.h)});var pe=_4._getPadExtents(node,cs);this._contentBox={l:_4._toPixelValue(node,cs.paddingLeft),t:_4._toPixelValue(node,cs.paddingTop),w:bb.w-pe.w,h:bb.h-pe.h};this.layout();},layout:function(){},_setupChild:function(_1c5){var cls=this.baseClass+"-child "+(_1c5.baseClass?this.baseClass+"-"+_1c5.baseClass:"");_4.addClass(_1c5.domNode,cls);},addChild:function(_1c6,_1c7){this.inherited(arguments);if(this._started){this._setupChild(_1c6);}},removeChild:function(_1c8){var cls=this.baseClass+"-child"+(_1c8.baseClass?" "+this.baseClass+"-"+_1c8.baseClass:"");_4.removeClass(_1c8.domNode,cls);this.inherited(arguments);}});_5.layout.marginBox2contentBox=function(node,mb){var cs=_4.getComputedStyle(node);var me=_4._getMarginExtents(node,cs);var pb=_4._getPadBorderExtents(node,cs);return {l:_4._toPixelValue(node,cs.paddingLeft),t:_4._toPixelValue(node,cs.paddingTop),w:mb.w-(me.w+pb.w),h:mb.h-(me.h+pb.h)};};(function(){var _1c9=function(word){return word.substring(0,1).toUpperCase()+word.substring(1);};var size=function(_1ca,dim){_1ca.resize?_1ca.resize(dim):_4.marginBox(_1ca.domNode,dim);_4.mixin(_1ca,_4.marginBox(_1ca.domNode));_4.mixin(_1ca,dim);};_5.layout.layoutChildren=function(_1cb,dim,_1cc,_1cd,_1ce){dim=_4.mixin({},dim);_4.addClass(_1cb,"dijitLayoutContainer");_1cc=_4.filter(_1cc,function(item){return item.region!="center"&&item.layoutAlign!="client";}).concat(_4.filter(_1cc,function(item){return item.region=="center"||item.layoutAlign=="client";}));_4.forEach(_1cc,function(_1cf){var elm=_1cf.domNode,pos=(_1cf.region||_1cf.layoutAlign);var _1d0=elm.style;_1d0.left=dim.l+"px";_1d0.top=dim.t+"px";_1d0.bottom=_1d0.right="auto";_4.addClass(elm,"dijitAlign"+_1c9(pos));var _1d1={};if(_1cd&&_1cd==_1cf.id){_1d1[_1cf.region=="top"||_1cf.region=="bottom"?"h":"w"]=_1ce;}if(pos=="top"||pos=="bottom"){_1d1.w=dim.w;size(_1cf,_1d1);dim.h-=_1cf.h;if(pos=="top"){dim.t+=_1cf.h;}else{_1d0.top=dim.t+dim.h+"px";}}else{if(pos=="left"||pos=="right"){_1d1.h=dim.h;size(_1cf,_1d1);dim.w-=_1cf.w;if(pos=="left"){dim.l+=_1cf.w;}else{_1d0.left=dim.l+dim.w+"px";}}else{if(pos=="client"||pos=="center"){size(_1cf,dim);}}}});};})();}if(!_4._hasResource["dijit._CssStateMixin"]){_4._hasResource["dijit._CssStateMixin"]=true;_4.provide("dijit._CssStateMixin");_4.declare("dijit._CssStateMixin",[],{cssStateNodes:{},hovering:false,active:false,_applyAttributes:function(){this.inherited(arguments);_4.forEach(["onmouseenter","onmouseleave","onmousedown"],function(e){this.connect(this.domNode,e,"_cssMouseEvent");},this);_4.forEach(["disabled","readOnly","checked","selected","focused","state","hovering","active"],function(attr){this.watch(attr,_4.hitch(this,"_setStateClass"));},this);for(var ap in this.cssStateNodes){this._trackMouseState(this[ap],this.cssStateNodes[ap]);}this._setStateClass();},_cssMouseEvent:function(_1d2){if(!this.disabled){switch(_1d2.type){case "mouseenter":case "mouseover":this._set("hovering",true);this._set("active",this._mouseDown);break;case "mouseleave":case "mouseout":this._set("hovering",false);this._set("active",false);break;case "mousedown":this._set("active",true);this._mouseDown=true;var _1d3=this.connect(_4.body(),"onmouseup",function(){this._mouseDown=false;this._set("active",false);this.disconnect(_1d3);});break;}}},_setStateClass:function(){var _1d4=this.baseClass.split(" ");function _1d5(_1d6){_1d4=_1d4.concat(_4.map(_1d4,function(c){return c+_1d6;}),"dijit"+_1d6);};if(!this.isLeftToRight()){_1d5("Rtl");}if(this.checked){_1d5("Checked");}if(this.state){_1d5(this.state);}if(this.selected){_1d5("Selected");}if(this.disabled){_1d5("Disabled");}else{if(this.readOnly){_1d5("ReadOnly");}else{if(this.active){_1d5("Active");}else{if(this.hovering){_1d5("Hover");}}}}if(this._focused){_1d5("Focused");}var tn=this.stateNode||this.domNode,_1d7={};_4.forEach(tn.className.split(" "),function(c){_1d7[c]=true;});if("_stateClasses" in this){_4.forEach(this._stateClasses,function(c){delete _1d7[c];});}_4.forEach(_1d4,function(c){_1d7[c]=true;});var _1d8=[];for(var c in _1d7){_1d8.push(c);}tn.className=_1d8.join(" ");this._stateClasses=_1d4;},_trackMouseState:function(node,_1d9){var _1da=false,_1db=false,_1dc=false;var self=this,cn=_4.hitch(this,"connect",node);function _1dd(){var _1de=("disabled" in self&&self.disabled)||("readonly" in self&&self.readonly);_4.toggleClass(node,_1d9+"Hover",_1da&&!_1db&&!_1de);_4.toggleClass(node,_1d9+"Active",_1db&&!_1de);_4.toggleClass(node,_1d9+"Focused",_1dc&&!_1de);};cn("onmouseenter",function(){_1da=true;_1dd();});cn("onmouseleave",function(){_1da=false;_1db=false;_1dd();});cn("onmousedown",function(){_1db=true;_1dd();});cn("onmouseup",function(){_1db=false;_1dd();});cn("onfocus",function(){_1dc=true;_1dd();});cn("onblur",function(){_1dc=false;_1dd();});this.watch("disabled",_1dd);this.watch("readOnly",_1dd);}});}if(!_4._hasResource["dijit.form._FormWidget"]){_4._hasResource["dijit.form._FormWidget"]=true;_4.provide("dijit.form._FormWidget");_4.declare("dijit.form._FormWidget",[_5._Widget,_5._Templated,_5._CssStateMixin],{name:"",alt:"",value:"",type:"text",tabIndex:"0",disabled:false,intermediateChanges:false,scrollOnFocus:true,attributeMap:_4.delegate(_5._Widget.prototype.attributeMap,{value:"focusNode",id:"focusNode",tabIndex:"focusNode",alt:"focusNode",title:"focusNode"}),postMixInProperties:function(){this.nameAttrSetting=this.name?("name=\""+this.name.replace(/'/g,"&quot;")+"\""):"";this.inherited(arguments);},postCreate:function(){this.inherited(arguments);this.connect(this.domNode,"onmousedown","_onMouseDown");},_setDisabledAttr:function(_1df){this._set("disabled",_1df);_4.attr(this.focusNode,"disabled",_1df);if(this.valueNode){_4.attr(this.valueNode,"disabled",_1df);}_5.setWaiState(this.focusNode,"disabled",_1df);if(_1df){this._set("hovering",false);this._set("active",false);var _1e0="tabIndex" in this.attributeMap?this.attributeMap.tabIndex:"focusNode";_4.forEach(_4.isArray(_1e0)?_1e0:[_1e0],function(_1e1){var node=this[_1e1];if(_4.isWebKit||_5.hasDefaultTabStop(node)){node.setAttribute("tabIndex","-1");}else{node.removeAttribute("tabIndex");}},this);}else{if(this.tabIndex!=""){this.focusNode.setAttribute("tabIndex",this.tabIndex);}}},setDisabled:function(_1e2){_4.deprecated("setDisabled("+_1e2+") is deprecated. Use set('disabled',"+_1e2+") instead.","","2.0");this.set("disabled",_1e2);},_onFocus:function(e){if(this.scrollOnFocus){_4.window.scrollIntoView(this.domNode);}this.inherited(arguments);},isFocusable:function(){return !this.disabled&&this.focusNode&&(_4.style(this.domNode,"display")!="none");},focus:function(){if(!this.disabled){_5.focus(this.focusNode);}},compare:function(val1,val2){if(typeof val1=="number"&&typeof val2=="number"){return (isNaN(val1)&&isNaN(val2))?0:val1-val2;}else{if(val1>val2){return 1;}else{if(val1<val2){return -1;}else{return 0;}}}},onChange:function(_1e3){},_onChangeActive:false,_handleOnChange:function(_1e4,_1e5){if(this._lastValueReported==undefined&&(_1e5===null||!this._onChangeActive)){this._resetValue=this._lastValueReported=_1e4;}this._pendingOnChange=this._pendingOnChange||(typeof _1e4!=typeof this._lastValueReported)||(this.compare(_1e4,this._lastValueReported)!=0);if((this.intermediateChanges||_1e5||_1e5===undefined)&&this._pendingOnChange){this._lastValueReported=_1e4;this._pendingOnChange=false;if(this._onChangeActive){if(this._onChangeHandle){clearTimeout(this._onChangeHandle);}this._onChangeHandle=setTimeout(_4.hitch(this,function(){this._onChangeHandle=null;this.onChange(_1e4);}),0);}}},create:function(){this.inherited(arguments);this._onChangeActive=true;},destroy:function(){if(this._onChangeHandle){clearTimeout(this._onChangeHandle);this.onChange(this._lastValueReported);}this.inherited(arguments);},setValue:function(_1e6){_4.deprecated("dijit.form._FormWidget:setValue("+_1e6+") is deprecated. Use set('value',"+_1e6+") instead.","","2.0");this.set("value",_1e6);},getValue:function(){_4.deprecated(this.declaredClass+"::getValue() is deprecated. Use get('value') instead.","","2.0");return this.get("value");},_onMouseDown:function(e){if(!e.ctrlKey&&_4.mouseButtons.isLeft(e)&&this.isFocusable()){var _1e7=this.connect(_4.body(),"onmouseup",function(){if(this.isFocusable()){this.focus();}this.disconnect(_1e7);});}}});_4.declare("dijit.form._FormValueWidget",_5.form._FormWidget,{readOnly:false,attributeMap:_4.delegate(_5.form._FormWidget.prototype.attributeMap,{value:"",readOnly:"focusNode"}),_setReadOnlyAttr:function(_1e8){_4.attr(this.focusNode,"readOnly",_1e8);_5.setWaiState(this.focusNode,"readonly",_1e8);this._set("readOnly",_1e8);},postCreate:function(){this.inherited(arguments);if(_4.isIE){this.connect(this.focusNode||this.domNode,"onkeydown",this._onKeyDown);}if(this._resetValue===undefined){this._lastValueReported=this._resetValue=this.value;}},_setValueAttr:function(_1e9,_1ea){this._handleOnChange(_1e9,_1ea);},_handleOnChange:function(_1eb,_1ec){this._set("value",_1eb);this.inherited(arguments);},undo:function(){this._setValueAttr(this._lastValueReported,false);},reset:function(){this._hasBeenBlurred=false;this._setValueAttr(this._resetValue,true);},_onKeyDown:function(e){if(e.keyCode==_4.keys.ESCAPE&&!(e.ctrlKey||e.altKey||e.metaKey)){var te;if(_4.isIE){e.preventDefault();te=document.createEventObject();te.keyCode=_4.keys.ESCAPE;te.shiftKey=e.shiftKey;e.srcElement.fireEvent("onkeypress",te);}}},_layoutHackIE7:function(){if(_4.isIE==7){var _1ed=this.domNode;var _1ee=_1ed.parentNode;var _1ef=_1ed.firstChild||_1ed;var _1f0=_1ef.style.filter;var _1f1=this;while(_1ee&&_1ee.clientHeight==0){(function ping(){var _1f2=_1f1.connect(_1ee,"onscroll",function(e){_1f1.disconnect(_1f2);_1ef.style.filter=(new Date()).getMilliseconds();setTimeout(function(){_1ef.style.filter=_1f0;},0);});})();_1ee=_1ee.parentNode;}}}});}if(!_4._hasResource["dijit.dijit"]){_4._hasResource["dijit.dijit"]=true;_4.provide("dijit.dijit");}if(!_4._hasResource["dijit._KeyNavContainer"]){_4._hasResource["dijit._KeyNavContainer"]=true;_4.provide("dijit._KeyNavContainer");_4.declare("dijit._KeyNavContainer",_5._Container,{tabIndex:"0",_keyNavCodes:{},connectKeyNavHandlers:function(_1f3,_1f4){var _1f5=(this._keyNavCodes={});var prev=_4.hitch(this,this.focusPrev);var next=_4.hitch(this,this.focusNext);_4.forEach(_1f3,function(code){_1f5[code]=prev;});_4.forEach(_1f4,function(code){_1f5[code]=next;});_1f5[_4.keys.HOME]=_4.hitch(this,"focusFirstChild");_1f5[_4.keys.END]=_4.hitch(this,"focusLastChild");this.connect(this.domNode,"onkeypress","_onContainerKeypress");this.connect(this.domNode,"onfocus","_onContainerFocus");},startupKeyNavChildren:function(){_4.forEach(this.getChildren(),_4.hitch(this,"_startupChild"));},addChild:function(_1f6,_1f7){_5._KeyNavContainer.superclass.addChild.apply(this,arguments);this._startupChild(_1f6);},focus:function(){this.focusFirstChild();},focusFirstChild:function(){var _1f8=this._getFirstFocusableChild();if(_1f8){this.focusChild(_1f8);}},focusLastChild:function(){var _1f9=this._getLastFocusableChild();if(_1f9){this.focusChild(_1f9);}},focusNext:function(){var _1fa=this._getNextFocusableChild(this.focusedChild,1);this.focusChild(_1fa);},focusPrev:function(){var _1fb=this._getNextFocusableChild(this.focusedChild,-1);this.focusChild(_1fb,true);},focusChild:function(_1fc,last){if(this.focusedChild&&_1fc!==this.focusedChild){this._onChildBlur(this.focusedChild);}_1fc.focus(last?"end":"start");this._set("focusedChild",_1fc);},_startupChild:function(_1fd){_1fd.set("tabIndex","-1");this.connect(_1fd,"_onFocus",function(){_1fd.set("tabIndex",this.tabIndex);});this.connect(_1fd,"_onBlur",function(){_1fd.set("tabIndex","-1");});},_onContainerFocus:function(evt){if(evt.target!==this.domNode){return;}this.focusFirstChild();_4.attr(this.domNode,"tabIndex","-1");},_onBlur:function(evt){if(this.tabIndex){_4.attr(this.domNode,"tabIndex",this.tabIndex);}this.inherited(arguments);},_onContainerKeypress:function(evt){if(evt.ctrlKey||evt.altKey){return;}var func=this._keyNavCodes[evt.charOrCode];if(func){func();_4.stopEvent(evt);}},_onChildBlur:function(_1fe){},_getFirstFocusableChild:function(){return this._getNextFocusableChild(null,1);},_getLastFocusableChild:function(){return this._getNextFocusableChild(null,-1);},_getNextFocusableChild:function(_1ff,dir){if(_1ff){_1ff=this._getSiblingOfChild(_1ff,dir);}var _200=this.getChildren();for(var i=0;i<_200.length;i++){if(!_1ff){_1ff=_200[(dir>0)?0:(_200.length-1)];}if(_1ff.isFocusable()){return _1ff;}_1ff=this._getSiblingOfChild(_1ff,dir);}return null;}});}if(!_4._hasResource["dijit.MenuItem"]){_4._hasResource["dijit.MenuItem"]=true;_4.provide("dijit.MenuItem");_4.declare("dijit.MenuItem",[_5._Widget,_5._Templated,_5._Contained,_5._CssStateMixin],{templateString:_4.cache("dijit","templates/MenuItem.html","<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" role=\"menuitem\" tabIndex=\"-1\"\r\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\r\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\r\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitIcon dijitMenuItemIcon\" dojoAttachPoint=\"iconNode\"/>\r\n\t</td>\r\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" dojoAttachPoint=\"containerNode\"></td>\r\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" dojoAttachPoint=\"accelKeyNode\"></td>\r\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">\r\n\t\t<div dojoAttachPoint=\"arrowWrapper\" style=\"visibility: hidden\">\r\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuExpand\"/>\r\n\t\t\t<span class=\"dijitMenuExpandA11y\">+</span>\r\n\t\t</div>\r\n\t</td>\r\n</tr>\r\n"),attributeMap:_4.delegate(_5._Widget.prototype.attributeMap,{label:{node:"containerNode",type:"innerHTML"},iconClass:{node:"iconNode",type:"class"}}),baseClass:"dijitMenuItem",label:"",iconClass:"",accelKey:"",disabled:false,_fillContent:function(_201){if(_201&&!("label" in this.params)){this.set("label",_201.innerHTML);}},buildRendering:function(){this.inherited(arguments);var _202=this.id+"_text";_4.attr(this.containerNode,"id",_202);if(this.accelKeyNode){_4.attr(this.accelKeyNode,"id",this.id+"_accel");_202+=" "+this.id+"_accel";}_5.setWaiState(this.domNode,"labelledby",_202);_4.setSelectable(this.domNode,false);},_onHover:function(){this.getParent().onItemHover(this);},_onUnhover:function(){this.getParent().onItemUnhover(this);this._set("hovering",false);},_onClick:function(evt){this.getParent().onItemClick(this,evt);_4.stopEvent(evt);},onClick:function(evt){},focus:function(){try{if(_4.isIE==8){this.containerNode.focus();}_5.focus(this.focusNode);}catch(e){}},_onFocus:function(){this._setSelected(true);this.getParent()._onItemFocus(this);this.inherited(arguments);},_setSelected:function(_203){_4.toggleClass(this.domNode,"dijitMenuItemSelected",_203);},setLabel:function(_204){_4.deprecated("dijit.MenuItem.setLabel() is deprecated. Use set('label', ...) instead.","","2.0");this.set("label",_204);},setDisabled:function(_205){_4.deprecated("dijit.Menu.setDisabled() is deprecated. Use set('disabled', bool) instead.","","2.0");this.set("disabled",_205);},_setDisabledAttr:function(_206){_5.setWaiState(this.focusNode,"disabled",_206?"true":"false");this._set("disabled",_206);},_setAccelKeyAttr:function(_207){this.accelKeyNode.style.display=_207?"":"none";this.accelKeyNode.innerHTML=_207;_4.attr(this.containerNode,"colSpan",_207?"1":"2");this._set("accelKey",_207);}});}if(!_4._hasResource["dijit.PopupMenuItem"]){_4._hasResource["dijit.PopupMenuItem"]=true;_4.provide("dijit.PopupMenuItem");_4.declare("dijit.PopupMenuItem",_5.MenuItem,{_fillContent:function(){if(this.srcNodeRef){var _208=_4.query("*",this.srcNodeRef);_5.PopupMenuItem.superclass._fillContent.call(this,_208[0]);this.dropDownContainer=this.srcNodeRef;}},startup:function(){if(this._started){return;}this.inherited(arguments);if(!this.popup){var node=_4.query("[widgetId]",this.dropDownContainer)[0];this.popup=_5.byNode(node);}_4.body().appendChild(this.popup.domNode);this.popup.startup();this.popup.domNode.style.display="none";if(this.arrowWrapper){_4.style(this.arrowWrapper,"visibility","");}_5.setWaiState(this.focusNode,"haspopup","true");},destroyDescendants:function(){if(this.popup){if(!this.popup._destroyed){this.popup.destroyRecursive();}delete this.popup;}this.inherited(arguments);}});}if(!_4._hasResource["dijit.CheckedMenuItem"]){_4._hasResource["dijit.CheckedMenuItem"]=true;_4.provide("dijit.CheckedMenuItem");_4.declare("dijit.CheckedMenuItem",_5.MenuItem,{templateString:_4.cache("dijit","templates/CheckedMenuItem.html","<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" role=\"menuitemcheckbox\" tabIndex=\"-1\"\r\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\r\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\r\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" dojoAttachPoint=\"iconNode\"/>\r\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">&#10003;</span>\r\n\t</td>\r\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" dojoAttachPoint=\"containerNode,labelNode\"></td>\r\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" dojoAttachPoint=\"accelKeyNode\"></td>\r\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">&nbsp;</td>\r\n</tr>\r\n"),checked:false,_setCheckedAttr:function(_209){_4.toggleClass(this.domNode,"dijitCheckedMenuItemChecked",_209);_5.setWaiState(this.domNode,"checked",_209);this._set("checked",_209);},onChange:function(_20a){},_onClick:function(e){if(!this.disabled){this.set("checked",!this.checked);this.onChange(this.checked);}this.inherited(arguments);}});}if(!_4._hasResource["dijit.MenuSeparator"]){_4._hasResource["dijit.MenuSeparator"]=true;_4.provide("dijit.MenuSeparator");_4.declare("dijit.MenuSeparator",[_5._Widget,_5._Templated,_5._Contained],{templateString:_4.cache("dijit","templates/MenuSeparator.html","<tr class=\"dijitMenuSeparator\">\r\n\t<td class=\"dijitMenuSeparatorIconCell\">\r\n\t\t<div class=\"dijitMenuSeparatorTop\"></div>\r\n\t\t<div class=\"dijitMenuSeparatorBottom\"></div>\r\n\t</td>\r\n\t<td colspan=\"3\" class=\"dijitMenuSeparatorLabelCell\">\r\n\t\t<div class=\"dijitMenuSeparatorTop dijitMenuSeparatorLabel\"></div>\r\n\t\t<div class=\"dijitMenuSeparatorBottom\"></div>\r\n\t</td>\r\n</tr>\r\n"),buildRendering:function(){this.inherited(arguments);_4.setSelectable(this.domNode,false);},isFocusable:function(){return false;}});}if(!_4._hasResource["dijit.Menu"]){_4._hasResource["dijit.Menu"]=true;_4.provide("dijit.Menu");_4.declare("dijit._MenuBase",[_5._Widget,_5._Templated,_5._KeyNavContainer],{parentMenu:null,popupDelay:500,startup:function(){if(this._started){return;}_4.forEach(this.getChildren(),function(_20b){_20b.startup();});this.startupKeyNavChildren();this.inherited(arguments);},onExecute:function(){},onCancel:function(_20c){},_moveToPopup:function(evt){if(this.focusedChild&&this.focusedChild.popup&&!this.focusedChild.disabled){this.focusedChild._onClick(evt);}else{var _20d=this._getTopMenu();if(_20d&&_20d._isMenuBar){_20d.focusNext();}}},_onPopupHover:function(evt){if(this.currentPopup&&this.currentPopup._pendingClose_timer){var _20e=this.currentPopup.parentMenu;if(_20e.focusedChild){_20e.focusedChild._setSelected(false);}_20e.focusedChild=this.currentPopup.from_item;_20e.focusedChild._setSelected(true);this._stopPendingCloseTimer(this.currentPopup);}},onItemHover:function(item){if(this.isActive){this.focusChild(item);if(this.focusedChild.popup&&!this.focusedChild.disabled&&!this.hover_timer){this.hover_timer=setTimeout(_4.hitch(this,"_openPopup"),this.popupDelay);}}if(this.focusedChild){this.focusChild(item);}this._hoveredChild=item;},_onChildBlur:function(item){this._stopPopupTimer();item._setSelected(false);var _20f=item.popup;if(_20f){this._stopPendingCloseTimer(_20f);_20f._pendingClose_timer=setTimeout(function(){_20f._pendingClose_timer=null;if(_20f.parentMenu){_20f.parentMenu.currentPopup=null;}_5.popup.close(_20f);},this.popupDelay);}},onItemUnhover:function(item){if(this.isActive){this._stopPopupTimer();}if(this._hoveredChild==item){this._hoveredChild=null;}},_stopPopupTimer:function(){if(this.hover_timer){clearTimeout(this.hover_timer);this.hover_timer=null;}},_stopPendingCloseTimer:function(_210){if(_210._pendingClose_timer){clearTimeout(_210._pendingClose_timer);_210._pendingClose_timer=null;}},_stopFocusTimer:function(){if(this._focus_timer){clearTimeout(this._focus_timer);this._focus_timer=null;}},_getTopMenu:function(){for(var top=this;top.parentMenu;top=top.parentMenu){}return top;},onItemClick:function(item,evt){if(typeof this.isShowingNow=="undefined"){this._markActive();}this.focusChild(item);if(item.disabled){return false;}if(item.popup){this._openPopup();}else{this.onExecute();item.onClick(evt);}},_openPopup:function(){this._stopPopupTimer();var _211=this.focusedChild;if(!_211){return;}var _212=_211.popup;if(_212.isShowingNow){return;}if(this.currentPopup){this._stopPendingCloseTimer(this.currentPopup);_5.popup.close(this.currentPopup);}_212.parentMenu=this;_212.from_item=_211;var self=this;_5.popup.open({parent:this,popup:_212,around:_211.domNode,orient:this._orient||(this.isLeftToRight()?{"TR":"TL","TL":"TR","BR":"BL","BL":"BR"}:{"TL":"TR","TR":"TL","BL":"BR","BR":"BL"}),onCancel:function(){self.focusChild(_211);self._cleanUp();_211._setSelected(true);self.focusedChild=_211;},onExecute:_4.hitch(this,"_cleanUp")});this.currentPopup=_212;_212.connect(_212.domNode,"onmouseenter",_4.hitch(self,"_onPopupHover"));if(_212.focus){_212._focus_timer=setTimeout(_4.hitch(_212,function(){this._focus_timer=null;this.focus();}),0);}},_markActive:function(){this.isActive=true;_4.replaceClass(this.domNode,"dijitMenuActive","dijitMenuPassive");},onOpen:function(e){this.isShowingNow=true;this._markActive();},_markInactive:function(){this.isActive=false;_4.replaceClass(this.domNode,"dijitMenuPassive","dijitMenuActive");},onClose:function(){this._stopFocusTimer();this._markInactive();this.isShowingNow=false;this.parentMenu=null;},_closeChild:function(){this._stopPopupTimer();var _213=this.focusedChild&&this.focusedChild.from_item;if(this.currentPopup){if(_5._curFocus&&_4.isDescendant(_5._curFocus,this.currentPopup.domNode)){this.focusedChild.focusNode.focus();}_5.popup.close(this.currentPopup);this.currentPopup=null;}if(this.focusedChild){this.focusedChild._setSelected(false);this.focusedChild._onUnhover();this.focusedChild=null;}},_onItemFocus:function(item){if(this._hoveredChild&&this._hoveredChild!=item){this._hoveredChild._onUnhover();}},_onBlur:function(){this._cleanUp();this.inherited(arguments);},_cleanUp:function(){this._closeChild();if(typeof this.isShowingNow=="undefined"){this._markInactive();}}});_4.declare("dijit.Menu",_5._MenuBase,{constructor:function(){this._bindings=[];},templateString:_4.cache("dijit","templates/Menu.html","<table class=\"dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable\" role=\"menu\" tabIndex=\"${tabIndex}\" dojoAttachEvent=\"onkeypress:_onKeyPress\" cellspacing=\"0\">\r\n\t<tbody class=\"dijitReset\" dojoAttachPoint=\"containerNode\"></tbody>\r\n</table>\r\n"),baseClass:"dijitMenu",targetNodeIds:[],contextMenuForWindow:false,leftClickToOpen:false,refocus:true,postCreate:function(){if(this.contextMenuForWindow){this.bindDomNode(_4.body());}else{_4.forEach(this.targetNodeIds,this.bindDomNode,this);}var k=_4.keys,l=this.isLeftToRight();this._openSubMenuKey=l?k.RIGHT_ARROW:k.LEFT_ARROW;this._closeSubMenuKey=l?k.LEFT_ARROW:k.RIGHT_ARROW;this.connectKeyNavHandlers([k.UP_ARROW],[k.DOWN_ARROW]);},_onKeyPress:function(evt){if(evt.ctrlKey||evt.altKey){return;}switch(evt.charOrCode){case this._openSubMenuKey:this._moveToPopup(evt);_4.stopEvent(evt);break;case this._closeSubMenuKey:if(this.parentMenu){if(this.parentMenu._isMenuBar){this.parentMenu.focusPrev();}else{this.onCancel(false);}}else{_4.stopEvent(evt);}break;}},_iframeContentWindow:function(_214){var win=_4.window.get(this._iframeContentDocument(_214))||this._iframeContentDocument(_214)["__parent__"]||(_214.name&&_4.doc.frames[_214.name])||null;return win;},_iframeContentDocument:function(_215){var doc=_215.contentDocument||(_215.contentWindow&&_215.contentWindow.document)||(_215.name&&_4.doc.frames[_215.name]&&_4.doc.frames[_215.name].document)||null;return doc;},bindDomNode:function(node){node=_4.byId(node);var cn;if(node.tagName.toLowerCase()=="iframe"){var _216=node,win=this._iframeContentWindow(_216);cn=_4.withGlobal(win,_4.body);}else{cn=(node==_4.body()?_4.doc.documentElement:node);}var _217={node:node,iframe:_216};_4.attr(node,"_dijitMenu"+this.id,this._bindings.push(_217));var _218=_4.hitch(this,function(cn){return [_4.connect(cn,this.leftClickToOpen?"onclick":"oncontextmenu",this,function(evt){_4.stopEvent(evt);this._scheduleOpen(evt.target,_216,{x:evt.pageX,y:evt.pageY});}),_4.connect(cn,"onkeydown",this,function(evt){if(evt.shiftKey&&evt.keyCode==_4.keys.F10){_4.stopEvent(evt);this._scheduleOpen(evt.target,_216);}})];});_217.connects=cn?_218(cn):[];if(_216){_217.onloadHandler=_4.hitch(this,function(){var win=this._iframeContentWindow(_216);cn=_4.withGlobal(win,_4.body);_217.connects=_218(cn);});if(_216.addEventListener){_216.addEventListener("load",_217.onloadHandler,false);}else{_216.attachEvent("onload",_217.onloadHandler);}}},unBindDomNode:function(_219){var node;try{node=_4.byId(_219);}catch(e){return;}var _21a="_dijitMenu"+this.id;if(node&&_4.hasAttr(node,_21a)){var bid=_4.attr(node,_21a)-1,b=this._bindings[bid];_4.forEach(b.connects,_4.disconnect);var _21b=b.iframe;if(_21b){if(_21b.removeEventListener){_21b.removeEventListener("load",b.onloadHandler,false);}else{_21b.detachEvent("onload",b.onloadHandler);}}_4.removeAttr(node,_21a);delete this._bindings[bid];}},_scheduleOpen:function(_21c,_21d,_21e){if(!this._openTimer){this._openTimer=setTimeout(_4.hitch(this,function(){delete this._openTimer;this._openMyself({target:_21c,iframe:_21d,coords:_21e});}),1);}},_openMyself:function(args){var _21f=args.target,_220=args.iframe,_221=args.coords;if(_221){if(_220){var od=_21f.ownerDocument,ifc=_4.position(_220,true),win=this._iframeContentWindow(_220),_222=_4.withGlobal(win,"_docScroll",_4);var cs=_4.getComputedStyle(_220),tp=_4._toPixelValue,left=(_4.isIE&&_4.isQuirks?0:tp(_220,cs.paddingLeft))+(_4.isIE&&_4.isQuirks?tp(_220,cs.borderLeftWidth):0),top=(_4.isIE&&_4.isQuirks?0:tp(_220,cs.paddingTop))+(_4.isIE&&_4.isQuirks?tp(_220,cs.borderTopWidth):0);_221.x+=ifc.x+left-_222.x;_221.y+=ifc.y+top-_222.y;}}else{_221=_4.position(_21f,true);_221.x+=10;_221.y+=10;}var self=this;var _223=_5.getFocus(this);function _224(){if(self.refocus){_5.focus(_223);}_5.popup.close(self);};_5.popup.open({popup:this,x:_221.x,y:_221.y,onExecute:_224,onCancel:_224,orient:this.isLeftToRight()?"L":"R"});this.focus();this._onBlur=function(){this.inherited("_onBlur",arguments);_5.popup.close(this);};},uninitialize:function(){_4.forEach(this._bindings,function(b){if(b){this.unBindDomNode(b.node);}},this);this.inherited(arguments);}});}if(!_4._hasResource["dojox.html.metrics"]){_4._hasResource["dojox.html.metrics"]=true;_4.provide("dojox.html.metrics");(function(){var dhm=_6.html.metrics;dhm.getFontMeasurements=function(){var _225={"1em":0,"1ex":0,"100%":0,"12pt":0,"16px":0,"xx-small":0,"x-small":0,"small":0,"medium":0,"large":0,"x-large":0,"xx-large":0};if(_4.isIE){_4.doc.documentElement.style.fontSize="100%";}var div=_4.doc.createElement("div");var ds=div.style;ds.position="absolute";ds.left="-100px";ds.top="0";ds.width="30px";ds.height="1000em";ds.borderWidth="0";ds.margin="0";ds.padding="0";ds.outline="0";ds.lineHeight="1";ds.overflow="hidden";_4.body().appendChild(div);for(var p in _225){ds.fontSize=p;_225[p]=Math.round(div.offsetHeight*12/16)*16/12/1000;}_4.body().removeChild(div);div=null;return _225;};var _226=null;dhm.getCachedFontMeasurements=function(_227){if(_227||!_226){_226=dhm.getFontMeasurements();}return _226;};var _228=null,_229={};dhm.getTextBox=function(text,_22a,_22b){var m,s;if(!_228){m=_228=_4.doc.createElement("div");var c=_4.doc.createElement("div");c.appendChild(m);s=c.style;s.overflow="scroll";s.position="absolute";s.left="0px";s.top="-10000px";s.width="1px";s.height="1px";s.visibility="hidden";s.borderWidth="0";s.margin="0";s.padding="0";s.outline="0";_4.body().appendChild(c);}else{m=_228;}m.className="";s=m.style;s.borderWidth="0";s.margin="0";s.padding="0";s.outline="0";if(arguments.length>1&&_22a){for(var i in _22a){if(i in _229){continue;}s[i]=_22a[i];}}if(arguments.length>2&&_22b){m.className=_22b;}m.innerHTML=text;var box=_4.position(m);box.w=m.parentNode.scrollWidth;return box;};var _22c={w:16,h:16};dhm.getScrollbar=function(){return {w:_22c.w,h:_22c.h};};dhm._fontResizeNode=null;dhm.initOnFontResize=function(_22d){var f=dhm._fontResizeNode=_4.doc.createElement("iframe");var fs=f.style;fs.position="absolute";fs.width="5em";fs.height="10em";fs.top="-10000px";if(_4.isIE){f.onreadystatechange=function(){if(f.contentWindow.document.readyState=="complete"){f.onresize=f.contentWindow.parent[_6._scopeName].html.metrics._fontresize;}};}else{f.onload=function(){f.contentWindow.onresize=f.contentWindow.parent[_6._scopeName].html.metrics._fontresize;};}f.setAttribute("src","javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'");_4.body().appendChild(f);dhm.initOnFontResize=function(){};};dhm.onFontResize=function(){};dhm._fontresize=function(){dhm.onFontResize();};_4.addOnUnload(function(){var f=dhm._fontResizeNode;if(f){if(_4.isIE&&f.onresize){f.onresize=null;}else{if(f.contentWindow&&f.contentWindow.onresize){f.contentWindow.onresize=null;}}dhm._fontResizeNode=null;}});_4.addOnLoad(function(){try{var n=_4.doc.createElement("div");n.style.cssText="top:0;left:0;width:100px;height:100px;overflow:scroll;position:absolute;visibility:hidden;";_4.body().appendChild(n);_22c.w=n.offsetWidth-n.clientWidth;_22c.h=n.offsetHeight-n.clientHeight;_4.body().removeChild(n);delete n;}catch(e){}if("fontSizeWatch" in _4.config&&!!_4.config.fontSizeWatch){dhm.initOnFontResize();}});})();}if(!_4._hasResource["dojox.grid.util"]){_4._hasResource["dojox.grid.util"]=true;_4.provide("dojox.grid.util");(function(){var dgu=_6.grid.util;dgu.na="...";dgu.rowIndexTag="gridRowIndex";dgu.gridViewTag="gridView";dgu.fire=function(ob,ev,args){var fn=ob&&ev&&ob[ev];return fn&&(args?fn.apply(ob,args):ob[ev]());};dgu.setStyleHeightPx=function(_22e,_22f){if(_22f>=0){var s=_22e.style;var v=_22f+"px";if(_22e&&s["height"]!=v){s["height"]=v;}}};dgu.mouseEvents=["mouseover","mouseout","mousedown","mouseup","click","dblclick","contextmenu"];dgu.keyEvents=["keyup","keydown","keypress"];dgu.funnelEvents=function(_230,_231,_232,_233){var evts=(_233?_233:dgu.mouseEvents.concat(dgu.keyEvents));for(var i=0,l=evts.length;i<l;i++){_231.connect(_230,"on"+evts[i],_232);}};dgu.removeNode=function(_234){_234=_4.byId(_234);_234&&_234.parentNode&&_234.parentNode.removeChild(_234);return _234;};dgu.arrayCompare=function(inA,inB){for(var i=0,l=inA.length;i<l;i++){if(inA[i]!=inB[i]){return false;}}return (inA.length==inB.length);};dgu.arrayInsert=function(_235,_236,_237){if(_235.length<=_236){_235[_236]=_237;}else{_235.splice(_236,0,_237);}};dgu.arrayRemove=function(_238,_239){_238.splice(_239,1);};dgu.arraySwap=function(_23a,inI,inJ){var _23b=_23a[inI];_23a[inI]=_23a[inJ];_23a[inJ]=_23b;};})();}if(!_4._hasResource["dojox.grid._Scroller"]){_4._hasResource["dojox.grid._Scroller"]=true;_4.provide("dojox.grid._Scroller");(function(){var _23c=function(_23d){var i=0,n,p=_23d.parentNode;while((n=p.childNodes[i++])){if(n==_23d){return i-1;}}return -1;};var _23e=function(_23f){if(!_23f){return;}var _240=function(inW){return inW.domNode&&_4.isDescendant(inW.domNode,_23f,true);};var ws=_5.registry.filter(_240);for(var i=0,w;(w=ws[i]);i++){w.destroy();}delete ws;};var _241=function(_242){var node=_4.byId(_242);return (node&&node.tagName?node.tagName.toLowerCase():"");};var _243=function(_244,_245){var _246=[];var i=0,n;while((n=_244.childNodes[i])){i++;if(_241(n)==_245){_246.push(n);}}return _246;};var _247=function(_248){return _243(_248,"div");};_4.declare("dojox.grid._Scroller",null,{constructor:function(_249){this.setContentNodes(_249);this.pageHeights=[];this.pageNodes=[];this.stack=[];},rowCount:0,defaultRowHeight:32,keepRows:100,contentNode:null,scrollboxNode:null,defaultPageHeight:0,keepPages:10,pageCount:0,windowHeight:0,firstVisibleRow:0,lastVisibleRow:0,averageRowHeight:0,page:0,pageTop:0,init:function(_24a,_24b,_24c){switch(arguments.length){case 3:this.rowsPerPage=_24c;case 2:this.keepRows=_24b;case 1:this.rowCount=_24a;default:break;}this.defaultPageHeight=this.defaultRowHeight*this.rowsPerPage;this.pageCount=this._getPageCount(this.rowCount,this.rowsPerPage);this.setKeepInfo(this.keepRows);this.invalidate();if(this.scrollboxNode){this.scrollboxNode.scrollTop=0;this.scroll(0);this.scrollboxNode.onscroll=_4.hitch(this,"onscroll");}},_getPageCount:function(_24d,_24e){return _24d?(Math.ceil(_24d/_24e)||1):0;},destroy:function(){this.invalidateNodes();delete this.contentNodes;delete this.contentNode;delete this.scrollboxNode;},setKeepInfo:function(_24f){this.keepRows=_24f;this.keepPages=!this.keepRows?this.keepPages:Math.max(Math.ceil(this.keepRows/this.rowsPerPage),2);},setContentNodes:function(_250){this.contentNodes=_250;this.colCount=(this.contentNodes?this.contentNodes.length:0);this.pageNodes=[];for(var i=0;i<this.colCount;i++){this.pageNodes[i]=[];}},getDefaultNodes:function(){return this.pageNodes[0]||[];},invalidate:function(){this._invalidating=true;this.invalidateNodes();this.pageHeights=[];this.height=(this.pageCount?(this.pageCount-1)*this.defaultPageHeight+this.calcLastPageHeight():0);this.resize();this._invalidating=false;},updateRowCount:function(_251){this.invalidateNodes();this.rowCount=_251;var _252=this.pageCount;if(_252===0){this.height=1;}this.pageCount=this._getPageCount(this.rowCount,this.rowsPerPage);if(this.pageCount<_252){for(var i=_252-1;i>=this.pageCount;i--){this.height-=this.getPageHeight(i);delete this.pageHeights[i];}}else{if(this.pageCount>_252){this.height+=this.defaultPageHeight*(this.pageCount-_252-1)+this.calcLastPageHeight();}}this.resize();},pageExists:function(_253){return Boolean(this.getDefaultPageNode(_253));},measurePage:function(_254){if(this.grid.rowHeight){var _255=this.grid.rowHeight+1;return ((_254+1)*this.rowsPerPage>this.rowCount?this.rowCount-_254*this.rowsPerPage:this.rowsPerPage)*_255;}var n=this.getDefaultPageNode(_254);return (n&&n.innerHTML)?n.offsetHeight:undefined;},positionPage:function(_256,_257){for(var i=0;i<this.colCount;i++){this.pageNodes[i][_256].style.top=_257+"px";}},repositionPages:function(_258){var _259=this.getDefaultNodes();var last=0;for(var i=0;i<this.stack.length;i++){last=Math.max(this.stack[i],last);}var n=_259[_258];var y=(n?this.getPageNodePosition(n)+this.getPageHeight(_258):0);for(var p=_258+1;p<=last;p++){n=_259[p];if(n){if(this.getPageNodePosition(n)==y){return;}this.positionPage(p,y);}y+=this.getPageHeight(p);}},installPage:function(_25a){for(var i=0;i<this.colCount;i++){this.contentNodes[i].appendChild(this.pageNodes[i][_25a]);}},preparePage:function(_25b,_25c){var p=(_25c?this.popPage():null);for(var i=0;i<this.colCount;i++){var _25d=this.pageNodes[i];var _25e=(p===null?this.createPageNode():this.invalidatePageNode(p,_25d));_25e.pageIndex=_25b;_25d[_25b]=_25e;}},renderPage:function(_25f){var _260=[];var i,j;for(i=0;i<this.colCount;i++){_260[i]=this.pageNodes[i][_25f];}for(i=0,j=_25f*this.rowsPerPage;(i<this.rowsPerPage)&&(j<this.rowCount);i++,j++){this.renderRow(j,_260);}},removePage:function(_261){for(var i=0,j=_261*this.rowsPerPage;i<this.rowsPerPage;i++,j++){this.removeRow(j);}},destroyPage:function(_262){for(var i=0;i<this.colCount;i++){var n=this.invalidatePageNode(_262,this.pageNodes[i]);if(n){_4.destroy(n);}}},pacify:function(_263){},pacifying:false,pacifyTicks:200,setPacifying:function(_264){if(this.pacifying!=_264){this.pacifying=_264;this.pacify(this.pacifying);}},startPacify:function(){this.startPacifyTicks=new Date().getTime();},doPacify:function(){var _265=(new Date().getTime()-this.startPacifyTicks)>this.pacifyTicks;this.setPacifying(true);this.startPacify();return _265;},endPacify:function(){this.setPacifying(false);},resize:function(){if(this.scrollboxNode){this.windowHeight=this.scrollboxNode.clientHeight;}for(var i=0;i<this.colCount;i++){_6.grid.util.setStyleHeightPx(this.contentNodes[i],Math.max(1,this.height));}var _266=(!this._invalidating);if(!_266){var ah=this.grid.get("autoHeight");if(typeof ah=="number"&&ah<=Math.min(this.rowsPerPage,this.rowCount)){_266=true;}}if(_266){this.needPage(this.page,this.pageTop);}var _267=(this.page<this.pageCount-1)?this.rowsPerPage:((this.rowCount%this.rowsPerPage)||this.rowsPerPage);var _268=this.getPageHeight(this.page);this.averageRowHeight=(_268>0&&_267>0)?(_268/_267):0;},calcLastPageHeight:function(){if(!this.pageCount){return 0;}var _269=this.pageCount-1;var _26a=((this.rowCount%this.rowsPerPage)||(this.rowsPerPage))*this.defaultRowHeight;this.pageHeights[_269]=_26a;return _26a;},updateContentHeight:function(inDh){this.height+=inDh;this.resize();},updatePageHeight:function(_26b,_26c,_26d){if(this.pageExists(_26b)){var oh=this.getPageHeight(_26b);var h=(this.measurePage(_26b));if(h===undefined){h=oh;}this.pageHeights[_26b]=h;if(oh!=h){this.updateContentHeight(h-oh);var ah=this.grid.get("autoHeight");if((typeof ah=="number"&&ah>this.rowCount)||(ah===true&&!_26c)){if(!_26d){this.grid.sizeChange();}else{var ns=this.grid.viewsNode.style;ns.height=parseInt(ns.height)+h-oh+"px";this.repositionPages(_26b);}}else{this.repositionPages(_26b);}}return h;}return 0;},rowHeightChanged:function(_26e,_26f){this.updatePageHeight(Math.floor(_26e/this.rowsPerPage),false,_26f);},invalidateNodes:function(){while(this.stack.length){this.destroyPage(this.popPage());}},createPageNode:function(){var p=document.createElement("div");_4.attr(p,"role","presentation");p.style.position="absolute";p.style[_4._isBodyLtr()?"left":"right"]="0";return p;},getPageHeight:function(_270){var ph=this.pageHeights[_270];return (ph!==undefined?ph:this.defaultPageHeight);},pushPage:function(_271){return this.stack.push(_271);},popPage:function(){return this.stack.shift();},findPage:function(_272){var i=0,h=0;for(var ph=0;i<this.pageCount;i++,h+=ph){ph=this.getPageHeight(i);if(h+ph>=_272){break;}}this.page=i;this.pageTop=h;},buildPage:function(_273,_274,_275){this.preparePage(_273,_274);this.positionPage(_273,_275);this.installPage(_273);this.renderPage(_273);this.pushPage(_273);},needPage:function(_276,_277){var h=this.getPageHeight(_276),oh=h;if(!this.pageExists(_276)){this.buildPage(_276,(!this.grid._autoHeight&&this.keepPages&&(this.stack.length>=this.keepPages)),_277);h=this.updatePageHeight(_276,true);}else{this.positionPage(_276,_277);}return h;},onscroll:function(){this.scroll(this.scrollboxNode.scrollTop);},scroll:function(_278){this.grid.scrollTop=_278;if(this.colCount){this.startPacify();this.findPage(_278);var h=this.height;var b=this.getScrollBottom(_278);for(var p=this.page,y=this.pageTop;(p<this.pageCount)&&((b<0)||(y<b));p++){y+=this.needPage(p,y);}this.firstVisibleRow=this.getFirstVisibleRow(this.page,this.pageTop,_278);this.lastVisibleRow=this.getLastVisibleRow(p-1,y,b);if(h!=this.height){this.repositionPages(p-1);}this.endPacify();}},getScrollBottom:function(_279){return (this.windowHeight>=0?_279+this.windowHeight:-1);},processNodeEvent:function(e,_27a){var t=e.target;while(t&&(t!=_27a)&&t.parentNode&&(t.parentNode.parentNode!=_27a)){t=t.parentNode;}if(!t||!t.parentNode||(t.parentNode.parentNode!=_27a)){return false;}var page=t.parentNode;e.topRowIndex=page.pageIndex*this.rowsPerPage;e.rowIndex=e.topRowIndex+_23c(t);e.rowTarget=t;return true;},processEvent:function(e){return this.processNodeEvent(e,this.contentNode);},renderRow:function(_27b,_27c){},removeRow:function(_27d){},getDefaultPageNode:function(_27e){return this.getDefaultNodes()[_27e];},positionPageNode:function(_27f,_280){},getPageNodePosition:function(_281){return _281.offsetTop;},invalidatePageNode:function(_282,_283){var p=_283[_282];if(p){delete _283[_282];this.removePage(_282,p);_23e(p);p.innerHTML="";}return p;},getPageRow:function(_284){return _284*this.rowsPerPage;},getLastPageRow:function(_285){return Math.min(this.rowCount,this.getPageRow(_285+1))-1;},getFirstVisibleRow:function(_286,_287,_288){if(!this.pageExists(_286)){return 0;}var row=this.getPageRow(_286);var _289=this.getDefaultNodes();var rows=_247(_289[_286]);for(var i=0,l=rows.length;i<l&&_287<_288;i++,row++){_287+=rows[i].offsetHeight;}return (row?row-1:row);},getLastVisibleRow:function(_28a,_28b,_28c){if(!this.pageExists(_28a)){return 0;}var _28d=this.getDefaultNodes();var row=this.getLastPageRow(_28a);var rows=_247(_28d[_28a]);for(var i=rows.length-1;i>=0&&_28b>_28c;i--,row--){_28b-=rows[i].offsetHeight;}return row+1;},findTopRow:function(_28e){var _28f=this.getDefaultNodes();var rows=_247(_28f[this.page]);for(var i=0,l=rows.length,t=this.pageTop,h;i<l;i++){h=rows[i].offsetHeight;t+=h;if(t>=_28e){this.offset=h-(t-_28e);return i+this.page*this.rowsPerPage;}}return -1;},findScrollTop:function(_290){var _291=Math.floor(_290/this.rowsPerPage);var t=0;var i,l;for(i=0;i<_291;i++){t+=this.getPageHeight(i);}this.pageTop=t;this.page=_291;this.needPage(_291,this.pageTop);var _292=this.getDefaultNodes();var rows=_247(_292[_291]);var r=_290-this.rowsPerPage*_291;for(i=0,l=rows.length;i<l&&i<r;i++){t+=rows[i].offsetHeight;}return t;},dummy:0});})();}if(!_4._hasResource["dojox.grid.cells._base"]){_4._hasResource["dojox.grid.cells._base"]=true;_4.provide("dojox.grid.cells._base");_4.declare("dojox.grid._DeferredTextWidget",_5._Widget,{deferred:null,_destroyOnRemove:true,postCreate:function(){if(this.deferred){this.deferred.addBoth(_4.hitch(this,function(text){if(this.domNode){this.domNode.innerHTML=text;}}));}}});(function(){var _293=function(_294){try{_6.grid.util.fire(_294,"focus");_6.grid.util.fire(_294,"select");}catch(e){}};var _295=function(){setTimeout(_4.hitch.apply(_4,arguments),0);};var dgc=_6.grid.cells;_4.declare("dojox.grid.cells._Base",null,{styles:"",classes:"",editable:false,alwaysEditing:false,formatter:null,defaultValue:"...",value:null,hidden:false,noresize:false,draggable:true,_valueProp:"value",_formatPending:false,constructor:function(_296){this._props=_296||{};_4.mixin(this,_296);if(this.draggable===undefined){this.draggable=true;}},_defaultFormat:function(_297,_298){var s=this.grid.formatterScope||this;var f=this.formatter;if(f&&s&&typeof f=="string"){f=this.formatter=s[f];}var v=(_297!=this.defaultValue&&f)?f.apply(s,_298):_297;if(typeof v=="undefined"){return this.defaultValue;}if(v&&v.addBoth){v=new _6.grid._DeferredTextWidget({deferred:v},_4.create("span",{innerHTML:this.defaultValue}));}if(v&&v.declaredClass&&v.startup){return "<div class='dojoxGridStubNode' linkWidget='"+v.id+"' cellIdx='"+this.index+"'>"+this.defaultValue+"</div>";}return v;},format:function(_299,_29a){var f,i=this.grid.edit.info,d=this.get?this.get(_299,_29a):(this.value||this.defaultValue);d=(d&&d.replace&&this.grid.escapeHTMLInData)?d.replace(/&/g,"&amp;").replace(/</g,"&lt;"):d;if(this.editable&&(this.alwaysEditing||(i.rowIndex==_299&&i.cell==this))){return this.formatEditing(d,_299);}else{return this._defaultFormat(d,[d,_299,this]);}},formatEditing:function(_29b,_29c){},getNode:function(_29d){return this.view.getCellNode(_29d,this.index);},getHeaderNode:function(){return this.view.getHeaderCellNode(this.index);},getEditNode:function(_29e){return (this.getNode(_29e)||0).firstChild||0;},canResize:function(){var uw=this.unitWidth;return uw&&(uw!=="auto");},isFlex:function(){var uw=this.unitWidth;return uw&&_4.isString(uw)&&(uw=="auto"||uw.slice(-1)=="%");},applyEdit:function(_29f,_2a0){this.grid.edit.applyCellEdit(_29f,this,_2a0);},cancelEdit:function(_2a1){this.grid.doCancelEdit(_2a1);},_onEditBlur:function(_2a2){if(this.grid.edit.isEditCell(_2a2,this.index)){this.grid.edit.apply();}},registerOnBlur:function(_2a3,_2a4){if(this.commitOnBlur){_4.connect(_2a3,"onblur",function(e){setTimeout(_4.hitch(this,"_onEditBlur",_2a4),250);});}},needFormatNode:function(_2a5,_2a6){this._formatPending=true;_295(this,"_formatNode",_2a5,_2a6);},cancelFormatNode:function(){this._formatPending=false;},_formatNode:function(_2a7,_2a8){if(this._formatPending){this._formatPending=false;_4.setSelectable(this.grid.domNode,true);this.formatNode(this.getEditNode(_2a8),_2a7,_2a8);}},formatNode:function(_2a9,_2aa,_2ab){if(_4.isIE){_295(this,"focus",_2ab,_2a9);}else{this.focus(_2ab,_2a9);}},dispatchEvent:function(m,e){if(m in this){return this[m](e);}},getValue:function(_2ac){return this.getEditNode(_2ac)[this._valueProp];},setValue:function(_2ad,_2ae){var n=this.getEditNode(_2ad);if(n){n[this._valueProp]=_2ae;}},focus:function(_2af,_2b0){_293(_2b0||this.getEditNode(_2af));},save:function(_2b1){this.value=this.value||this.getValue(_2b1);},restore:function(_2b2){this.setValue(_2b2,this.value);},_finish:function(_2b3){_4.setSelectable(this.grid.domNode,false);this.cancelFormatNode();},apply:function(_2b4){this.applyEdit(this.getValue(_2b4),_2b4);this._finish(_2b4);},cancel:function(_2b5){this.cancelEdit(_2b5);this._finish(_2b5);}});dgc._Base.markupFactory=function(node,_2b6){var d=_4;var _2b7=d.trim(d.attr(node,"formatter")||"");if(_2b7){_2b6.formatter=_4.getObject(_2b7)||_2b7;}var get=d.trim(d.attr(node,"get")||"");if(get){_2b6.get=_4.getObject(get);}var _2b8=function(attr,cell,_2b9){var _2ba=d.trim(d.attr(node,attr)||"");if(_2ba){cell[_2b9||attr]=!(_2ba.toLowerCase()=="false");}};_2b8("sortDesc",_2b6);_2b8("editable",_2b6);_2b8("alwaysEditing",_2b6);_2b8("noresize",_2b6);_2b8("draggable",_2b6);var _2bb=d.trim(d.attr(node,"loadingText")||d.attr(node,"defaultValue")||"");if(_2bb){_2b6.defaultValue=_2bb;}var _2bc=function(attr,cell,_2bd){var _2be=d.trim(d.attr(node,attr)||"")||undefined;if(_2be){cell[_2bd||attr]=_2be;}};_2bc("styles",_2b6);_2bc("headerStyles",_2b6);_2bc("cellStyles",_2b6);_2bc("classes",_2b6);_2bc("headerClasses",_2b6);_2bc("cellClasses",_2b6);};_4.declare("dojox.grid.cells.Cell",dgc._Base,{constructor:function(){this.keyFilter=this.keyFilter;},keyFilter:null,formatEditing:function(_2bf,_2c0){this.needFormatNode(_2bf,_2c0);return "<input class=\"dojoxGridInput\" type=\"text\" value=\""+_2bf+"\">";},formatNode:function(_2c1,_2c2,_2c3){this.inherited(arguments);this.registerOnBlur(_2c1,_2c3);},doKey:function(e){if(this.keyFilter){var key=String.fromCharCode(e.charCode);if(key.search(this.keyFilter)==-1){_4.stopEvent(e);}}},_finish:function(_2c4){this.inherited(arguments);var n=this.getEditNode(_2c4);try{_6.grid.util.fire(n,"blur");}catch(e){}}});dgc.Cell.markupFactory=function(node,_2c5){dgc._Base.markupFactory(node,_2c5);var d=_4;var _2c6=d.trim(d.attr(node,"keyFilter")||"");if(_2c6){_2c5.keyFilter=new RegExp(_2c6);}};_4.declare("dojox.grid.cells.RowIndex",dgc.Cell,{name:"Row",postscript:function(){this.editable=false;},get:function(_2c7){return _2c7+1;}});dgc.RowIndex.markupFactory=function(node,_2c8){dgc.Cell.markupFactory(node,_2c8);};_4.declare("dojox.grid.cells.Select",dgc.Cell,{options:null,values:null,returnIndex:-1,constructor:function(_2c9){this.values=this.values||this.options;},formatEditing:function(_2ca,_2cb){this.needFormatNode(_2ca,_2cb);var h=["<select class=\"dojoxGridSelect\">"];for(var i=0,o,v;((o=this.options[i])!==undefined)&&((v=this.values[i])!==undefined);i++){h.push("<option",(_2ca==v?" selected":"")," value=\""+v+"\"",">",o,"</option>");}h.push("</select>");return h.join("");},getValue:function(_2cc){var n=this.getEditNode(_2cc);if(n){var i=n.selectedIndex,o=n.options[i];return this.returnIndex>-1?i:o.value||o.innerHTML;}}});dgc.Select.markupFactory=function(node,cell){dgc.Cell.markupFactory(node,cell);var d=_4;var _2cd=d.trim(d.attr(node,"options")||"");if(_2cd){var o=_2cd.split(",");if(o[0]!=_2cd){cell.options=o;}}var _2ce=d.trim(d.attr(node,"values")||"");if(_2ce){var v=_2ce.split(",");if(v[0]!=_2ce){cell.values=v;}}};_4.declare("dojox.grid.cells.AlwaysEdit",dgc.Cell,{alwaysEditing:true,_formatNode:function(_2cf,_2d0){this.formatNode(this.getEditNode(_2d0),_2cf,_2d0);},applyStaticValue:function(_2d1){var e=this.grid.edit;e.applyCellEdit(this.getValue(_2d1),this,_2d1);e.start(this,_2d1,true);}});dgc.AlwaysEdit.markupFactory=function(node,cell){dgc.Cell.markupFactory(node,cell);};_4.declare("dojox.grid.cells.Bool",dgc.AlwaysEdit,{_valueProp:"checked",formatEditing:function(_2d2,_2d3){return "<input class=\"dojoxGridInput\" type=\"checkbox\""+(_2d2?" checked=\"checked\"":"")+" style=\"width: auto\" />";},doclick:function(e){if(e.target.tagName=="INPUT"){this.applyStaticValue(e.rowIndex);}}});dgc.Bool.markupFactory=function(node,cell){dgc.AlwaysEdit.markupFactory(node,cell);};})();}if(!_4._hasResource["dojox.grid.cells"]){_4._hasResource["dojox.grid.cells"]=true;_4.provide("dojox.grid.cells");}if(!_4._hasResource["dojo.dnd.common"]){_4._hasResource["dojo.dnd.common"]=true;_4.provide("dojo.dnd.common");_4.getObject("dnd",true,_4);_4.dnd.getCopyKeyState=_4.isCopyKey;_4.dnd._uniqueId=0;_4.dnd.getUniqueId=function(){var id;do{id=_4._scopeName+"Unique"+(++_4.dnd._uniqueId);}while(_4.byId(id));return id;};_4.dnd._empty={};_4.dnd.isFormElement=function(e){var t=e.target;if(t.nodeType==3){t=t.parentNode;}return " button textarea input select option ".indexOf(" "+t.tagName.toLowerCase()+" ")>=0;};}if(!_4._hasResource["dojo.dnd.autoscroll"]){_4._hasResource["dojo.dnd.autoscroll"]=true;_4.provide("dojo.dnd.autoscroll");_4.getObject("dnd",true,_4);_4.dnd.getViewport=_4.window.getBox;_4.dnd.V_TRIGGER_AUTOSCROLL=32;_4.dnd.H_TRIGGER_AUTOSCROLL=32;_4.dnd.V_AUTOSCROLL_VALUE=16;_4.dnd.H_AUTOSCROLL_VALUE=16;_4.dnd.autoScroll=function(e){var v=_4.window.getBox(),dx=0,dy=0;if(e.clientX<_4.dnd.H_TRIGGER_AUTOSCROLL){dx=-_4.dnd.H_AUTOSCROLL_VALUE;}else{if(e.clientX>v.w-_4.dnd.H_TRIGGER_AUTOSCROLL){dx=_4.dnd.H_AUTOSCROLL_VALUE;}}if(e.clientY<_4.dnd.V_TRIGGER_AUTOSCROLL){dy=-_4.dnd.V_AUTOSCROLL_VALUE;}else{if(e.clientY>v.h-_4.dnd.V_TRIGGER_AUTOSCROLL){dy=_4.dnd.V_AUTOSCROLL_VALUE;}}window.scrollBy(dx,dy);};_4.dnd._validNodes={"div":1,"p":1,"td":1};_4.dnd._validOverflow={"auto":1,"scroll":1};_4.dnd.autoScrollNodes=function(e){for(var n=e.target;n;){if(n.nodeType==1&&(n.tagName.toLowerCase() in _4.dnd._validNodes)){var s=_4.getComputedStyle(n);if(s.overflow.toLowerCase() in _4.dnd._validOverflow){var b=_4._getContentBox(n,s),t=_4.position(n,true);var w=Math.min(_4.dnd.H_TRIGGER_AUTOSCROLL,b.w/2),h=Math.min(_4.dnd.V_TRIGGER_AUTOSCROLL,b.h/2),rx=e.pageX-t.x,ry=e.pageY-t.y,dx=0,dy=0;if(_4.isWebKit||_4.isOpera){rx+=_4.body().scrollLeft;ry+=_4.body().scrollTop;}if(rx>0&&rx<b.w){if(rx<w){dx=-w;}else{if(rx>b.w-w){dx=w;}}}if(ry>0&&ry<b.h){if(ry<h){dy=-h;}else{if(ry>b.h-h){dy=h;}}}var _2d4=n.scrollLeft,_2d5=n.scrollTop;n.scrollLeft=n.scrollLeft+dx;n.scrollTop=n.scrollTop+dy;if(_2d4!=n.scrollLeft||_2d5!=n.scrollTop){return;}}}try{n=n.parentNode;}catch(x){n=null;}}_4.dnd.autoScroll(e);};}if(!_4._hasResource["dojo.dnd.Mover"]){_4._hasResource["dojo.dnd.Mover"]=true;_4.provide("dojo.dnd.Mover");_4.declare("dojo.dnd.Mover",null,{constructor:function(node,e,host){this.node=_4.byId(node);var pos=e.touches?e.touches[0]:e;this.marginBox={l:pos.pageX,t:pos.pageY};this.mouseButton=e.button;var h=(this.host=host),d=node.ownerDocument;this.events=[_4.connect(d,"onmousemove",this,"onFirstMove"),_4.connect(d,"ontouchmove",this,"onFirstMove"),_4.connect(d,"onmousemove",this,"onMouseMove"),_4.connect(d,"ontouchmove",this,"onMouseMove"),_4.connect(d,"onmouseup",this,"onMouseUp"),_4.connect(d,"ontouchend",this,"onMouseUp"),_4.connect(d,"ondragstart",_4.stopEvent),_4.connect(d.body,"onselectstart",_4.stopEvent)];if(h&&h.onMoveStart){h.onMoveStart(this);}},onMouseMove:function(e){_4.dnd.autoScroll(e);var m=this.marginBox,pos=e.touches?e.touches[0]:e;this.host.onMove(this,{l:m.l+pos.pageX,t:m.t+pos.pageY},e);_4.stopEvent(e);},onMouseUp:function(e){if(_4.isWebKit&&_4.isMac&&this.mouseButton==2?e.button==0:this.mouseButton==e.button){this.destroy();}_4.stopEvent(e);},onFirstMove:function(e){var s=this.node.style,l,t,h=this.host;switch(s.position){case "relative":case "absolute":l=Math.round(parseFloat(s.left))||0;t=Math.round(parseFloat(s.top))||0;break;default:s.position="absolute";var m=_4.marginBox(this.node);var b=_4.doc.body;var bs=_4.getComputedStyle(b);var bm=_4._getMarginBox(b,bs);var bc=_4._getContentBox(b,bs);l=m.l-(bc.l-bm.l);t=m.t-(bc.t-bm.t);break;}this.marginBox.l=l-this.marginBox.l;this.marginBox.t=t-this.marginBox.t;if(h&&h.onFirstMove){h.onFirstMove(this,e);}_4.disconnect(this.events.shift());_4.disconnect(this.events.shift());},destroy:function(){_4.forEach(this.events,_4.disconnect);var h=this.host;if(h&&h.onMoveStop){h.onMoveStop(this);}this.events=this.node=this.host=null;}});}if(!_4._hasResource["dojo.dnd.Moveable"]){_4._hasResource["dojo.dnd.Moveable"]=true;_4.provide("dojo.dnd.Moveable");_4.declare("dojo.dnd.Moveable",null,{handle:"",delay:0,skip:false,constructor:function(node,_2d6){this.node=_4.byId(node);if(!_2d6){_2d6={};}this.handle=_2d6.handle?_4.byId(_2d6.handle):null;if(!this.handle){this.handle=this.node;}this.delay=_2d6.delay>0?_2d6.delay:0;this.skip=_2d6.skip;this.mover=_2d6.mover?_2d6.mover:_4.dnd.Mover;this.events=[_4.connect(this.handle,"onmousedown",this,"onMouseDown"),_4.connect(this.handle,"ontouchstart",this,"onMouseDown"),_4.connect(this.handle,"ondragstart",this,"onSelectStart"),_4.connect(this.handle,"onselectstart",this,"onSelectStart")];},markupFactory:function(_2d7,node){return new _4.dnd.Moveable(node,_2d7);},destroy:function(){_4.forEach(this.events,_4.disconnect);this.events=this.node=this.handle=null;},onMouseDown:function(e){if(this.skip&&_4.dnd.isFormElement(e)){return;}if(this.delay){this.events.push(_4.connect(this.handle,"onmousemove",this,"onMouseMove"),_4.connect(this.handle,"ontouchmove",this,"onMouseMove"),_4.connect(this.handle,"onmouseup",this,"onMouseUp"),_4.connect(this.handle,"ontouchend",this,"onMouseUp"));var pos=e.touches?e.touches[0]:e;this._lastX=pos.pageX;this._lastY=pos.pageY;}else{this.onDragDetected(e);}_4.stopEvent(e);},onMouseMove:function(e){var pos=e.touches?e.touches[0]:e;if(Math.abs(pos.pageX-this._lastX)>this.delay||Math.abs(pos.pageY-this._lastY)>this.delay){this.onMouseUp(e);this.onDragDetected(e);}_4.stopEvent(e);},onMouseUp:function(e){for(var i=0;i<2;++i){_4.disconnect(this.events.pop());}_4.stopEvent(e);},onSelectStart:function(e){if(!this.skip||!_4.dnd.isFormElement(e)){_4.stopEvent(e);}},onDragDetected:function(e){new this.mover(this.node,e,this);},onMoveStart:function(_2d8){_4.publish("/dnd/move/start",[_2d8]);_4.addClass(_4.body(),"dojoMove");_4.addClass(this.node,"dojoMoveItem");},onMoveStop:function(_2d9){_4.publish("/dnd/move/stop",[_2d9]);_4.removeClass(_4.body(),"dojoMove");_4.removeClass(this.node,"dojoMoveItem");},onFirstMove:function(_2da,e){},onMove:function(_2db,_2dc,e){this.onMoving(_2db,_2dc);var s=_2db.node.style;s.left=_2dc.l+"px";s.top=_2dc.t+"px";this.onMoved(_2db,_2dc);},onMoving:function(_2dd,_2de){},onMoved:function(_2df,_2e0){}});}if(!_4._hasResource["dojox.grid._Builder"]){_4._hasResource["dojox.grid._Builder"]=true;_4.provide("dojox.grid._Builder");(function(){var dg=_6.grid;var _2e1=function(td){return td.cellIndex>=0?td.cellIndex:_4.indexOf(td.parentNode.cells,td);};var _2e2=function(tr){return tr.rowIndex>=0?tr.rowIndex:_4.indexOf(tr.parentNode.childNodes,tr);};var _2e3=function(_2e4,_2e5){return _2e4&&((_2e4.rows||0)[_2e5]||_2e4.childNodes[_2e5]);};var _2e6=function(node){for(var n=node;n&&n.tagName!="TABLE";n=n.parentNode){}return n;};var _2e7=function(_2e8,_2e9){for(var n=_2e8;n&&_2e9(n);n=n.parentNode){}return n;};var _2ea=function(_2eb){var name=_2eb.toUpperCase();return function(node){return node.tagName!=name;};};var _2ec=_6.grid.util.rowIndexTag;var _2ed=_6.grid.util.gridViewTag;dg._Builder=_4.extend(function(view){if(view){this.view=view;this.grid=view.grid;}},{view:null,_table:"<table class=\"dojoxGridRowTable\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" role=\"presentation\"",getTableArray:function(){var html=[this._table];if(this.view.viewWidth){html.push([" style=\"width:",this.view.viewWidth,";\""].join(""));}html.push(">");return html;},generateCellMarkup:function(_2ee,_2ef,_2f0,_2f1){var _2f2=[],html;if(_2f1){var _2f3=_2ee.index!=_2ee.grid.getSortIndex()?"":_2ee.grid.sortInfo>0?"aria-sort=\"ascending\"":"aria-sort=\"descending\"";if(!_2ee.id){_2ee.id=this.grid.id+"Hdr"+_2ee.index;}html=["<th tabIndex=\"-1\" aria-readonly=\"true\" role=\"columnheader\"",_2f3,"id=\"",_2ee.id,"\""];}else{var _2f4=this.grid.editable&&!_2ee.editable?"aria-readonly=\"true\"":"";html=["<td tabIndex=\"-1\" role=\"gridcell\"",_2f4];}if(_2ee.colSpan){html.push(" colspan=\"",_2ee.colSpan,"\"");}if(_2ee.rowSpan){html.push(" rowspan=\"",_2ee.rowSpan,"\"");}html.push(" class=\"dojoxGridCell ");if(_2ee.classes){html.push(_2ee.classes," ");}if(_2f0){html.push(_2f0," ");}_2f2.push(html.join(""));_2f2.push("");html=["\" idx=\"",_2ee.index,"\" style=\""];if(_2ef&&_2ef[_2ef.length-1]!=";"){_2ef+=";";}html.push(_2ee.styles,_2ef||"",_2ee.hidden?"display:none;":"");if(_2ee.unitWidth){html.push("width:",_2ee.unitWidth,";");}_2f2.push(html.join(""));_2f2.push("");html=["\""];if(_2ee.attrs){html.push(" ",_2ee.attrs);}html.push(">");_2f2.push(html.join(""));_2f2.push("");_2f2.push(_2f1?"</th>":"</td>");return _2f2;},isCellNode:function(_2f5){return Boolean(_2f5&&_2f5!=_4.doc&&_4.attr(_2f5,"idx"));},getCellNodeIndex:function(_2f6){return _2f6?Number(_4.attr(_2f6,"idx")):-1;},getCellNode:function(_2f7,_2f8){for(var i=0,row;(row=_2e3(_2f7.firstChild,i));i++){for(var j=0,cell;(cell=row.cells[j]);j++){if(this.getCellNodeIndex(cell)==_2f8){return cell;}}}return null;},findCellTarget:function(_2f9,_2fa){var n=_2f9;while(n&&(!this.isCellNode(n)||(n.offsetParent&&_2ed in n.offsetParent.parentNode&&n.offsetParent.parentNode[_2ed]!=this.view.id))&&(n!=_2fa)){n=n.parentNode;}return n!=_2fa?n:null;},baseDecorateEvent:function(e){e.dispatch="do"+e.type;e.grid=this.grid;e.sourceView=this.view;e.cellNode=this.findCellTarget(e.target,e.rowNode);e.cellIndex=this.getCellNodeIndex(e.cellNode);e.cell=(e.cellIndex>=0?this.grid.getCell(e.cellIndex):null);},findTarget:function(_2fb,_2fc){var n=_2fb;while(n&&(n!=this.domNode)&&(!(_2fc in n)||(_2ed in n&&n[_2ed]!=this.view.id))){n=n.parentNode;}return (n!=this.domNode)?n:null;},findRowTarget:function(_2fd){return this.findTarget(_2fd,_2ec);},isIntraNodeEvent:function(e){try{return (e.cellNode&&e.relatedTarget&&_4.isDescendant(e.relatedTarget,e.cellNode));}catch(x){return false;}},isIntraRowEvent:function(e){try{var row=e.relatedTarget&&this.findRowTarget(e.relatedTarget);return !row&&(e.rowIndex==-1)||row&&(e.rowIndex==row.gridRowIndex);}catch(x){return false;}},dispatchEvent:function(e){if(e.dispatch in this){return this[e.dispatch](e);}return false;},domouseover:function(e){if(e.cellNode&&(e.cellNode!=this.lastOverCellNode)){this.lastOverCellNode=e.cellNode;this.grid.onMouseOver(e);}this.grid.onMouseOverRow(e);},domouseout:function(e){if(e.cellNode&&(e.cellNode==this.lastOverCellNode)&&!this.isIntraNodeEvent(e,this.lastOverCellNode)){this.lastOverCellNode=null;this.grid.onMouseOut(e);if(!this.isIntraRowEvent(e)){this.grid.onMouseOutRow(e);}}},domousedown:function(e){if(e.cellNode){this.grid.onMouseDown(e);}this.grid.onMouseDownRow(e);}});dg._ContentBuilder=_4.extend(function(view){dg._Builder.call(this,view);},dg._Builder.prototype,{update:function(){this.prepareHtml();},prepareHtml:function(){var _2fe=this.grid.get,_2ff=this.view.structure.cells;for(var j=0,row;(row=_2ff[j]);j++){for(var i=0,cell;(cell=row[i]);i++){cell.get=cell.get||(cell.value==undefined)&&_2fe;cell.markup=this.generateCellMarkup(cell,cell.cellStyles,cell.cellClasses,false);if(!this.grid.editable&&cell.editable){this.grid.editable=true;}}}},generateHtml:function(_300,_301){var html=this.getTableArray(),v=this.view,_302=v.structure.cells,item=this.grid.getItem(_301);_6.grid.util.fire(this.view,"onBeforeRow",[_301,_302]);for(var j=0,row;(row=_302[j]);j++){if(row.hidden||row.header){continue;}html.push(!row.invisible?"<tr>":"<tr class=\"dojoxGridInvisible\">");for(var i=0,cell,m,cc,cs;(cell=row[i]);i++){m=cell.markup;cc=cell.customClasses=[];cs=cell.customStyles=[];m[5]=cell.format(_301,item);m[1]=cc.join(" ");m[3]=cs.join(";");html.push.apply(html,m);}html.push("</tr>");}html.push("</table>");return html.join("");},decorateEvent:function(e){e.rowNode=this.findRowTarget(e.target);if(!e.rowNode){return false;}e.rowIndex=e.rowNode[_2ec];this.baseDecorateEvent(e);e.cell=this.grid.getCell(e.cellIndex);return true;}});dg._HeaderBuilder=_4.extend(function(view){this.moveable=null;dg._Builder.call(this,view);},dg._Builder.prototype,{_skipBogusClicks:false,overResizeWidth:4,minColWidth:1,update:function(){if(this.tableMap){this.tableMap.mapRows(this.view.structure.cells);}else{this.tableMap=new dg._TableMap(this.view.structure.cells);}},generateHtml:function(_303,_304){var html=this.getTableArray(),_305=this.view.structure.cells;_6.grid.util.fire(this.view,"onBeforeRow",[-1,_305]);for(var j=0,row;(row=_305[j]);j++){if(row.hidden){continue;}html.push(!row.invisible?"<tr>":"<tr class=\"dojoxGridInvisible\">");for(var i=0,cell,_306;(cell=row[i]);i++){cell.customClasses=[];cell.customStyles=[];if(this.view.simpleStructure){if(cell.draggable){if(cell.headerClasses){if(cell.headerClasses.indexOf("dojoDndItem")==-1){cell.headerClasses+=" dojoDndItem";}}else{cell.headerClasses="dojoDndItem";}}if(cell.attrs){if(cell.attrs.indexOf("dndType='gridColumn_")==-1){cell.attrs+=" dndType='gridColumn_"+this.grid.id+"'";}}else{cell.attrs="dndType='gridColumn_"+this.grid.id+"'";}}_306=this.generateCellMarkup(cell,cell.headerStyles,cell.headerClasses,true);_306[5]=(_304!=undefined?_304:_303(cell));_306[3]=cell.customStyles.join(";");_306[1]=cell.customClasses.join(" ");html.push(_306.join(""));}html.push("</tr>");}html.push("</table>");return html.join("");},getCellX:function(e){var n,x=e.layerX;if(_4.isMoz){n=_2e7(e.target,_2ea("th"));x-=(n&&n.offsetLeft)||0;var t=e.sourceView.getScrollbarWidth();if(!_4._isBodyLtr()){table=_2e7(n,_2ea("table"));x-=(table&&table.offsetLeft)||0;}}n=_2e7(e.target,function(){if(!n||n==e.cellNode){return false;}x+=(n.offsetLeft<0?0:n.offsetLeft);return true;});return x;},decorateEvent:function(e){this.baseDecorateEvent(e);e.rowIndex=-1;e.cellX=this.getCellX(e);return true;},prepareResize:function(e,mod){do{var i=_2e1(e.cellNode);e.cellNode=(i?e.cellNode.parentNode.cells[i+mod]:null);e.cellIndex=(e.cellNode?this.getCellNodeIndex(e.cellNode):-1);}while(e.cellNode&&e.cellNode.style.display=="none");return Boolean(e.cellNode);},canResize:function(e){if(!e.cellNode||e.cellNode.colSpan>1){return false;}var cell=this.grid.getCell(e.cellIndex);return !cell.noresize&&cell.canResize();},overLeftResizeArea:function(e){if(_4.hasClass(_4.body(),"dojoDndMove")){return false;}if(_4.isIE){var tN=e.target;if(_4.hasClass(tN,"dojoxGridArrowButtonNode")||_4.hasClass(tN,"dojoxGridArrowButtonChar")){return false;}}if(_4._isBodyLtr()){return (e.cellIndex>0)&&(e.cellX>0&&e.cellX<this.overResizeWidth)&&this.prepareResize(e,-1);}var t=e.cellNode&&(e.cellX>0&&e.cellX<this.overResizeWidth);return t;},overRightResizeArea:function(e){if(_4.hasClass(_4.body(),"dojoDndMove")){return false;}if(_4.isIE){var tN=e.target;if(_4.hasClass(tN,"dojoxGridArrowButtonNode")||_4.hasClass(tN,"dojoxGridArrowButtonChar")){return false;}}if(_4._isBodyLtr()){return e.cellNode&&(e.cellX>=e.cellNode.offsetWidth-this.overResizeWidth);}return (e.cellIndex>0)&&(e.cellX>=e.cellNode.offsetWidth-this.overResizeWidth)&&this.prepareResize(e,-1);},domousemove:function(e){if(!this.moveable){var c=(this.overRightResizeArea(e)?"dojoxGridColResize":(this.overLeftResizeArea(e)?"dojoxGridColResize":""));if(c&&!this.canResize(e)){c="dojoxGridColNoResize";}_4.toggleClass(e.sourceView.headerNode,"dojoxGridColNoResize",(c=="dojoxGridColNoResize"));_4.toggleClass(e.sourceView.headerNode,"dojoxGridColResize",(c=="dojoxGridColResize"));if(_4.isIE){var t=e.sourceView.headerNode.scrollLeft;e.sourceView.headerNode.scrollLeft=t;}if(c){_4.stopEvent(e);}}},domousedown:function(e){if(!this.moveable){if((this.overRightResizeArea(e)||this.overLeftResizeArea(e))&&this.canResize(e)){this.beginColumnResize(e);}else{this.grid.onMouseDown(e);this.grid.onMouseOverRow(e);}}},doclick:function(e){if(this._skipBogusClicks){_4.stopEvent(e);return true;}return false;},colResizeSetup:function(e,_307){var _308=_4.contentBox(e.sourceView.headerNode);if(_307){this.lineDiv=document.createElement("div");var vw=(_4.position||_4._abs)(e.sourceView.headerNode,true);var _309=_4.contentBox(e.sourceView.domNode);var l=e.pageX;if(!_4._isBodyLtr()&&_4.isIE<8){l-=_6.html.metrics.getScrollbar().w;}_4.style(this.lineDiv,{top:vw.y+"px",left:l+"px",height:(_309.h+_308.h)+"px"});_4.addClass(this.lineDiv,"dojoxGridResizeColLine");this.lineDiv._origLeft=l;_4.body().appendChild(this.lineDiv);}var _30a=[],_30b=this.tableMap.findOverlappingNodes(e.cellNode);for(var i=0,cell;(cell=_30b[i]);i++){_30a.push({node:cell,index:this.getCellNodeIndex(cell),width:cell.offsetWidth});}var view=e.sourceView;var adj=_4._isBodyLtr()?1:-1;var _30c=e.grid.views.views;var _30d=[];for(var j=view.idx+adj,_30e;(_30e=_30c[j]);j=j+adj){_30d.push({node:_30e.headerNode,left:window.parseInt(_30e.headerNode.style.left)});}var _30f=view.headerContentNode.firstChild;var drag={scrollLeft:e.sourceView.headerNode.scrollLeft,view:view,node:e.cellNode,index:e.cellIndex,w:_4.contentBox(e.cellNode).w,vw:_308.w,table:_30f,tw:_4.contentBox(_30f).w,spanners:_30a,followers:_30d};return drag;},beginColumnResize:function(e){this.moverDiv=document.createElement("div");_4.style(this.moverDiv,{position:"absolute",left:0});_4.body().appendChild(this.moverDiv);_4.addClass(this.grid.domNode,"dojoxGridColumnResizing");var m=(this.moveable=new _4.dnd.Moveable(this.moverDiv));var drag=this.colResizeSetup(e,true);m.onMove=_4.hitch(this,"doResizeColumn",drag);_4.connect(m,"onMoveStop",_4.hitch(this,function(){this.endResizeColumn(drag);if(drag.node.releaseCapture){drag.node.releaseCapture();}this.moveable.destroy();delete this.moveable;this.moveable=null;_4.removeClass(this.grid.domNode,"dojoxGridColumnResizing");}));if(e.cellNode.setCapture){e.cellNode.setCapture();}m.onMouseDown(e);},doResizeColumn:function(_310,_311,_312){var _313=_312.l;var data={deltaX:_313,w:_310.w+(_4._isBodyLtr()?_313:-_313),vw:_310.vw+_313,tw:_310.tw+_313};this.dragRecord={inDrag:_310,mover:_311,leftTop:_312};if(data.w>=this.minColWidth){if(!_311){this.doResizeNow(_310,data);}else{_4.style(this.lineDiv,"left",(this.lineDiv._origLeft+data.deltaX)+"px");}}},endResizeColumn:function(_314){if(this.dragRecord){var _315=this.dragRecord.leftTop;var _316=_4._isBodyLtr()?_315.l:-_315.l;_316+=Math.max(_314.w+_316,this.minColWidth)-(_314.w+_316);if(_4.isWebKit&&_314.spanners.length){_316+=_4._getPadBorderExtents(_314.spanners[0].node).w;}var data={deltaX:_316,w:_314.w+_316,vw:_314.vw+_316,tw:_314.tw+_316};this.doResizeNow(_314,data);delete this.dragRecord;}_4.destroy(this.lineDiv);_4.destroy(this.moverDiv);_4.destroy(this.moverDiv);delete this.moverDiv;this._skipBogusClicks=true;_314.view.update();this._skipBogusClicks=false;this.grid.onResizeColumn(_314.index);},doResizeNow:function(_317,data){_317.view.convertColPctToFixed();if(_317.view.flexCells&&!_317.view.testFlexCells()){var t=_2e6(_317.node);if(t){(t.style.width="");}}var i,s,sw,f,fl;for(i=0;(s=_317.spanners[i]);i++){sw=s.width+data.deltaX;s.node.style.width=sw+"px";_317.view.setColWidth(s.index,sw);}if(_4._isBodyLtr()||!_4.isIE){for(i=0;(f=_317.followers[i]);i++){fl=f.left+data.deltaX;f.node.style.left=fl+"px";}}_317.node.style.width=data.w+"px";_317.view.setColWidth(_317.index,data.w);_317.view.headerNode.style.width=data.vw+"px";_317.view.setColumnsWidth(data.tw);if(!_4._isBodyLtr()){_317.view.headerNode.scrollLeft=_317.scrollLeft+data.deltaX;}}});dg._TableMap=_4.extend(function(rows){this.mapRows(rows);},{map:null,mapRows:function(_318){var _319=_318.length;if(!_319){return;}this.map=[];var row;for(var k=0;(row=_318[k]);k++){this.map[k]=[];}for(var j=0;(row=_318[j]);j++){for(var i=0,x=0,cell,_31a,_31b;(cell=row[i]);i++){while(this.map[j][x]){x++;}this.map[j][x]={c:i,r:j};_31b=cell.rowSpan||1;_31a=cell.colSpan||1;for(var y=0;y<_31b;y++){for(var s=0;s<_31a;s++){this.map[j+y][x+s]=this.map[j][x];}}x+=_31a;}}},dumpMap:function(){for(var j=0,row,h="";(row=this.map[j]);j++,h=""){for(var i=0,cell;(cell=row[i]);i++){h+=cell.r+","+cell.c+" ";}}},getMapCoords:function(_31c,_31d){for(var j=0,row;(row=this.map[j]);j++){for(var i=0,cell;(cell=row[i]);i++){if(cell.c==_31d&&cell.r==_31c){return {j:j,i:i};}}}return {j:-1,i:-1};},getNode:function(_31e,_31f,_320){var row=_31e&&_31e.rows[_31f];return row&&row.cells[_320];},_findOverlappingNodes:function(_321,_322,_323){var _324=[];var m=this.getMapCoords(_322,_323);for(var j=0,row;(row=this.map[j]);j++){if(j==m.j){continue;}var rw=row[m.i];var n=(rw?this.getNode(_321,rw.r,rw.c):null);if(n){_324.push(n);}}return _324;},findOverlappingNodes:function(_325){return this._findOverlappingNodes(_2e6(_325),_2e2(_325.parentNode),_2e1(_325));}});})();}if(!_4._hasResource["dojo.dnd.Container"]){_4._hasResource["dojo.dnd.Container"]=true;_4.provide("dojo.dnd.Container");_4.declare("dojo.dnd.Container",null,{skipForm:false,constructor:function(node,_326){this.node=_4.byId(node);if(!_326){_326={};}this.creator=_326.creator||null;this.skipForm=_326.skipForm;this.parent=_326.dropParent&&_4.byId(_326.dropParent);this.map={};this.current=null;this.containerState="";_4.addClass(this.node,"dojoDndContainer");if(!(_326&&_326._skipStartup)){this.startup();}this.events=[_4.connect(this.node,"onmouseover",this,"onMouseOver"),_4.connect(this.node,"onmouseout",this,"onMouseOut"),_4.connect(this.node,"ondragstart",this,"onSelectStart"),_4.connect(this.node,"onselectstart",this,"onSelectStart")];},creator:function(){},getItem:function(key){return this.map[key];},setItem:function(key,data){this.map[key]=data;},delItem:function(key){delete this.map[key];},forInItems:function(f,o){o=o||_4.global;var m=this.map,e=_4.dnd._empty;for(var i in m){if(i in e){continue;}f.call(o,m[i],i,this);}return o;},clearItems:function(){this.map={};},getAllNodes:function(){return _4.query("> .dojoDndItem",this.parent);},sync:function(){var map={};this.getAllNodes().forEach(function(node){if(node.id){var item=this.getItem(node.id);if(item){map[node.id]=item;return;}}else{node.id=_4.dnd.getUniqueId();}var type=node.getAttribute("dndType"),data=node.getAttribute("dndData");map[node.id]={data:data||node.innerHTML,type:type?type.split(/\s*,\s*/):["text"]};},this);this.map=map;return this;},insertNodes:function(data,_327,_328){if(!this.parent.firstChild){_328=null;}else{if(_327){if(!_328){_328=this.parent.firstChild;}}else{if(_328){_328=_328.nextSibling;}}}if(_328){for(var i=0;i<data.length;++i){var t=this._normalizedCreator(data[i]);this.setItem(t.node.id,{data:t.data,type:t.type});this.parent.insertBefore(t.node,_328);}}else{for(var i=0;i<data.length;++i){var t=this._normalizedCreator(data[i]);this.setItem(t.node.id,{data:t.data,type:t.type});this.parent.appendChild(t.node);}}return this;},destroy:function(){_4.forEach(this.events,_4.disconnect);this.clearItems();this.node=this.parent=this.current=null;},markupFactory:function(_329,node){_329._skipStartup=true;return new _4.dnd.Container(node,_329);},startup:function(){if(!this.parent){this.parent=this.node;if(this.parent.tagName.toLowerCase()=="table"){var c=this.parent.getElementsByTagName("tbody");if(c&&c.length){this.parent=c[0];}}}this.defaultCreator=_4.dnd._defaultCreator(this.parent);this.sync();},onMouseOver:function(e){var n=e.relatedTarget;while(n){if(n==this.node){break;}try{n=n.parentNode;}catch(x){n=null;}}if(!n){this._changeState("Container","Over");this.onOverEvent();}n=this._getChildByEvent(e);if(this.current==n){return;}if(this.current){this._removeItemClass(this.current,"Over");}if(n){this._addItemClass(n,"Over");}this.current=n;},onMouseOut:function(e){for(var n=e.relatedTarget;n;){if(n==this.node){return;}try{n=n.parentNode;}catch(x){n=null;}}if(this.current){this._removeItemClass(this.current,"Over");this.current=null;}this._changeState("Container","");this.onOutEvent();},onSelectStart:function(e){if(!this.skipForm||!_4.dnd.isFormElement(e)){_4.stopEvent(e);}},onOverEvent:function(){},onOutEvent:function(){},_changeState:function(type,_32a){var _32b="dojoDnd"+type;var _32c=type.toLowerCase()+"State";_4.replaceClass(this.node,_32b+_32a,_32b+this[_32c]);this[_32c]=_32a;},_addItemClass:function(node,type){_4.addClass(node,"dojoDndItem"+type);},_removeItemClass:function(node,type){_4.removeClass(node,"dojoDndItem"+type);},_getChildByEvent:function(e){var node=e.target;if(node){for(var _32d=node.parentNode;_32d;node=_32d,_32d=node.parentNode){if(_32d==this.parent&&_4.hasClass(node,"dojoDndItem")){return node;}}}return null;},_normalizedCreator:function(item,hint){var t=(this.creator||this.defaultCreator).call(this,item,hint);if(!_4.isArray(t.type)){t.type=["text"];}if(!t.node.id){t.node.id=_4.dnd.getUniqueId();}_4.addClass(t.node,"dojoDndItem");return t;}});_4.dnd._createNode=function(tag){if(!tag){return _4.dnd._createSpan;}return function(text){return _4.create(tag,{innerHTML:text});};};_4.dnd._createTrTd=function(text){var tr=_4.create("tr");_4.create("td",{innerHTML:text},tr);return tr;};_4.dnd._createSpan=function(text){return _4.create("span",{innerHTML:text});};_4.dnd._defaultCreatorNodes={ul:"li",ol:"li",div:"div",p:"div"};_4.dnd._defaultCreator=function(node){var tag=node.tagName.toLowerCase();var c=tag=="tbody"||tag=="thead"?_4.dnd._createTrTd:_4.dnd._createNode(_4.dnd._defaultCreatorNodes[tag]);return function(item,hint){var _32e=item&&_4.isObject(item),data,type,n;if(_32e&&item.tagName&&item.nodeType&&item.getAttribute){data=item.getAttribute("dndData")||item.innerHTML;type=item.getAttribute("dndType");type=type?type.split(/\s*,\s*/):["text"];n=item;}else{data=(_32e&&item.data)?item.data:item;type=(_32e&&item.type)?item.type:["text"];n=(hint=="avatar"?_4.dnd._createSpan:c)(String(data));}if(!n.id){n.id=_4.dnd.getUniqueId();}return {node:n,data:data,type:type};};};}if(!_4._hasResource["dojo.dnd.Selector"]){_4._hasResource["dojo.dnd.Selector"]=true;_4.provide("dojo.dnd.Selector");_4.declare("dojo.dnd.Selector",_4.dnd.Container,{constructor:function(node,_32f){if(!_32f){_32f={};}this.singular=_32f.singular;this.autoSync=_32f.autoSync;this.selection={};this.anchor=null;this.simpleSelection=false;this.events.push(_4.connect(this.node,"onmousedown",this,"onMouseDown"),_4.connect(this.node,"onmouseup",this,"onMouseUp"));},singular:false,getSelectedNodes:function(){var t=new _4.NodeList();var e=_4.dnd._empty;for(var i in this.selection){if(i in e){continue;}t.push(_4.byId(i));}return t;},selectNone:function(){return this._removeSelection()._removeAnchor();},selectAll:function(){this.forInItems(function(data,id){this._addItemClass(_4.byId(id),"Selected");this.selection[id]=1;},this);return this._removeAnchor();},deleteSelectedNodes:function(){var e=_4.dnd._empty;for(var i in this.selection){if(i in e){continue;}var n=_4.byId(i);this.delItem(i);_4.destroy(n);}this.anchor=null;this.selection={};return this;},forInSelectedItems:function(f,o){o=o||_4.global;var s=this.selection,e=_4.dnd._empty;for(var i in s){if(i in e){continue;}f.call(o,this.getItem(i),i,this);}},sync:function(){_4.dnd.Selector.superclass.sync.call(this);if(this.anchor){if(!this.getItem(this.anchor.id)){this.anchor=null;}}var t=[],e=_4.dnd._empty;for(var i in this.selection){if(i in e){continue;}if(!this.getItem(i)){t.push(i);}}_4.forEach(t,function(i){delete this.selection[i];},this);return this;},insertNodes:function(_330,data,_331,_332){var _333=this._normalizedCreator;this._normalizedCreator=function(item,hint){var t=_333.call(this,item,hint);if(_330){if(!this.anchor){this.anchor=t.node;this._removeItemClass(t.node,"Selected");this._addItemClass(this.anchor,"Anchor");}else{if(this.anchor!=t.node){this._removeItemClass(t.node,"Anchor");this._addItemClass(t.node,"Selected");}}this.selection[t.node.id]=1;}else{this._removeItemClass(t.node,"Selected");this._removeItemClass(t.node,"Anchor");}return t;};_4.dnd.Selector.superclass.insertNodes.call(this,data,_331,_332);this._normalizedCreator=_333;return this;},destroy:function(){_4.dnd.Selector.superclass.destroy.call(this);this.selection=this.anchor=null;},markupFactory:function(_334,node){_334._skipStartup=true;return new _4.dnd.Selector(node,_334);},onMouseDown:function(e){if(this.autoSync){this.sync();}if(!this.current){return;}if(!this.singular&&!_4.isCopyKey(e)&&!e.shiftKey&&(this.current.id in this.selection)){this.simpleSelection=true;if(e.button===_4.mouseButtons.LEFT){_4.stopEvent(e);}return;}if(!this.singular&&e.shiftKey){if(!_4.isCopyKey(e)){this._removeSelection();}var c=this.getAllNodes();if(c.length){if(!this.anchor){this.anchor=c[0];this._addItemClass(this.anchor,"Anchor");}this.selection[this.anchor.id]=1;if(this.anchor!=this.current){var i=0;for(;i<c.length;++i){var node=c[i];if(node==this.anchor||node==this.current){break;}}for(++i;i<c.length;++i){var node=c[i];if(node==this.anchor||node==this.current){break;}this._addItemClass(node,"Selected");this.selection[node.id]=1;}this._addItemClass(this.current,"Selected");this.selection[this.current.id]=1;}}}else{if(this.singular){if(this.anchor==this.current){if(_4.isCopyKey(e)){this.selectNone();}}else{this.selectNone();this.anchor=this.current;this._addItemClass(this.anchor,"Anchor");this.selection[this.current.id]=1;}}else{if(_4.isCopyKey(e)){if(this.anchor==this.current){delete this.selection[this.anchor.id];this._removeAnchor();}else{if(this.current.id in this.selection){this._removeItemClass(this.current,"Selected");delete this.selection[this.current.id];}else{if(this.anchor){this._removeItemClass(this.anchor,"Anchor");this._addItemClass(this.anchor,"Selected");}this.anchor=this.current;this._addItemClass(this.current,"Anchor");this.selection[this.current.id]=1;}}}else{if(!(this.current.id in this.selection)){this.selectNone();this.anchor=this.current;this._addItemClass(this.current,"Anchor");this.selection[this.current.id]=1;}}}}_4.stopEvent(e);},onMouseUp:function(e){if(!this.simpleSelection){return;}this.simpleSelection=false;this.selectNone();if(this.current){this.anchor=this.current;this._addItemClass(this.anchor,"Anchor");this.selection[this.current.id]=1;}},onMouseMove:function(e){this.simpleSelection=false;},onOverEvent:function(){this.onmousemoveEvent=_4.connect(this.node,"onmousemove",this,"onMouseMove");},onOutEvent:function(){_4.disconnect(this.onmousemoveEvent);delete this.onmousemoveEvent;},_removeSelection:function(){var e=_4.dnd._empty;for(var i in this.selection){if(i in e){continue;}var node=_4.byId(i);if(node){this._removeItemClass(node,"Selected");}}this.selection={};return this;},_removeAnchor:function(){if(this.anchor){this._removeItemClass(this.anchor,"Anchor");this.anchor=null;}return this;}});}if(!_4._hasResource["dojo.dnd.Avatar"]){_4._hasResource["dojo.dnd.Avatar"]=true;_4.provide("dojo.dnd.Avatar");_4.declare("dojo.dnd.Avatar",null,{constructor:function(_335){this.manager=_335;this.construct();},construct:function(){this.isA11y=_4.hasClass(_4.body(),"dijit_a11y");var a=_4.create("table",{"class":"dojoDndAvatar",style:{position:"absolute",zIndex:"1999",margin:"0px"}}),_336=this.manager.source,node,b=_4.create("tbody",null,a),tr=_4.create("tr",null,b),td=_4.create("td",null,tr),icon=this.isA11y?_4.create("span",{id:"a11yIcon",innerHTML:this.manager.copy?"+":"<"},td):null,span=_4.create("span",{innerHTML:_336.generateText?this._generateText():""},td),k=Math.min(5,this.manager.nodes.length),i=0;_4.attr(tr,{"class":"dojoDndAvatarHeader",style:{opacity:0.9}});for(;i<k;++i){if(_336.creator){node=_336._normalizedCreator(_336.getItem(this.manager.nodes[i].id).data,"avatar").node;}else{node=this.manager.nodes[i].cloneNode(true);if(node.tagName.toLowerCase()=="tr"){var _337=_4.create("table"),_338=_4.create("tbody",null,_337);_338.appendChild(node);node=_337;}}node.id="";tr=_4.create("tr",null,b);td=_4.create("td",null,tr);td.appendChild(node);_4.attr(tr,{"class":"dojoDndAvatarItem",style:{opacity:(9-i)/10}});}this.node=a;},destroy:function(){_4.destroy(this.node);this.node=false;},update:function(){_4[(this.manager.canDropFlag?"add":"remove")+"Class"](this.node,"dojoDndAvatarCanDrop");if(this.isA11y){var icon=_4.byId("a11yIcon");var text="+";if(this.manager.canDropFlag&&!this.manager.copy){text="< ";}else{if(!this.manager.canDropFlag&&!this.manager.copy){text="o";}else{if(!this.manager.canDropFlag){text="x";}}}icon.innerHTML=text;}_4.query(("tr.dojoDndAvatarHeader td span"+(this.isA11y?" span":"")),this.node).forEach(function(node){node.innerHTML=this._generateText();},this);},_generateText:function(){return this.manager.nodes.length.toString();}});}if(!_4._hasResource["dojo.dnd.Manager"]){_4._hasResource["dojo.dnd.Manager"]=true;_4.provide("dojo.dnd.Manager");_4.declare("dojo.dnd.Manager",null,{constructor:function(){this.avatar=null;this.source=null;this.nodes=[];this.copy=true;this.target=null;this.canDropFlag=false;this.events=[];},OFFSET_X:16,OFFSET_Y:16,overSource:function(_339){if(this.avatar){this.target=(_339&&_339.targetState!="Disabled")?_339:null;this.canDropFlag=Boolean(this.target);this.avatar.update();}_4.publish("/dnd/source/over",[_339]);},outSource:function(_33a){if(this.avatar){if(this.target==_33a){this.target=null;this.canDropFlag=false;this.avatar.update();_4.publish("/dnd/source/over",[null]);}}else{_4.publish("/dnd/source/over",[null]);}},startDrag:function(_33b,_33c,copy){this.source=_33b;this.nodes=_33c;this.copy=Boolean(copy);this.avatar=this.makeAvatar();_4.body().appendChild(this.avatar.node);_4.publish("/dnd/start",[_33b,_33c,this.copy]);this.events=[_4.connect(_4.doc,"onmousemove",this,"onMouseMove"),_4.connect(_4.doc,"onmouseup",this,"onMouseUp"),_4.connect(_4.doc,"onkeydown",this,"onKeyDown"),_4.connect(_4.doc,"onkeyup",this,"onKeyUp"),_4.connect(_4.doc,"ondragstart",_4.stopEvent),_4.connect(_4.body(),"onselectstart",_4.stopEvent)];var c="dojoDnd"+(copy?"Copy":"Move");_4.addClass(_4.body(),c);},canDrop:function(flag){var _33d=Boolean(this.target&&flag);if(this.canDropFlag!=_33d){this.canDropFlag=_33d;this.avatar.update();}},stopDrag:function(){_4.removeClass(_4.body(),["dojoDndCopy","dojoDndMove"]);_4.forEach(this.events,_4.disconnect);this.events=[];this.avatar.destroy();this.avatar=null;this.source=this.target=null;this.nodes=[];},makeAvatar:function(){return new _4.dnd.Avatar(this);},updateAvatar:function(){this.avatar.update();},onMouseMove:function(e){var a=this.avatar;if(a){_4.dnd.autoScrollNodes(e);var s=a.node.style;s.left=(e.pageX+this.OFFSET_X)+"px";s.top=(e.pageY+this.OFFSET_Y)+"px";var copy=Boolean(this.source.copyState(_4.isCopyKey(e)));if(this.copy!=copy){this._setCopyStatus(copy);}}},onMouseUp:function(e){if(this.avatar){if(this.target&&this.canDropFlag){var copy=Boolean(this.source.copyState(_4.isCopyKey(e))),_33e=[this.source,this.nodes,copy,this.target,e];_4.publish("/dnd/drop/before",_33e);_4.publish("/dnd/drop",_33e);}else{_4.publish("/dnd/cancel");}this.stopDrag();}},onKeyDown:function(e){if(this.avatar){switch(e.keyCode){case _4.keys.CTRL:var copy=Boolean(this.source.copyState(true));if(this.copy!=copy){this._setCopyStatus(copy);}break;case _4.keys.ESCAPE:_4.publish("/dnd/cancel");this.stopDrag();break;}}},onKeyUp:function(e){if(this.avatar&&e.keyCode==_4.keys.CTRL){var copy=Boolean(this.source.copyState(false));if(this.copy!=copy){this._setCopyStatus(copy);}}},_setCopyStatus:function(copy){this.copy=copy;this.source._markDndStatus(this.copy);this.updateAvatar();_4.replaceClass(_4.body(),"dojoDnd"+(this.copy?"Copy":"Move"),"dojoDnd"+(this.copy?"Move":"Copy"));}});_4.dnd._manager=null;_4.dnd.manager=function(){if(!_4.dnd._manager){_4.dnd._manager=new _4.dnd.Manager();}return _4.dnd._manager;};}if(!_4._hasResource["dojo.dnd.Source"]){_4._hasResource["dojo.dnd.Source"]=true;_4.provide("dojo.dnd.Source");_4.declare("dojo.dnd.Source",_4.dnd.Selector,{isSource:true,horizontal:false,copyOnly:false,selfCopy:false,selfAccept:true,skipForm:false,withHandles:false,autoSync:false,delay:0,accept:["text"],generateText:true,constructor:function(node,_33f){_4.mixin(this,_4.mixin({},_33f));var type=this.accept;if(type.length){this.accept={};for(var i=0;i<type.length;++i){this.accept[type[i]]=1;}}this.isDragging=false;this.mouseDown=false;this.targetAnchor=null;this.targetBox=null;this.before=true;this._lastX=0;this._lastY=0;this.sourceState="";if(this.isSource){_4.addClass(this.node,"dojoDndSource");}this.targetState="";if(this.accept){_4.addClass(this.node,"dojoDndTarget");}if(this.horizontal){_4.addClass(this.node,"dojoDndHorizontal");}this.topics=[_4.subscribe("/dnd/source/over",this,"onDndSourceOver"),_4.subscribe("/dnd/start",this,"onDndStart"),_4.subscribe("/dnd/drop",this,"onDndDrop"),_4.subscribe("/dnd/cancel",this,"onDndCancel")];},checkAcceptance:function(_340,_341){if(this==_340){return !this.copyOnly||this.selfAccept;}for(var i=0;i<_341.length;++i){var type=_340.getItem(_341[i].id).type;var flag=false;for(var j=0;j<type.length;++j){if(type[j] in this.accept){flag=true;break;}}if(!flag){return false;}}return true;},copyState:function(_342,self){if(_342){return true;}if(arguments.length<2){self=this==_4.dnd.manager().target;}if(self){if(this.copyOnly){return this.selfCopy;}}else{return this.copyOnly;}return false;},destroy:function(){_4.dnd.Source.superclass.destroy.call(this);_4.forEach(this.topics,_4.unsubscribe);this.targetAnchor=null;},markupFactory:function(_343,node){_343._skipStartup=true;return new _4.dnd.Source(node,_343);},onMouseMove:function(e){if(this.isDragging&&this.targetState=="Disabled"){return;}_4.dnd.Source.superclass.onMouseMove.call(this,e);var m=_4.dnd.manager();if(!this.isDragging){if(this.mouseDown&&this.isSource&&(Math.abs(e.pageX-this._lastX)>this.delay||Math.abs(e.pageY-this._lastY)>this.delay)){var _344=this.getSelectedNodes();if(_344.length){m.startDrag(this,_344,this.copyState(_4.isCopyKey(e),true));}}}if(this.isDragging){var _345=false;if(this.current){if(!this.targetBox||this.targetAnchor!=this.current){this.targetBox=_4.position(this.current,true);}if(this.horizontal){_345=(e.pageX-this.targetBox.x)<(this.targetBox.w/2);}else{_345=(e.pageY-this.targetBox.y)<(this.targetBox.h/2);}}if(this.current!=this.targetAnchor||_345!=this.before){this._markTargetAnchor(_345);m.canDrop(!this.current||m.source!=this||!(this.current.id in this.selection));}}},onMouseDown:function(e){if(!this.mouseDown&&this._legalMouseDown(e)&&(!this.skipForm||!_4.dnd.isFormElement(e))){this.mouseDown=true;this._lastX=e.pageX;this._lastY=e.pageY;_4.dnd.Source.superclass.onMouseDown.call(this,e);}},onMouseUp:function(e){if(this.mouseDown){this.mouseDown=false;_4.dnd.Source.superclass.onMouseUp.call(this,e);}},onDndSourceOver:function(_346){if(this!=_346){this.mouseDown=false;if(this.targetAnchor){this._unmarkTargetAnchor();}}else{if(this.isDragging){var m=_4.dnd.manager();m.canDrop(this.targetState!="Disabled"&&(!this.current||m.source!=this||!(this.current.id in this.selection)));}}},onDndStart:function(_347,_348,copy){if(this.autoSync){this.sync();}if(this.isSource){this._changeState("Source",this==_347?(copy?"Copied":"Moved"):"");}var _349=this.accept&&this.checkAcceptance(_347,_348);this._changeState("Target",_349?"":"Disabled");if(this==_347){_4.dnd.manager().overSource(this);}this.isDragging=true;},onDndDrop:function(_34a,_34b,copy,_34c){if(this==_34c){this.onDrop(_34a,_34b,copy);}this.onDndCancel();},onDndCancel:function(){if(this.targetAnchor){this._unmarkTargetAnchor();this.targetAnchor=null;}this.before=true;this.isDragging=false;this.mouseDown=false;this._changeState("Source","");this._changeState("Target","");},onDrop:function(_34d,_34e,copy){if(this!=_34d){this.onDropExternal(_34d,_34e,copy);}else{this.onDropInternal(_34e,copy);}},onDropExternal:function(_34f,_350,copy){var _351=this._normalizedCreator;if(this.creator){this._normalizedCreator=function(node,hint){return _351.call(this,_34f.getItem(node.id).data,hint);};}else{if(copy){this._normalizedCreator=function(node,hint){var t=_34f.getItem(node.id);var n=node.cloneNode(true);n.id=_4.dnd.getUniqueId();return {node:n,data:t.data,type:t.type};};}else{this._normalizedCreator=function(node,hint){var t=_34f.getItem(node.id);_34f.delItem(node.id);return {node:node,data:t.data,type:t.type};};}}this.selectNone();if(!copy&&!this.creator){_34f.selectNone();}this.insertNodes(true,_350,this.before,this.current);if(!copy&&this.creator){_34f.deleteSelectedNodes();}this._normalizedCreator=_351;},onDropInternal:function(_352,copy){var _353=this._normalizedCreator;if(this.current&&this.current.id in this.selection){return;}if(copy){if(this.creator){this._normalizedCreator=function(node,hint){return _353.call(this,this.getItem(node.id).data,hint);};}else{this._normalizedCreator=function(node,hint){var t=this.getItem(node.id);var n=node.cloneNode(true);n.id=_4.dnd.getUniqueId();return {node:n,data:t.data,type:t.type};};}}else{if(!this.current){return;}this._normalizedCreator=function(node,hint){var t=this.getItem(node.id);return {node:node,data:t.data,type:t.type};};}this._removeSelection();this.insertNodes(true,_352,this.before,this.current);this._normalizedCreator=_353;},onDraggingOver:function(){},onDraggingOut:function(){},onOverEvent:function(){_4.dnd.Source.superclass.onOverEvent.call(this);_4.dnd.manager().overSource(this);if(this.isDragging&&this.targetState!="Disabled"){this.onDraggingOver();}},onOutEvent:function(){_4.dnd.Source.superclass.onOutEvent.call(this);_4.dnd.manager().outSource(this);if(this.isDragging&&this.targetState!="Disabled"){this.onDraggingOut();}},_markTargetAnchor:function(_354){if(this.current==this.targetAnchor&&this.before==_354){return;}if(this.targetAnchor){this._removeItemClass(this.targetAnchor,this.before?"Before":"After");}this.targetAnchor=this.current;this.targetBox=null;this.before=_354;if(this.targetAnchor){this._addItemClass(this.targetAnchor,this.before?"Before":"After");}},_unmarkTargetAnchor:function(){if(!this.targetAnchor){return;}this._removeItemClass(this.targetAnchor,this.before?"Before":"After");this.targetAnchor=null;this.targetBox=null;this.before=true;},_markDndStatus:function(copy){this._changeState("Source",copy?"Copied":"Moved");},_legalMouseDown:function(e){if(!_4.mouseButtons.isLeft(e)){return false;}if(!this.withHandles){return true;}for(var node=e.target;node&&node!==this.node;node=node.parentNode){if(_4.hasClass(node,"dojoDndHandle")){return true;}if(_4.hasClass(node,"dojoDndItem")||_4.hasClass(node,"dojoDndIgnore")){break;}}return false;}});_4.declare("dojo.dnd.Target",_4.dnd.Source,{constructor:function(node,_355){this.isSource=false;_4.removeClass(this.node,"dojoDndSource");},markupFactory:function(_356,node){_356._skipStartup=true;return new _4.dnd.Target(node,_356);}});_4.declare("dojo.dnd.AutoSource",_4.dnd.Source,{constructor:function(node,_357){this.autoSync=true;},markupFactory:function(_358,node){_358._skipStartup=true;return new _4.dnd.AutoSource(node,_358);}});}if(!_4._hasResource["dojox.grid._View"]){_4._hasResource["dojox.grid._View"]=true;_4.provide("dojox.grid._View");(function(){var _359=function(_35a,_35b){return _35a.style.cssText==undefined?_35a.getAttribute("style"):_35a.style.cssText;};_4.declare("dojox.grid._View",[_5._Widget,_5._Templated],{defaultWidth:"18em",viewWidth:"",templateString:"<div class=\"dojoxGridView\" role=\"presentation\">\r\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" role=\"presentation\">\r\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" role=\"presentation\">\r\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" role=\"row\"></div>\r\n\t\t</div>\r\n\t</div>\r\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" role=\"presentation\" />\r\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" role=\"presentation\" />\r\n\t<div class=\"dojoxGridScrollbox\" dojoAttachPoint=\"scrollboxNode\" role=\"presentation\">\r\n\t\t<div class=\"dojoxGridContent\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\" role=\"presentation\"></div>\r\n\t</div>\r\n</div>\r\n",themeable:false,classTag:"dojoxGrid",marginBottom:0,rowPad:2,_togglingColumn:-1,_headerBuilderClass:_6.grid._HeaderBuilder,_contentBuilderClass:_6.grid._ContentBuilder,postMixInProperties:function(){this.rowNodes={};},postCreate:function(){this.connect(this.scrollboxNode,"onscroll","doscroll");_6.grid.util.funnelEvents(this.contentNode,this,"doContentEvent",["mouseover","mouseout","click","dblclick","contextmenu","mousedown"]);_6.grid.util.funnelEvents(this.headerNode,this,"doHeaderEvent",["dblclick","mouseover","mouseout","mousemove","mousedown","click","contextmenu"]);this.content=new this._contentBuilderClass(this);this.header=new this._headerBuilderClass(this);if(!_4._isBodyLtr()){this.headerNodeContainer.style.width="";}},destroy:function(){_4.destroy(this.headerNode);delete this.headerNode;for(var i in this.rowNodes){_4.destroy(this.rowNodes[i]);}this.rowNodes={};if(this.source){this.source.destroy();}this.inherited(arguments);},focus:function(){if(_4.isIE||_4.isWebKit||_4.isOpera){this.hiddenFocusNode.focus();}else{this.scrollboxNode.focus();}},setStructure:function(_35c){var vs=(this.structure=_35c);if(vs.width&&!isNaN(vs.width)){this.viewWidth=vs.width+"em";}else{this.viewWidth=vs.width||(vs.noscroll?"auto":this.viewWidth);}this._onBeforeRow=vs.onBeforeRow||function(){};this._onAfterRow=vs.onAfterRow||function(){};this.noscroll=vs.noscroll;if(this.noscroll){this.scrollboxNode.style.overflow="hidden";}this.simpleStructure=Boolean(vs.cells.length==1);this.testFlexCells();this.updateStructure();},_cleanupRowWidgets:function(_35d){if(_35d){_4.forEach(_4.query("[widgetId]",_35d).map(_5.byNode),function(w){if(w._destroyOnRemove){w.destroy();delete w;}else{if(w.domNode&&w.domNode.parentNode){w.domNode.parentNode.removeChild(w.domNode);}}});}},onBeforeRow:function(_35e,_35f){this._onBeforeRow(_35e,_35f);if(_35e>=0){this._cleanupRowWidgets(this.getRowNode(_35e));}},onAfterRow:function(_360,_361,_362){this._onAfterRow(_360,_361,_362);var g=this.grid;_4.forEach(_4.query(".dojoxGridStubNode",_362),function(n){if(n&&n.parentNode){var lw=n.getAttribute("linkWidget");var _363=window.parseInt(_4.attr(n,"cellIdx"),10);var _364=g.getCell(_363);var w=_5.byId(lw);if(w){n.parentNode.replaceChild(w.domNode,n);if(!w._started){w.startup();}}else{n.innerHTML="";}}},this);},testFlexCells:function(){this.flexCells=false;for(var j=0,row;(row=this.structure.cells[j]);j++){for(var i=0,cell;(cell=row[i]);i++){cell.view=this;this.flexCells=this.flexCells||cell.isFlex();}}return this.flexCells;},updateStructure:function(){this.header.update();this.content.update();},getScrollbarWidth:function(){var _365=this.hasVScrollbar();var _366=_4.style(this.scrollboxNode,"overflow");if(this.noscroll||!_366||_366=="hidden"){_365=false;}else{if(_366=="scroll"){_365=true;}}return (_365?_6.html.metrics.getScrollbar().w:0);},getColumnsWidth:function(){var h=this.headerContentNode;return h&&h.firstChild?h.firstChild.offsetWidth:0;},setColumnsWidth:function(_367){this.headerContentNode.firstChild.style.width=_367+"px";if(this.viewWidth){this.viewWidth=_367+"px";}},getWidth:function(){return this.viewWidth||(this.getColumnsWidth()+this.getScrollbarWidth())+"px";},getContentWidth:function(){return Math.max(0,_4._getContentBox(this.domNode).w-this.getScrollbarWidth())+"px";},render:function(){this.scrollboxNode.style.height="";this.renderHeader();if(this._togglingColumn>=0){this.setColumnsWidth(this.getColumnsWidth()-this._togglingColumn);this._togglingColumn=-1;}var _368=this.grid.layout.cells;var _369=_4.hitch(this,function(node,_36a){!_4._isBodyLtr()&&(_36a=!_36a);var inc=_36a?-1:1;var idx=this.header.getCellNodeIndex(node)+inc;var cell=_368[idx];while(cell&&cell.getHeaderNode()&&cell.getHeaderNode().style.display=="none"){idx+=inc;cell=_368[idx];}if(cell){return cell.getHeaderNode();}return null;});if(this.grid.columnReordering&&this.simpleStructure){if(this.source){this.source.destroy();}var _36b="dojoxGrid_bottomMarker";var _36c="dojoxGrid_topMarker";if(this.bottomMarker){_4.destroy(this.bottomMarker);}this.bottomMarker=_4.byId(_36b);if(this.topMarker){_4.destroy(this.topMarker);}this.topMarker=_4.byId(_36c);if(!this.bottomMarker){this.bottomMarker=_4.create("div",{"id":_36b,"class":"dojoxGridColPlaceBottom"},_4.body());this._hide(this.bottomMarker);this.topMarker=_4.create("div",{"id":_36c,"class":"dojoxGridColPlaceTop"},_4.body());this._hide(this.topMarker);}this.arrowDim=_4.contentBox(this.bottomMarker);var _36d=_4.contentBox(this.headerContentNode.firstChild.rows[0]).h;this.source=new _4.dnd.Source(this.headerContentNode.firstChild.rows[0],{horizontal:true,accept:["gridColumn_"+this.grid.id],viewIndex:this.index,generateText:false,onMouseDown:_4.hitch(this,function(e){this.header.decorateEvent(e);if((this.header.overRightResizeArea(e)||this.header.overLeftResizeArea(e))&&this.header.canResize(e)&&!this.header.moveable){this.header.beginColumnResize(e);}else{if(this.grid.headerMenu){this.grid.headerMenu.onCancel(true);}if(e.button===(_4.isIE?1:0)){_4.dnd.Source.prototype.onMouseDown.call(this.source,e);}}}),onMouseOver:_4.hitch(this,function(e){var src=this.source;if(src._getChildByEvent(e)){_4.dnd.Source.prototype.onMouseOver.apply(src,arguments);}}),_markTargetAnchor:_4.hitch(this,function(_36e){var src=this.source;if(src.current==src.targetAnchor&&src.before==_36e){return;}if(src.targetAnchor&&_369(src.targetAnchor,src.before)){src._removeItemClass(_369(src.targetAnchor,src.before),src.before?"After":"Before");}_4.dnd.Source.prototype._markTargetAnchor.call(src,_36e);var _36f=_36e?src.targetAnchor:_369(src.targetAnchor,src.before);var _370=0;if(!_36f){_36f=src.targetAnchor;_370=_4.contentBox(_36f).w+this.arrowDim.w/2+2;}var pos=(_4.position||_4._abs)(_36f,true);var left=Math.floor(pos.x-this.arrowDim.w/2+_370);_4.style(this.bottomMarker,"visibility","visible");_4.style(this.topMarker,"visibility","visible");_4.style(this.bottomMarker,{"left":left+"px","top":(_36d+pos.y)+"px"});_4.style(this.topMarker,{"left":left+"px","top":(pos.y-this.arrowDim.h)+"px"});if(src.targetAnchor&&_369(src.targetAnchor,src.before)){src._addItemClass(_369(src.targetAnchor,src.before),src.before?"After":"Before");}}),_unmarkTargetAnchor:_4.hitch(this,function(){var src=this.source;if(!src.targetAnchor){return;}if(src.targetAnchor&&_369(src.targetAnchor,src.before)){src._removeItemClass(_369(src.targetAnchor,src.before),src.before?"After":"Before");}this._hide(this.bottomMarker);this._hide(this.topMarker);_4.dnd.Source.prototype._unmarkTargetAnchor.call(src);}),destroy:_4.hitch(this,function(){_4.disconnect(this._source_conn);_4.unsubscribe(this._source_sub);_4.dnd.Source.prototype.destroy.call(this.source);if(this.bottomMarker){_4.destroy(this.bottomMarker);delete this.bottomMarker;}if(this.topMarker){_4.destroy(this.topMarker);delete this.topMarker;}}),onDndCancel:_4.hitch(this,function(){_4.dnd.Source.prototype.onDndCancel.call(this.source);this._hide(this.bottomMarker);this._hide(this.topMarker);})});this._source_conn=_4.connect(this.source,"onDndDrop",this,"_onDndDrop");this._source_sub=_4.subscribe("/dnd/drop/before",this,"_onDndDropBefore");this.source.startup();}},_hide:function(node){_4.style(node,{left:"-10000px",top:"-10000px","visibility":"hidden"});},_onDndDropBefore:function(_371,_372,copy){if(_4.dnd.manager().target!==this.source){return;}this.source._targetNode=this.source.targetAnchor;this.source._beforeTarget=this.source.before;var _373=this.grid.views.views;var _374=_373[_371.viewIndex];var _375=_373[this.index];if(_375!=_374){_374.convertColPctToFixed();_375.convertColPctToFixed();}},_onDndDrop:function(_376,_377,copy){if(_4.dnd.manager().target!==this.source){if(_4.dnd.manager().source===this.source){this._removingColumn=true;}return;}this._hide(this.bottomMarker);this._hide(this.topMarker);var _378=function(n){return n?_4.attr(n,"idx"):null;};var w=_4.marginBox(_377[0]).w;if(_376.viewIndex!==this.index){var _379=this.grid.views.views;var _37a=_379[_376.viewIndex];var _37b=_379[this.index];if(_37a.viewWidth&&_37a.viewWidth!="auto"){_37a.setColumnsWidth(_37a.getColumnsWidth()-w);}if(_37b.viewWidth&&_37b.viewWidth!="auto"){_37b.setColumnsWidth(_37b.getColumnsWidth());}}var stn=this.source._targetNode;var stb=this.source._beforeTarget;!_4._isBodyLtr()&&(stb=!stb);var _37c=this.grid.layout;var idx=this.index;delete this.source._targetNode;delete this.source._beforeTarget;_37c.moveColumn(_376.viewIndex,idx,_378(_377[0]),_378(stn),stb);},renderHeader:function(){this.headerContentNode.innerHTML=this.header.generateHtml(this._getHeaderContent);if(this.flexCells){this.contentWidth=this.getContentWidth();this.headerContentNode.firstChild.style.width=this.contentWidth;}_6.grid.util.fire(this,"onAfterRow",[-1,this.structure.cells,this.headerContentNode]);},_getHeaderContent:function(_37d){var n=_37d.name||_37d.grid.getCellName(_37d);var ret=["<div class=\"dojoxGridSortNode"];if(_37d.index!=_37d.grid.getSortIndex()){ret.push("\">");}else{ret=ret.concat([" ",_37d.grid.sortInfo>0?"dojoxGridSortUp":"dojoxGridSortDown","\"><div class=\"dojoxGridArrowButtonChar\">",_37d.grid.sortInfo>0?"&#9650;":"&#9660;","</div><div class=\"dojoxGridArrowButtonNode\" role=\"presentation\"></div>","<div class=\"dojoxGridColCaption\">"]);}ret=ret.concat([n,"</div></div>"]);return ret.join("");},resize:function(){this.adaptHeight();this.adaptWidth();},hasHScrollbar:function(_37e){var _37f=this._hasHScroll||false;if(this._hasHScroll==undefined||_37e){if(this.noscroll){this._hasHScroll=false;}else{var _380=_4.style(this.scrollboxNode,"overflow");if(_380=="hidden"){this._hasHScroll=false;}else{if(_380=="scroll"){this._hasHScroll=true;}else{this._hasHScroll=(this.scrollboxNode.offsetWidth-this.getScrollbarWidth()<this.contentNode.offsetWidth);}}}}if(_37f!==this._hasHScroll){this.grid.update();}return this._hasHScroll;},hasVScrollbar:function(_381){var _382=this._hasVScroll||false;if(this._hasVScroll==undefined||_381){if(this.noscroll){this._hasVScroll=false;}else{var _383=_4.style(this.scrollboxNode,"overflow");if(_383=="hidden"){this._hasVScroll=false;}else{if(_383=="scroll"){this._hasVScroll=true;}else{this._hasVScroll=(this.scrollboxNode.scrollHeight>this.scrollboxNode.clientHeight);}}}}if(_382!==this._hasVScroll){this.grid.update();}return this._hasVScroll;},convertColPctToFixed:function(){var _384=false;this.grid.initialWidth="";var _385=_4.query("th",this.headerContentNode);var _386=_4.map(_385,function(c,vIdx){var w=c.style.width;_4.attr(c,"vIdx",vIdx);if(w&&w.slice(-1)=="%"){_384=true;}else{if(w&&w.slice(-2)=="px"){return window.parseInt(w,10);}}return _4.contentBox(c).w;});if(_384){_4.forEach(this.grid.layout.cells,function(cell,idx){if(cell.view==this){var _387=cell.view.getHeaderCellNode(cell.index);if(_387&&_4.hasAttr(_387,"vIdx")){var vIdx=window.parseInt(_4.attr(_387,"vIdx"));this.setColWidth(idx,_386[vIdx]);_4.removeAttr(_387,"vIdx");}}},this);return true;}return false;},adaptHeight:function(_388){if(!this.grid._autoHeight){var h=(this.domNode.style.height&&parseInt(this.domNode.style.height.replace(/px/,""),10))||this.domNode.clientHeight;var self=this;var _389=function(){var v;for(var i in self.grid.views.views){v=self.grid.views.views[i];if(v!==self&&v.hasHScrollbar()){return true;}}return false;};if(_388||(this.noscroll&&_389())){h-=_6.html.metrics.getScrollbar().h;}_6.grid.util.setStyleHeightPx(this.scrollboxNode,h);}this.hasVScrollbar(true);},adaptWidth:function(){if(this.flexCells){this.contentWidth=this.getContentWidth();this.headerContentNode.firstChild.style.width=this.contentWidth;}var w=this.scrollboxNode.offsetWidth-this.getScrollbarWidth();if(!this._removingColumn){w=Math.max(w,this.getColumnsWidth())+"px";}else{w=Math.min(w,this.getColumnsWidth())+"px";this._removingColumn=false;}var cn=this.contentNode;cn.style.width=w;this.hasHScrollbar(true);},setSize:function(w,h){var ds=this.domNode.style;var hs=this.headerNode.style;if(w){ds.width=w;hs.width=w;}ds.height=(h>=0?h+"px":"");},renderRow:function(_38a){var _38b=this.createRowNode(_38a);this.buildRow(_38a,_38b);this.grid.edit.restore(this,_38a);return _38b;},createRowNode:function(_38c){var node=document.createElement("div");node.className=this.classTag+"Row";if(this instanceof _6.grid._RowSelector){_4.attr(node,"role","presentation");}else{_4.attr(node,"role","row");if(this.grid.selectionMode!="none"){_4.attr(node,"aria-selected","false");}}node[_6.grid.util.gridViewTag]=this.id;node[_6.grid.util.rowIndexTag]=_38c;this.rowNodes[_38c]=node;return node;},buildRow:function(_38d,_38e){this.buildRowContent(_38d,_38e);this.styleRow(_38d,_38e);},buildRowContent:function(_38f,_390){_390.innerHTML=this.content.generateHtml(_38f,_38f);if(this.flexCells&&this.contentWidth){_390.firstChild.style.width=this.contentWidth;}_6.grid.util.fire(this,"onAfterRow",[_38f,this.structure.cells,_390]);},rowRemoved:function(_391){if(_391>=0){this._cleanupRowWidgets(this.getRowNode(_391));}this.grid.edit.save(this,_391);delete this.rowNodes[_391];},getRowNode:function(_392){return this.rowNodes[_392];},getCellNode:function(_393,_394){var row=this.getRowNode(_393);if(row){return this.content.getCellNode(row,_394);}},getHeaderCellNode:function(_395){if(this.headerContentNode){return this.header.getCellNode(this.headerContentNode,_395);}},styleRow:function(_396,_397){_397._style=_359(_397);this.styleRowNode(_396,_397);},styleRowNode:function(_398,_399){if(_399){this.doStyleRowNode(_398,_399);}},doStyleRowNode:function(_39a,_39b){this.grid.styleRowNode(_39a,_39b);},updateRow:function(_39c){var _39d=this.getRowNode(_39c);if(_39d){_39d.style.height="";this.buildRow(_39c,_39d);}return _39d;},updateRowStyles:function(_39e){this.styleRowNode(_39e,this.getRowNode(_39e));},lastTop:0,firstScroll:0,doscroll:function(_39f){var _3a0=_4._isBodyLtr();if(this.firstScroll<2){if((!_3a0&&this.firstScroll==1)||(_3a0&&this.firstScroll===0)){var s=_4.marginBox(this.headerNodeContainer);if(_4.isIE){this.headerNodeContainer.style.width=s.w+this.getScrollbarWidth()+"px";}else{if(_4.isMoz){this.headerNodeContainer.style.width=s.w-this.getScrollbarWidth()+"px";this.scrollboxNode.scrollLeft=_3a0?this.scrollboxNode.clientWidth-this.scrollboxNode.scrollWidth:this.scrollboxNode.scrollWidth-this.scrollboxNode.clientWidth;}}}this.firstScroll++;}this.headerNode.scrollLeft=this.scrollboxNode.scrollLeft;var top=this.scrollboxNode.scrollTop;if(top!==this.lastTop){this.grid.scrollTo(top);}},setScrollTop:function(_3a1){this.lastTop=_3a1;this.scrollboxNode.scrollTop=_3a1;return this.scrollboxNode.scrollTop;},doContentEvent:function(e){if(this.content.decorateEvent(e)){this.grid.onContentEvent(e);}},doHeaderEvent:function(e){if(this.header.decorateEvent(e)){this.grid.onHeaderEvent(e);}},dispatchContentEvent:function(e){return this.content.dispatchEvent(e);},dispatchHeaderEvent:function(e){return this.header.dispatchEvent(e);},setColWidth:function(_3a2,_3a3){this.grid.setCellWidth(_3a2,_3a3+"px");},update:function(){if(!this.domNode){return;}this.content.update();this.grid.update();var left=this.scrollboxNode.scrollLeft;this.scrollboxNode.scrollLeft=left;this.headerNode.scrollLeft=left;}});_4.declare("dojox.grid._GridAvatar",_4.dnd.Avatar,{construct:function(){var dd=_4.doc;var a=dd.createElement("table");a.cellPadding=a.cellSpacing="0";a.className="dojoxGridDndAvatar";a.style.position="absolute";a.style.zIndex=1999;a.style.margin="0px";var b=dd.createElement("tbody");var tr=dd.createElement("tr");var td=dd.createElement("td");var img=dd.createElement("td");tr.className="dojoxGridDndAvatarItem";img.className="dojoxGridDndAvatarItemImage";img.style.width="16px";var _3a4=this.manager.source,node;if(_3a4.creator){node=_3a4._normalizedCreator(_3a4.getItem(this.manager.nodes[0].id).data,"avatar").node;}else{node=this.manager.nodes[0].cloneNode(true);var _3a5,_3a6;if(node.tagName.toLowerCase()=="tr"){_3a5=dd.createElement("table");_3a6=dd.createElement("tbody");_3a6.appendChild(node);_3a5.appendChild(_3a6);node=_3a5;}else{if(node.tagName.toLowerCase()=="th"){_3a5=dd.createElement("table");_3a6=dd.createElement("tbody");var r=dd.createElement("tr");_3a5.cellPadding=_3a5.cellSpacing="0";r.appendChild(node);_3a6.appendChild(r);_3a5.appendChild(_3a6);node=_3a5;}}}node.id="";td.appendChild(node);tr.appendChild(img);tr.appendChild(td);_4.style(tr,"opacity",0.9);b.appendChild(tr);a.appendChild(b);this.node=a;var m=_4.dnd.manager();this.oldOffsetY=m.OFFSET_Y;m.OFFSET_Y=1;},destroy:function(){_4.dnd.manager().OFFSET_Y=this.oldOffsetY;this.inherited(arguments);}});var _3a7=_4.dnd.manager().makeAvatar;_4.dnd.manager().makeAvatar=function(){var src=this.source;if(src.viewIndex!==undefined&&!_4.hasClass(_4.body(),"dijit_a11y")){return new _6.grid._GridAvatar(this);}return _3a7.call(_4.dnd.manager());};})();}if(!_4._hasResource["dojox.grid._RowSelector"]){_4._hasResource["dojox.grid._RowSelector"]=true;_4.provide("dojox.grid._RowSelector");_4.declare("dojox.grid._RowSelector",_6.grid._View,{defaultWidth:"2em",noscroll:true,padBorderWidth:2,buildRendering:function(){this.inherited("buildRendering",arguments);this.scrollboxNode.style.overflow="hidden";this.headerNode.style.visibility="hidden";},getWidth:function(){return this.viewWidth||this.defaultWidth;},buildRowContent:function(_3a8,_3a9){var w=this.contentWidth||0;_3a9.innerHTML="<table class=\"dojoxGridRowbarTable\" style=\"width:"+w+"px;height:1px;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" role=\"presentation\"><tr><td class=\"dojoxGridRowbarInner\">&nbsp;</td></tr></table>";},renderHeader:function(){},updateRow:function(){},resize:function(){this.adaptHeight();},adaptWidth:function(){if(!("contentWidth" in this)&&this.contentNode){this.contentWidth=this.contentNode.offsetWidth-this.padBorderWidth;}},doStyleRowNode:function(_3aa,_3ab){var n=["dojoxGridRowbar dojoxGridNonNormalizedCell"];if(this.grid.rows.isOver(_3aa)){n.push("dojoxGridRowbarOver");}if(this.grid.selection.isSelected(_3aa)){n.push("dojoxGridRowbarSelected");}_3ab.className=n.join(" ");},domouseover:function(e){this.grid.onMouseOverRow(e);},domouseout:function(e){if(!this.isIntraRowEvent(e)){this.grid.onMouseOutRow(e);}}});}if(!_4._hasResource["dojox.grid._Layout"]){_4._hasResource["dojox.grid._Layout"]=true;_4.provide("dojox.grid._Layout");_4.declare("dojox.grid._Layout",null,{constructor:function(_3ac){this.grid=_3ac;},cells:[],structure:null,defaultWidth:"6em",moveColumn:function(_3ad,_3ae,_3af,_3b0,_3b1){var _3b2=this.structure[_3ad].cells[0];var _3b3=this.structure[_3ae].cells[0];var cell=null;var _3b4=0;var _3b5=0;for(var i=0,c;c=_3b2[i];i++){if(c.index==_3af){_3b4=i;break;}}cell=_3b2.splice(_3b4,1)[0];cell.view=this.grid.views.views[_3ae];for(i=0,c=null;c=_3b3[i];i++){if(c.index==_3b0){_3b5=i;break;}}if(!_3b1){_3b5+=1;}_3b3.splice(_3b5,0,cell);var _3b6=this.grid.getCell(this.grid.getSortIndex());if(_3b6){_3b6._currentlySorted=this.grid.getSortAsc();}this.cells=[];_3af=0;var v;for(i=0;v=this.structure[i];i++){for(var j=0,cs;cs=v.cells[j];j++){for(var k=0;c=cs[k];k++){c.index=_3af;this.cells.push(c);if("_currentlySorted" in c){var si=_3af+1;si*=c._currentlySorted?1:-1;this.grid.sortInfo=si;delete c._currentlySorted;}_3af++;}}}_4.forEach(this.cells,function(c){var _3b7=c.markup[2].split(" ");var _3b8=parseInt(_3b7[1].substring(5));if(_3b8!=c.index){_3b7[1]="idx=\""+c.index+"\"";c.markup[2]=_3b7.join(" ");}});this.grid.setupHeaderMenu();},setColumnVisibility:function(_3b9,_3ba){var cell=this.cells[_3b9];if(cell.hidden==_3ba){cell.hidden=!_3ba;var v=cell.view,w=v.viewWidth;if(w&&w!="auto"){v._togglingColumn=_4.marginBox(cell.getHeaderNode()).w||0;}v.update();return true;}else{return false;}},addCellDef:function(_3bb,_3bc,_3bd){var self=this;var _3be=function(_3bf){var w=0;if(_3bf.colSpan>1){w=0;}else{w=_3bf.width||self._defaultCellProps.width||self.defaultWidth;if(!isNaN(w)){w=w+"em";}}return w;};var _3c0={grid:this.grid,subrow:_3bb,layoutIndex:_3bc,index:this.cells.length};if(_3bd&&_3bd instanceof _6.grid.cells._Base){var _3c1=_4.clone(_3bd);_3c0.unitWidth=_3be(_3c1._props);_3c1=_4.mixin(_3c1,this._defaultCellProps,_3bd._props,_3c0);return _3c1;}var _3c2=_3bd.type||_3bd.cellType||this._defaultCellProps.type||this._defaultCellProps.cellType||_6.grid.cells.Cell;_3c0.unitWidth=_3be(_3bd);return new _3c2(_4.mixin({},this._defaultCellProps,_3bd,_3c0));},addRowDef:function(_3c3,_3c4){var _3c5=[];var _3c6=0,_3c7=0,_3c8=true;for(var i=0,def,cell;(def=_3c4[i]);i++){cell=this.addCellDef(_3c3,i,def);_3c5.push(cell);this.cells.push(cell);if(_3c8&&cell.relWidth){_3c6+=cell.relWidth;}else{if(cell.width){var w=cell.width;if(typeof w=="string"&&w.slice(-1)=="%"){_3c7+=window.parseInt(w,10);}else{if(w=="auto"){_3c8=false;}}}}}if(_3c6&&_3c8){_4.forEach(_3c5,function(cell){if(cell.relWidth){cell.width=cell.unitWidth=((cell.relWidth/_3c6)*(100-_3c7))+"%";}});}return _3c5;},addRowsDef:function(_3c9){var _3ca=[];if(_4.isArray(_3c9)){if(_4.isArray(_3c9[0])){for(var i=0,row;_3c9&&(row=_3c9[i]);i++){_3ca.push(this.addRowDef(i,row));}}else{_3ca.push(this.addRowDef(0,_3c9));}}return _3ca;},addViewDef:function(_3cb){this._defaultCellProps=_3cb.defaultCell||{};if(_3cb.width&&_3cb.width=="auto"){delete _3cb.width;}return _4.mixin({},_3cb,{cells:this.addRowsDef(_3cb.rows||_3cb.cells)});},setStructure:function(_3cc){this.fieldIndex=0;this.cells=[];var s=this.structure=[];if(this.grid.rowSelector){var sel={type:_6._scopeName+".grid._RowSelector"};if(_4.isString(this.grid.rowSelector)){var _3cd=this.grid.rowSelector;if(_3cd=="false"){sel=null;}else{if(_3cd!="true"){sel["width"]=_3cd;}}}else{if(!this.grid.rowSelector){sel=null;}}if(sel){s.push(this.addViewDef(sel));}}var _3ce=function(def){return ("name" in def||"field" in def||"get" in def);};var _3cf=function(def){if(_4.isArray(def)){if(_4.isArray(def[0])||_3ce(def[0])){return true;}}return false;};var _3d0=function(def){return (def!==null&&_4.isObject(def)&&("cells" in def||"rows" in def||("type" in def&&!_3ce(def))));};if(_4.isArray(_3cc)){var _3d1=false;for(var i=0,st;(st=_3cc[i]);i++){if(_3d0(st)){_3d1=true;break;}}if(!_3d1){s.push(this.addViewDef({cells:_3cc}));}else{for(i=0;(st=_3cc[i]);i++){if(_3cf(st)){s.push(this.addViewDef({cells:st}));}else{if(_3d0(st)){s.push(this.addViewDef(st));}}}}}else{if(_3d0(_3cc)){s.push(this.addViewDef(_3cc));}}this.cellCount=this.cells.length;this.grid.setupHeaderMenu();}});}if(!_4._hasResource["dojox.grid._ViewManager"]){_4._hasResource["dojox.grid._ViewManager"]=true;_4.provide("dojox.grid._ViewManager");_4.declare("dojox.grid._ViewManager",null,{constructor:function(_3d2){this.grid=_3d2;},defaultWidth:200,views:[],resize:function(){this.onEach("resize");},render:function(){this.onEach("render");},addView:function(_3d3){_3d3.idx=this.views.length;this.views.push(_3d3);},destroyViews:function(){for(var i=0,v;v=this.views[i];i++){v.destroy();}this.views=[];},getContentNodes:function(){var _3d4=[];for(var i=0,v;v=this.views[i];i++){_3d4.push(v.contentNode);}return _3d4;},forEach:function(_3d5){for(var i=0,v;v=this.views[i];i++){_3d5(v,i);}},onEach:function(_3d6,_3d7){_3d7=_3d7||[];for(var i=0,v;v=this.views[i];i++){if(_3d6 in v){v[_3d6].apply(v,_3d7);}}},normalizeHeaderNodeHeight:function(){var _3d8=[];for(var i=0,v;(v=this.views[i]);i++){if(v.headerContentNode.firstChild){_3d8.push(v.headerContentNode);}}this.normalizeRowNodeHeights(_3d8);},normalizeRowNodeHeights:function(_3d9){var h=0;var _3da=[];if(this.grid.rowHeight){h=this.grid.rowHeight;}else{if(_3d9.length<=1){return;}for(var i=0,n;(n=_3d9[i]);i++){if(!_4.hasClass(n,"dojoxGridNonNormalizedCell")){_3da[i]=n.firstChild.offsetHeight;h=Math.max(h,_3da[i]);}}h=(h>=0?h:0);if(_4.isMoz&&h){h++;}}for(i=0;(n=_3d9[i]);i++){if(_3da[i]!=h){n.firstChild.style.height=h+"px";}}},resetHeaderNodeHeight:function(){for(var i=0,v,n;(v=this.views[i]);i++){n=v.headerContentNode.firstChild;if(n){n.style.height="";}}},renormalizeRow:function(_3db){var _3dc=[];for(var i=0,v,n;(v=this.views[i])&&(n=v.getRowNode(_3db));i++){n.firstChild.style.height="";_3dc.push(n);}this.normalizeRowNodeHeights(_3dc);},getViewWidth:function(_3dd){return this.views[_3dd].getWidth()||this.defaultWidth;},measureHeader:function(){this.resetHeaderNodeHeight();this.forEach(function(_3de){_3de.headerContentNode.style.height="";});var h=0;this.forEach(function(_3df){h=Math.max(_3df.headerNode.offsetHeight,h);});return h;},measureContent:function(){var h=0;this.forEach(function(_3e0){h=Math.max(_3e0.domNode.offsetHeight,h);});return h;},findClient:function(_3e1){var c=this.grid.elasticView||-1;if(c<0){for(var i=1,v;(v=this.views[i]);i++){if(v.viewWidth){for(i=1;(v=this.views[i]);i++){if(!v.viewWidth){c=i;break;}}break;}}}if(c<0){c=Math.floor(this.views.length/2);}return c;},arrange:function(l,w){var i,v,vw,len=this.views.length;var c=(w<=0?len:this.findClient());var _3e2=function(v,l){var ds=v.domNode.style;var hs=v.headerNode.style;if(!_4._isBodyLtr()){ds.right=l+"px";if(_4.isMoz){hs.right=l+v.getScrollbarWidth()+"px";hs.width=parseInt(hs.width,10)-v.getScrollbarWidth()+"px";}else{hs.right=l+"px";}}else{ds.left=l+"px";hs.left=l+"px";}ds.top=0+"px";hs.top=0;};for(i=0;(v=this.views[i])&&(i<c);i++){vw=this.getViewWidth(i);v.setSize(vw,0);_3e2(v,l);if(v.headerContentNode&&v.headerContentNode.firstChild){vw=v.getColumnsWidth()+v.getScrollbarWidth();}else{vw=v.domNode.offsetWidth;}l+=vw;}i++;var r=w;for(var j=len-1;(v=this.views[j])&&(i<=j);j--){vw=this.getViewWidth(j);v.setSize(vw,0);vw=v.domNode.offsetWidth;r-=vw;_3e2(v,r);}if(c<len){v=this.views[c];vw=Math.max(1,r-l);v.setSize(vw+"px",0);_3e2(v,l);}return l;},renderRow:function(_3e3,_3e4,_3e5){var _3e6=[];for(var i=0,v,n,_3e7;(v=this.views[i])&&(n=_3e4[i]);i++){_3e7=v.renderRow(_3e3);n.appendChild(_3e7);_3e6.push(_3e7);}if(!_3e5){this.normalizeRowNodeHeights(_3e6);}},rowRemoved:function(_3e8){this.onEach("rowRemoved",[_3e8]);},updateRow:function(_3e9,_3ea){for(var i=0,v;v=this.views[i];i++){v.updateRow(_3e9);}if(!_3ea){this.renormalizeRow(_3e9);}},updateRowStyles:function(_3eb){this.onEach("updateRowStyles",[_3eb]);},setScrollTop:function(_3ec){var top=_3ec;for(var i=0,v;v=this.views[i];i++){top=v.setScrollTop(_3ec);if(_4.isIE&&v.headerNode&&v.scrollboxNode){v.headerNode.scrollLeft=v.scrollboxNode.scrollLeft;}}return top;},getFirstScrollingView:function(){for(var i=0,v;(v=this.views[i]);i++){if(v.hasHScrollbar()||v.hasVScrollbar()){return v;}}return null;}});}if(!_4._hasResource["dojox.grid._RowManager"]){_4._hasResource["dojox.grid._RowManager"]=true;_4.provide("dojox.grid._RowManager");(function(){var _3ed=function(_3ee,_3ef){if(_3ee.style.cssText==undefined){_3ee.setAttribute("style",_3ef);}else{_3ee.style.cssText=_3ef;}};_4.declare("dojox.grid._RowManager",null,{constructor:function(_3f0){this.grid=_3f0;},linesToEms:2,overRow:-2,prepareStylingRow:function(_3f1,_3f2){return {index:_3f1,node:_3f2,odd:Boolean(_3f1&1),selected:!!this.grid.selection.isSelected(_3f1),over:this.isOver(_3f1),customStyles:"",customClasses:"dojoxGridRow"};},styleRowNode:function(_3f3,_3f4){var row=this.prepareStylingRow(_3f3,_3f4);this.grid.onStyleRow(row);this.applyStyles(row);},applyStyles:function(_3f5){var i=_3f5;i.node.className=i.customClasses;var h=i.node.style.height;_3ed(i.node,i.customStyles+";"+(i.node._style||""));i.node.style.height=h;},updateStyles:function(_3f6){this.grid.updateRowStyles(_3f6);},setOverRow:function(_3f7){var last=this.overRow;this.overRow=_3f7;if((last!=this.overRow)&&(_4.isString(last)||last>=0)){this.updateStyles(last);}this.updateStyles(this.overRow);},isOver:function(_3f8){return (this.overRow==_3f8&&!_4.hasClass(this.grid.domNode,"dojoxGridColumnResizing"));}});})();}if(!_4._hasResource["dojox.grid._FocusManager"]){_4._hasResource["dojox.grid._FocusManager"]=true;_4.provide("dojox.grid._FocusManager");_4.declare("dojox.grid._FocusManager",null,{constructor:function(_3f9){this.grid=_3f9;this.cell=null;this.rowIndex=-1;this._connects=[];this._headerConnects=[];this.headerMenu=this.grid.headerMenu;this._connects.push(_4.connect(this.grid.domNode,"onfocus",this,"doFocus"));this._connects.push(_4.connect(this.grid.domNode,"onblur",this,"doBlur"));this._connects.push(_4.connect(this.grid.domNode,"oncontextmenu",this,"doContextMenu"));this._connects.push(_4.connect(this.grid.lastFocusNode,"onfocus",this,"doLastNodeFocus"));this._connects.push(_4.connect(this.grid.lastFocusNode,"onblur",this,"doLastNodeBlur"));this._connects.push(_4.connect(this.grid,"_onFetchComplete",this,"_delayedCellFocus"));this._connects.push(_4.connect(this.grid,"postrender",this,"_delayedHeaderFocus"));},destroy:function(){_4.forEach(this._connects,_4.disconnect);_4.forEach(this._headerConnects,_4.disconnect);delete this.grid;delete this.cell;},_colHeadNode:null,_colHeadFocusIdx:null,_contextMenuBindNode:null,tabbingOut:false,focusClass:"dojoxGridCellFocus",focusView:null,initFocusView:function(){this.focusView=this.grid.views.getFirstScrollingView()||this.focusView||this.grid.views.views[0];this._initColumnHeaders();},isFocusCell:function(_3fa,_3fb){return (this.cell==_3fa)&&(this.rowIndex==_3fb);},isLastFocusCell:function(){if(this.cell){return (this.rowIndex==this.grid.rowCount-1)&&(this.cell.index==this.grid.layout.cellCount-1);}return false;},isFirstFocusCell:function(){if(this.cell){return (this.rowIndex===0)&&(this.cell.index===0);}return false;},isNoFocusCell:function(){return (this.rowIndex<0)||!this.cell;},isNavHeader:function(){return (!!this._colHeadNode);},getHeaderIndex:function(){if(this._colHeadNode){return _4.indexOf(this._findHeaderCells(),this._colHeadNode);}else{return -1;}},_focusifyCellNode:function(_3fc){var n=this.cell&&this.cell.getNode(this.rowIndex);if(n){_4.toggleClass(n,this.focusClass,_3fc);if(_3fc){var sl=this.scrollIntoView();try{if(!this.grid.edit.isEditing()){_6.grid.util.fire(n,"focus");if(sl){this.cell.view.scrollboxNode.scrollLeft=sl;}}}catch(e){}}}},_delayedCellFocus:function(){if(this.isNavHeader()||!this.grid._focused){return;}var n=this.cell&&this.cell.getNode(this.rowIndex);if(n){try{if(!this.grid.edit.isEditing()){_4.toggleClass(n,this.focusClass,true);this.blurHeader();_6.grid.util.fire(n,"focus");}}catch(e){}}},_delayedHeaderFocus:function(){if(this.isNavHeader()){this.focusHeader();this.grid.domNode.focus();}},_initColumnHeaders:function(){_4.forEach(this._headerConnects,_4.disconnect);this._headerConnects=[];var _3fd=this._findHeaderCells();for(var i=0;i<_3fd.length;i++){this._headerConnects.push(_4.connect(_3fd[i],"onfocus",this,"doColHeaderFocus"));this._headerConnects.push(_4.connect(_3fd[i],"onblur",this,"doColHeaderBlur"));}},_findHeaderCells:function(){var _3fe=_4.query("th",this.grid.viewsHeaderNode);var _3ff=[];for(var i=0;i<_3fe.length;i++){var _400=_3fe[i];var _401=_4.hasAttr(_400,"tabIndex");var _402=_4.attr(_400,"tabIndex");if(_401&&_402<0){_3ff.push(_400);}}return _3ff;},_setActiveColHeader:function(_403,_404,_405){_4.attr(this.grid.domNode,"aria-activedescendant",_403.id);if(_405!=null&&_405>=0&&_405!=_404){_4.toggleClass(this._findHeaderCells()[_405],this.focusClass,false);}_4.toggleClass(_403,this.focusClass,true);this._colHeadNode=_403;this._colHeadFocusIdx=_404;this._scrollHeader(this._colHeadFocusIdx);},scrollIntoView:function(){var info=(this.cell?this._scrollInfo(this.cell):null);if(!info||!info.s){return null;}var rt=this.grid.scroller.findScrollTop(this.rowIndex);if(info.n&&info.sr){if(info.n.offsetLeft+info.n.offsetWidth>info.sr.l+info.sr.w){info.s.scrollLeft=info.n.offsetLeft+info.n.offsetWidth-info.sr.w;}else{if(info.n.offsetLeft<info.sr.l){info.s.scrollLeft=info.n.offsetLeft;}}}if(info.r&&info.sr){if(rt+info.r.offsetHeight>info.sr.t+info.sr.h){this.grid.setScrollTop(rt+info.r.offsetHeight-info.sr.h);}else{if(rt<info.sr.t){this.grid.setScrollTop(rt);}}}return info.s.scrollLeft;},_scrollInfo:function(cell,_406){if(cell){var cl=cell,sbn=cl.view.scrollboxNode,sbnr={w:sbn.clientWidth,l:sbn.scrollLeft,t:sbn.scrollTop,h:sbn.clientHeight},rn=cl.view.getRowNode(this.rowIndex);return {c:cl,s:sbn,sr:sbnr,n:(_406?_406:cell.getNode(this.rowIndex)),r:rn};}return null;},_scrollHeader:function(_407){var info=null;if(this._colHeadNode){var cell=this.grid.getCell(_407);info=this._scrollInfo(cell,cell.getNode(0));}if(info&&info.s&&info.sr&&info.n){var _408=info.sr.l+info.sr.w;if(info.n.offsetLeft+info.n.offsetWidth>_408){info.s.scrollLeft=info.n.offsetLeft+info.n.offsetWidth-info.sr.w;}else{if(info.n.offsetLeft<info.sr.l){info.s.scrollLeft=info.n.offsetLeft;}else{if(_4.isIE<=7&&cell&&cell.view.headerNode){cell.view.headerNode.scrollLeft=info.s.scrollLeft;}}}}},_isHeaderHidden:function(){var _409=this.focusView;if(!_409){for(var i=0,_40a;(_40a=this.grid.views.views[i]);i++){if(_40a.headerNode){_409=_40a;break;}}}return (_409&&_4.getComputedStyle(_409.headerNode).display=="none");},colSizeAdjust:function(e,_40b,_40c){var _40d=this._findHeaderCells();var view=this.focusView;if(!view){for(var i=0,_40e;(_40e=this.grid.views.views[i]);i++){if(_40e.header.tableMap.map){view=_40e;break;}}}var _40f=_40d[_40b];if(!view||(_40b==_40d.length-1&&_40b===0)){return;}view.content.baseDecorateEvent(e);e.cellNode=_40f;e.cellIndex=view.content.getCellNodeIndex(e.cellNode);e.cell=(e.cellIndex>=0?this.grid.getCell(e.cellIndex):null);if(view.header.canResize(e)){var _410={l:_40c};var drag=view.header.colResizeSetup(e,false);view.header.doResizeColumn(drag,null,_410);view.update();}},styleRow:function(_411){return;},setFocusIndex:function(_412,_413){this.setFocusCell(this.grid.getCell(_413),_412);},setFocusCell:function(_414,_415){if(_414&&!this.isFocusCell(_414,_415)){this.tabbingOut=false;if(this._colHeadNode){this.blurHeader();}this._colHeadNode=this._colHeadFocusIdx=null;this.focusGridView();this._focusifyCellNode(false);this.cell=_414;this.rowIndex=_415;this._focusifyCellNode(true);}if(_4.isOpera){setTimeout(_4.hitch(this.grid,"onCellFocus",this.cell,this.rowIndex),1);}else{this.grid.onCellFocus(this.cell,this.rowIndex);}},next:function(){if(this.cell){var row=this.rowIndex,col=this.cell.index+1,cc=this.grid.layout.cellCount-1,rc=this.grid.rowCount-1;if(col>cc){col=0;row++;}if(row>rc){col=cc;row=rc;}if(this.grid.edit.isEditing()){var _416=this.grid.getCell(col);if(!this.isLastFocusCell()&&(!_416.editable||this.grid.canEdit&&!this.grid.canEdit(_416,row))){this.cell=_416;this.rowIndex=row;this.next();return;}}this.setFocusIndex(row,col);}},previous:function(){if(this.cell){var row=(this.rowIndex||0),col=(this.cell.index||0)-1;if(col<0){col=this.grid.layout.cellCount-1;row--;}if(row<0){row=0;col=0;}if(this.grid.edit.isEditing()){var _417=this.grid.getCell(col);if(!this.isFirstFocusCell()&&!_417.editable){this.cell=_417;this.rowIndex=row;this.previous();return;}}this.setFocusIndex(row,col);}},move:function(_418,_419){var _41a=_419<0?-1:1;if(this.isNavHeader()){var _41b=this._findHeaderCells();var _41c=currentIdx=_4.indexOf(_41b,this._colHeadNode);currentIdx+=_419;while(currentIdx>=0&&currentIdx<_41b.length&&_41b[currentIdx].style.display=="none"){currentIdx+=_41a;}if((currentIdx>=0)&&(currentIdx<_41b.length)){this._setActiveColHeader(_41b[currentIdx],currentIdx,_41c);}}else{if(this.cell){var sc=this.grid.scroller,r=this.rowIndex,rc=this.grid.rowCount-1,row=Math.min(rc,Math.max(0,r+_418));if(_418){if(_418>0){if(row>sc.getLastPageRow(sc.page)){this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r));}}else{if(_418<0){if(row<=sc.getPageRow(sc.page)){this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row));}}}}var cc=this.grid.layout.cellCount-1,i=this.cell.index,col=Math.min(cc,Math.max(0,i+_419));var cell=this.grid.getCell(col);while(col>=0&&col<cc&&cell&&cell.hidden===true){col+=_41a;cell=this.grid.getCell(col);}if(!cell||cell.hidden===true){col=i;}this.setFocusIndex(row,col);if(_418){this.grid.updateRow(r);}}}},previousKey:function(e){if(this.grid.edit.isEditing()){_4.stopEvent(e);this.previous();}else{if(!this.isNavHeader()&&!this._isHeaderHidden()){this.grid.domNode.focus();_4.stopEvent(e);}else{this.tabOut(this.grid.domNode);if(this._colHeadFocusIdx!=null){_4.toggleClass(this._findHeaderCells()[this._colHeadFocusIdx],this.focusClass,false);this._colHeadFocusIdx=null;}this._focusifyCellNode(false);}}},nextKey:function(e){var _41d=(this.grid.rowCount===0);if(e.target===this.grid.domNode&&this._colHeadFocusIdx==null){this.focusHeader();_4.stopEvent(e);}else{if(this.isNavHeader()){this.blurHeader();if(!this.findAndFocusGridCell()){this.tabOut(this.grid.lastFocusNode);}this._colHeadNode=this._colHeadFocusIdx=null;}else{if(this.grid.edit.isEditing()){_4.stopEvent(e);this.next();}else{this.tabOut(this.grid.lastFocusNode);}}}},tabOut:function(_41e){this.tabbingOut=true;_41e.focus();},focusGridView:function(){_6.grid.util.fire(this.focusView,"focus");},focusGrid:function(_41f){this.focusGridView();this._focusifyCellNode(true);},findAndFocusGridCell:function(){var _420=true;var _421=(this.grid.rowCount===0);if(this.isNoFocusCell()&&!_421){var _422=0;var cell=this.grid.getCell(_422);if(cell.hidden){_422=this.isNavHeader()?this._colHeadFocusIdx:0;}this.setFocusIndex(0,_422);}else{if(this.cell&&!_421){if(this.focusView&&!this.focusView.rowNodes[this.rowIndex]){this.grid.scrollToRow(this.rowIndex);}this.focusGrid();}else{_420=false;}}this._colHeadNode=this._colHeadFocusIdx=null;return _420;},focusHeader:function(){var _423=this._findHeaderCells();var _424=this._colHeadFocusIdx;if(this._isHeaderHidden()){this.findAndFocusGridCell();}else{if(!this._colHeadFocusIdx){if(this.isNoFocusCell()){this._colHeadFocusIdx=0;}else{this._colHeadFocusIdx=this.cell.index;}}}this._colHeadNode=_423[this._colHeadFocusIdx];while(this._colHeadNode&&this._colHeadFocusIdx>=0&&this._colHeadFocusIdx<_423.length&&this._colHeadNode.style.display=="none"){this._colHeadFocusIdx++;this._colHeadNode=_423[this._colHeadFocusIdx];}if(this._colHeadNode&&this._colHeadNode.style.display!="none"){if(this.headerMenu&&this._contextMenuBindNode!=this.grid.domNode){this.headerMenu.unBindDomNode(this.grid.viewsHeaderNode);this.headerMenu.bindDomNode(this.grid.domNode);this._contextMenuBindNode=this.grid.domNode;}this._setActiveColHeader(this._colHeadNode,this._colHeadFocusIdx,_424);this._scrollHeader(this._colHeadFocusIdx);this._focusifyCellNode(false);}else{this.findAndFocusGridCell();}},blurHeader:function(){_4.removeClass(this._colHeadNode,this.focusClass);_4.removeAttr(this.grid.domNode,"aria-activedescendant");if(this.headerMenu&&this._contextMenuBindNode==this.grid.domNode){var _425=this.grid.viewsHeaderNode;this.headerMenu.unBindDomNode(this.grid.domNode);this.headerMenu.bindDomNode(_425);this._contextMenuBindNode=_425;}},doFocus:function(e){if(e&&e.target!=e.currentTarget){_4.stopEvent(e);return;}if(!this.tabbingOut){this.focusHeader();}this.tabbingOut=false;_4.stopEvent(e);},doBlur:function(e){_4.stopEvent(e);},doContextMenu:function(e){if(!this.headerMenu){_4.stopEvent(e);}},doLastNodeFocus:function(e){if(this.tabbingOut){this._focusifyCellNode(false);}else{if(this.grid.rowCount>0){if(this.isNoFocusCell()){this.setFocusIndex(0,0);}this._focusifyCellNode(true);}else{this.focusHeader();}}this.tabbingOut=false;_4.stopEvent(e);},doLastNodeBlur:function(e){_4.stopEvent(e);},doColHeaderFocus:function(e){this._setActiveColHeader(e.target,_4.attr(e.target,"idx"),this._colHeadFocusIdx);this._scrollHeader(this.getHeaderIndex());_4.stopEvent(e);},doColHeaderBlur:function(e){_4.toggleClass(e.target,this.focusClass,false);}});}if(!_4._hasResource["dojox.grid._EditManager"]){_4._hasResource["dojox.grid._EditManager"]=true;_4.provide("dojox.grid._EditManager");_4.declare("dojox.grid._EditManager",null,{constructor:function(_426){this.grid=_426;if(_4.isIE){this.connections=[_4.connect(document.body,"onfocus",_4.hitch(this,"_boomerangFocus"))];}else{this.connections=[_4.connect(this.grid,"onBlur",this,"apply")];}},info:{},destroy:function(){_4.forEach(this.connections,_4.disconnect);},cellFocus:function(_427,_428){if(this.grid.singleClickEdit||this.isEditRow(_428)){this.setEditCell(_427,_428);}else{this.apply();}if(this.isEditing()||(_427&&_427.editable&&_427.alwaysEditing)){this._focusEditor(_427,_428);}},rowClick:function(e){if(this.isEditing()&&!this.isEditRow(e.rowIndex)){this.apply();}},styleRow:function(_429){if(_429.index==this.info.rowIndex){_429.customClasses+=" dojoxGridRowEditing";}},dispatchEvent:function(e){var c=e.cell,ed=(c&&c["editable"])?c:0;return ed&&ed.dispatchEvent(e.dispatch,e);},isEditing:function(){return this.info.rowIndex!==undefined;},isEditCell:function(_42a,_42b){return (this.info.rowIndex===_42a)&&(this.info.cell.index==_42b);},isEditRow:function(_42c){return this.info.rowIndex===_42c;},setEditCell:function(_42d,_42e){if(!this.isEditCell(_42e,_42d.index)&&this.grid.canEdit&&this.grid.canEdit(_42d,_42e)){this.start(_42d,_42e,this.isEditRow(_42e)||_42d.editable);}},_focusEditor:function(_42f,_430){_6.grid.util.fire(_42f,"focus",[_430]);},focusEditor:function(){if(this.isEditing()){this._focusEditor(this.info.cell,this.info.rowIndex);}},_boomerangWindow:500,_shouldCatchBoomerang:function(){return this._catchBoomerang>new Date().getTime();},_boomerangFocus:function(){if(this._shouldCatchBoomerang()){this.grid.focus.focusGrid();this.focusEditor();this._catchBoomerang=0;}},_doCatchBoomerang:function(){if(_4.isIE){this._catchBoomerang=new Date().getTime()+this._boomerangWindow;}},start:function(_431,_432,_433){this.grid.beginUpdate();this.editorApply();if(this.isEditing()&&!this.isEditRow(_432)){this.applyRowEdit();this.grid.updateRow(_432);}if(_433){this.info={cell:_431,rowIndex:_432};this.grid.doStartEdit(_431,_432);this.grid.updateRow(_432);}else{this.info={};}this.grid.endUpdate();this.grid.focus.focusGrid();this._focusEditor(_431,_432);this._doCatchBoomerang();},_editorDo:function(_434){var c=this.info.cell;if(c&&c.editable){c[_434](this.info.rowIndex);}},editorApply:function(){this._editorDo("apply");},editorCancel:function(){this._editorDo("cancel");},applyCellEdit:function(_435,_436,_437){if(this.grid.canEdit(_436,_437)){this.grid.doApplyCellEdit(_435,_437,_436.field);}},applyRowEdit:function(){this.grid.doApplyEdit(this.info.rowIndex,this.info.cell.field);},apply:function(){if(this.isEditing()){this.grid.beginUpdate();this.editorApply();this.applyRowEdit();this.info={};this.grid.endUpdate();this.grid.focus.focusGrid();this._doCatchBoomerang();}},cancel:function(){if(this.isEditing()){this.grid.beginUpdate();this.editorCancel();this.info={};this.grid.endUpdate();this.grid.focus.focusGrid();this._doCatchBoomerang();}},save:function(_438,_439){var c=this.info.cell;if(this.isEditRow(_438)&&(!_439||c.view==_439)&&c.editable){c.save(c,this.info.rowIndex);}},restore:function(_43a,_43b){var c=this.info.cell;if(this.isEditRow(_43b)&&c.view==_43a&&c.editable){c.restore(c,this.info.rowIndex);}}});}if(!_4._hasResource["dojox.grid.Selection"]){_4._hasResource["dojox.grid.Selection"]=true;_4.provide("dojox.grid.Selection");_4.declare("dojox.grid.Selection",null,{constructor:function(_43c){this.grid=_43c;this.selected=[];this.setMode(_43c.selectionMode);},mode:"extended",selected:null,updating:0,selectedIndex:-1,setMode:function(mode){if(this.selected.length){this.deselectAll();}if(mode!="extended"&&mode!="multiple"&&mode!="single"&&mode!="none"){this.mode="extended";}else{this.mode=mode;}},onCanSelect:function(_43d){return this.grid.onCanSelect(_43d);},onCanDeselect:function(_43e){return this.grid.onCanDeselect(_43e);},onSelected:function(_43f){},onDeselected:function(_440){},onChanging:function(){},onChanged:function(){},isSelected:function(_441){if(this.mode=="none"){return false;}return this.selected[_441];},getFirstSelected:function(){if(!this.selected.length||this.mode=="none"){return -1;}for(var i=0,l=this.selected.length;i<l;i++){if(this.selected[i]){return i;}}return -1;},getNextSelected:function(_442){if(this.mode=="none"){return -1;}for(var i=_442+1,l=this.selected.length;i<l;i++){if(this.selected[i]){return i;}}return -1;},getSelected:function(){var _443=[];for(var i=0,l=this.selected.length;i<l;i++){if(this.selected[i]){_443.push(i);}}return _443;},getSelectedCount:function(){var c=0;for(var i=0;i<this.selected.length;i++){if(this.selected[i]){c++;}}return c;},_beginUpdate:function(){if(this.updating===0){this.onChanging();}this.updating++;},_endUpdate:function(){this.updating--;if(this.updating===0){this.onChanged();}},select:function(_444){if(this.mode=="none"){return;}if(this.mode!="multiple"){this.deselectAll(_444);this.addToSelection(_444);}else{this.toggleSelect(_444);}},addToSelection:function(_445){if(this.mode=="none"){return;}if(_4.isArray(_445)){_4.forEach(_445,this.addToSelection,this);return;}_445=Number(_445);if(this.selected[_445]){this.selectedIndex=_445;}else{if(this.onCanSelect(_445)!==false){this.selectedIndex=_445;var _446=this.grid.getRowNode(_445);if(_446){_4.attr(_446,"aria-selected","true");}this._beginUpdate();this.selected[_445]=true;this.onSelected(_445);this._endUpdate();}}},deselect:function(_447){if(this.mode=="none"){return;}if(_4.isArray(_447)){_4.forEach(_447,this.deselect,this);return;}_447=Number(_447);if(this.selectedIndex==_447){this.selectedIndex=-1;}if(this.selected[_447]){if(this.onCanDeselect(_447)===false){return;}var _448=this.grid.getRowNode(_447);if(_448){_4.attr(_448,"aria-selected","false");}this._beginUpdate();delete this.selected[_447];this.onDeselected(_447);this._endUpdate();}},setSelected:function(_449,_44a){this[(_44a?"addToSelection":"deselect")](_449);},toggleSelect:function(_44b){if(_4.isArray(_44b)){_4.forEach(_44b,this.toggleSelect,this);return;}this.setSelected(_44b,!this.selected[_44b]);},_range:function(_44c,inTo,func){var s=(_44c>=0?_44c:inTo),e=inTo;if(s>e){e=s;s=inTo;}for(var i=s;i<=e;i++){func(i);}},selectRange:function(_44d,inTo){this._range(_44d,inTo,_4.hitch(this,"addToSelection"));},deselectRange:function(_44e,inTo){this._range(_44e,inTo,_4.hitch(this,"deselect"));},insert:function(_44f){this.selected.splice(_44f,0,false);if(this.selectedIndex>=_44f){this.selectedIndex++;}},remove:function(_450){this.selected.splice(_450,1);if(this.selectedIndex>=_450){this.selectedIndex--;}},deselectAll:function(_451){for(var i in this.selected){if((i!=_451)&&(this.selected[i]===true)){this.deselect(i);}}},clickSelect:function(_452,_453,_454){if(this.mode=="none"){return;}this._beginUpdate();if(this.mode!="extended"){this.select(_452);}else{var _455=this.selectedIndex;if(!_453){this.deselectAll(_452);}if(_454){this.selectRange(_455,_452);}else{if(_453){this.toggleSelect(_452);}else{this.addToSelection(_452);}}}this._endUpdate();},clickSelectEvent:function(e){this.clickSelect(e.rowIndex,_4.isCopyKey(e),e.shiftKey);},clear:function(){this._beginUpdate();this.deselectAll();this._endUpdate();}});}if(!_4._hasResource["dojox.grid._Events"]){_4._hasResource["dojox.grid._Events"]=true;_4.provide("dojox.grid._Events");_4.declare("dojox.grid._Events",null,{cellOverClass:"dojoxGridCellOver",onKeyEvent:function(e){this.dispatchKeyEvent(e);},onContentEvent:function(e){this.dispatchContentEvent(e);},onHeaderEvent:function(e){this.dispatchHeaderEvent(e);},onStyleRow:function(_456){var i=_456;i.customClasses+=(i.odd?" dojoxGridRowOdd":"")+(i.selected?" dojoxGridRowSelected":"")+(i.over?" dojoxGridRowOver":"");this.focus.styleRow(_456);this.edit.styleRow(_456);},onKeyDown:function(e){if(e.altKey||e.metaKey){return;}var dk=_4.keys;var _457;switch(e.keyCode){case dk.ESCAPE:this.edit.cancel();break;case dk.ENTER:if(!this.edit.isEditing()){_457=this.focus.getHeaderIndex();if(_457>=0){this.setSortIndex(_457);break;}else{this.selection.clickSelect(this.focus.rowIndex,_4.isCopyKey(e),e.shiftKey);}_4.stopEvent(e);}if(!e.shiftKey){var _458=this.edit.isEditing();this.edit.apply();if(!_458){this.edit.setEditCell(this.focus.cell,this.focus.rowIndex);}}if(!this.edit.isEditing()){var _459=this.focus.focusView||this.views.views[0];_459.content.decorateEvent(e);this.onRowClick(e);}break;case dk.SPACE:if(!this.edit.isEditing()){_457=this.focus.getHeaderIndex();if(_457>=0){this.setSortIndex(_457);break;}else{this.selection.clickSelect(this.focus.rowIndex,_4.isCopyKey(e),e.shiftKey);}_4.stopEvent(e);}break;case dk.TAB:this.focus[e.shiftKey?"previousKey":"nextKey"](e);break;case dk.LEFT_ARROW:case dk.RIGHT_ARROW:if(!this.edit.isEditing()){var _45a=e.keyCode;_4.stopEvent(e);_457=this.focus.getHeaderIndex();if(_457>=0&&(e.shiftKey&&e.ctrlKey)){this.focus.colSizeAdjust(e,_457,(_45a==dk.LEFT_ARROW?-1:1)*5);}else{var _45b=(_45a==dk.LEFT_ARROW)?1:-1;if(_4._isBodyLtr()){_45b*=-1;}this.focus.move(0,_45b);}}break;case dk.UP_ARROW:if(!this.edit.isEditing()&&this.focus.rowIndex!==0){_4.stopEvent(e);this.focus.move(-1,0);}break;case dk.DOWN_ARROW:if(!this.edit.isEditing()&&this.focus.rowIndex+1!=this.rowCount){_4.stopEvent(e);this.focus.move(1,0);}break;case dk.PAGE_UP:if(!this.edit.isEditing()&&this.focus.rowIndex!==0){_4.stopEvent(e);if(this.focus.rowIndex!=this.scroller.firstVisibleRow+1){this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex,0);}else{this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1));this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1,0);}}break;case dk.PAGE_DOWN:if(!this.edit.isEditing()&&this.focus.rowIndex+1!=this.rowCount){_4.stopEvent(e);if(this.focus.rowIndex!=this.scroller.lastVisibleRow-1){this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1,0);}else{this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1));this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1,0);}}break;default:break;}},onMouseOver:function(e){e.rowIndex==-1?this.onHeaderCellMouseOver(e):this.onCellMouseOver(e);},onMouseOut:function(e){e.rowIndex==-1?this.onHeaderCellMouseOut(e):this.onCellMouseOut(e);},onMouseDown:function(e){e.rowIndex==-1?this.onHeaderCellMouseDown(e):this.onCellMouseDown(e);},onMouseOverRow:function(e){if(!this.rows.isOver(e.rowIndex)){this.rows.setOverRow(e.rowIndex);e.rowIndex==-1?this.onHeaderMouseOver(e):this.onRowMouseOver(e);}},onMouseOutRow:function(e){if(this.rows.isOver(-1)){this.onHeaderMouseOut(e);}else{if(!this.rows.isOver(-2)){this.rows.setOverRow(-2);this.onRowMouseOut(e);}}},onMouseDownRow:function(e){if(e.rowIndex!=-1){this.onRowMouseDown(e);}},onCellMouseOver:function(e){if(e.cellNode){_4.addClass(e.cellNode,this.cellOverClass);}},onCellMouseOut:function(e){if(e.cellNode){_4.removeClass(e.cellNode,this.cellOverClass);}},onCellMouseDown:function(e){},onCellClick:function(e){this._click[0]=this._click[1];this._click[1]=e;if(!this.edit.isEditCell(e.rowIndex,e.cellIndex)){this.focus.setFocusCell(e.cell,e.rowIndex);}this.onRowClick(e);},onCellDblClick:function(e){if(this._click.length>1&&_4.isIE){this.edit.setEditCell(this._click[1].cell,this._click[1].rowIndex);}else{if(this._click.length>1&&this._click[0].rowIndex!=this._click[1].rowIndex){this.edit.setEditCell(this._click[0].cell,this._click[0].rowIndex);}else{this.edit.setEditCell(e.cell,e.rowIndex);}}this.onRowDblClick(e);},onCellContextMenu:function(e){this.onRowContextMenu(e);},onCellFocus:function(_45c,_45d){this.edit.cellFocus(_45c,_45d);},onRowClick:function(e){this.edit.rowClick(e);this.selection.clickSelectEvent(e);},onRowDblClick:function(e){},onRowMouseOver:function(e){},onRowMouseOut:function(e){},onRowMouseDown:function(e){},onRowContextMenu:function(e){_4.stopEvent(e);},onHeaderMouseOver:function(e){},onHeaderMouseOut:function(e){},onHeaderCellMouseOver:function(e){if(e.cellNode){_4.addClass(e.cellNode,this.cellOverClass);}},onHeaderCellMouseOut:function(e){if(e.cellNode){_4.removeClass(e.cellNode,this.cellOverClass);}},onHeaderCellMouseDown:function(e){},onHeaderClick:function(e){},onHeaderCellClick:function(e){this.setSortIndex(e.cell.index);this.onHeaderClick(e);},onHeaderDblClick:function(e){},onHeaderCellDblClick:function(e){this.onHeaderDblClick(e);},onHeaderCellContextMenu:function(e){this.onHeaderContextMenu(e);},onHeaderContextMenu:function(e){if(!this.headerMenu){_4.stopEvent(e);}},onStartEdit:function(_45e,_45f){},onApplyCellEdit:function(_460,_461,_462){},onCancelEdit:function(_463){},onApplyEdit:function(_464){},onCanSelect:function(_465){return true;},onCanDeselect:function(_466){return true;},onSelected:function(_467){this.updateRowStyles(_467);},onDeselected:function(_468){this.updateRowStyles(_468);},onSelectionChanged:function(){}});}if(!_4._hasResource["dojox.grid._Grid"]){_4._hasResource["dojox.grid._Grid"]=true;_4.provide("dojox.grid._Grid");(function(){if(!_4.isCopyKey){_4.isCopyKey=_4.dnd.getCopyKeyState;}_4.declare("dojox.grid._Grid",[_5._Widget,_5._Templated,_6.grid._Events],{templateString:"<div hidefocus=\"hidefocus\" role=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\r\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" role=\"presentation\"></div>\r\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" role=\"presentation\"></div>\r\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\r\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\r\n</div>\r\n",classTag:"dojoxGrid",rowCount:5,keepRows:75,rowsPerPage:25,autoWidth:false,initialWidth:"",autoHeight:"",rowHeight:0,autoRender:true,defaultHeight:"15em",height:"",structure:null,elasticView:-1,singleClickEdit:false,selectionMode:"extended",rowSelector:"",columnReordering:false,headerMenu:null,placeholderLabel:"GridColumns",selectable:false,_click:null,loadingMessage:"<span class='dojoxGridLoading'>${loadingState}</span>",errorMessage:"<span class='dojoxGridError'>${errorState}</span>",noDataMessage:"",escapeHTMLInData:true,formatterScope:null,editable:false,sortInfo:0,themeable:true,_placeholders:null,_layoutClass:_6.grid._Layout,buildRendering:function(){this.inherited(arguments);if(!this.domNode.getAttribute("tabIndex")){this.domNode.tabIndex="0";}this.createScroller();this.createLayout();this.createViews();this.createManagers();this.createSelection();this.connect(this.selection,"onSelected","onSelected");this.connect(this.selection,"onDeselected","onDeselected");this.connect(this.selection,"onChanged","onSelectionChanged");_6.html.metrics.initOnFontResize();this.connect(_6.html.metrics,"onFontResize","textSizeChanged");_6.grid.util.funnelEvents(this.domNode,this,"doKeyEvent",_6.grid.util.keyEvents);if(this.selectionMode!="none"){_4.attr(this.domNode,"aria-multiselectable",this.selectionMode=="single"?"false":"true");}_4.addClass(this.domNode,this.classTag);if(!this.isLeftToRight()){_4.addClass(this.domNode,this.classTag+"Rtl");}},postMixInProperties:function(){this.inherited(arguments);var _469=_4.i18n.getLocalization("dijit","loading",this.lang);this.loadingMessage=_4.string.substitute(this.loadingMessage,_469);this.errorMessage=_4.string.substitute(this.errorMessage,_469);if(this.srcNodeRef&&this.srcNodeRef.style.height){this.height=this.srcNodeRef.style.height;}this._setAutoHeightAttr(this.autoHeight,true);this.lastScrollTop=this.scrollTop=0;},postCreate:function(){this._placeholders=[];this._setHeaderMenuAttr(this.headerMenu);this._setStructureAttr(this.structure);this._click=[];this.inherited(arguments);if(this.domNode&&this.autoWidth&&this.initialWidth){this.domNode.style.width=this.initialWidth;}if(this.domNode&&!this.editable){_4.attr(this.domNode,"aria-readonly","true");}},destroy:function(){this.domNode.onReveal=null;this.domNode.onSizeChange=null;delete this._click;this.edit.destroy();delete this.edit;this.views.destroyViews();if(this.scroller){this.scroller.destroy();delete this.scroller;}if(this.focus){this.focus.destroy();delete this.focus;}if(this.headerMenu&&this._placeholders.length){_4.forEach(this._placeholders,function(p){p.unReplace(true);});this.headerMenu.unBindDomNode(this.viewsHeaderNode);}this.inherited(arguments);},_setAutoHeightAttr:function(ah,_46a){if(typeof ah=="string"){if(!ah||ah=="false"){ah=false;}else{if(ah=="true"){ah=true;}else{ah=window.parseInt(ah,10);}}}if(typeof ah=="number"){if(isNaN(ah)){ah=false;}if(ah<0){ah=true;}else{if(ah===0){ah=false;}}}this.autoHeight=ah;if(typeof ah=="boolean"){this._autoHeight=ah;}else{if(typeof ah=="number"){this._autoHeight=(ah>=this.get("rowCount"));}else{this._autoHeight=false;}}if(this._started&&!_46a){this.render();}},_getRowCountAttr:function(){return this.updating&&this.invalidated&&this.invalidated.rowCount!=undefined?this.invalidated.rowCount:this.rowCount;},textSizeChanged:function(){this.render();},sizeChange:function(){this.update();},createManagers:function(){this.rows=new _6.grid._RowManager(this);this.focus=new _6.grid._FocusManager(this);this.edit=new _6.grid._EditManager(this);},createSelection:function(){this.selection=new _6.grid.Selection(this);},createScroller:function(){this.scroller=new _6.grid._Scroller();this.scroller.grid=this;this.scroller.renderRow=_4.hitch(this,"renderRow");this.scroller.removeRow=_4.hitch(this,"rowRemoved");},createLayout:function(){this.layout=new this._layoutClass(this);this.connect(this.layout,"moveColumn","onMoveColumn");},onMoveColumn:function(){this.render();},onResizeColumn:function(_46b){},createViews:function(){this.views=new _6.grid._ViewManager(this);this.views.createView=_4.hitch(this,"createView");},createView:function(_46c,idx){var c=_4.getObject(_46c);var view=new c({grid:this,index:idx});this.viewsNode.appendChild(view.domNode);this.viewsHeaderNode.appendChild(view.headerNode);this.views.addView(view);_4.attr(this.domNode,"align",_4._isBodyLtr()?"left":"right");return view;},buildViews:function(){for(var i=0,vs;(vs=this.layout.structure[i]);i++){this.createView(vs.type||_6._scopeName+".grid._View",i).setStructure(vs);}this.scroller.setContentNodes(this.views.getContentNodes());},_setStructureAttr:function(_46d){var s=_46d;if(s&&_4.isString(s)){_4.deprecated("dojox.grid._Grid.set('structure', 'objVar')","use dojox.grid._Grid.set('structure', objVar) instead","2.0");s=_4.getObject(s);}this.structure=s;if(!s){if(this.layout.structure){s=this.layout.structure;}else{return;}}this.views.destroyViews();if(s!==this.layout.structure){this.layout.setStructure(s);}this._structureChanged();},setStructure:function(_46e){_4.deprecated("dojox.grid._Grid.setStructure(obj)","use dojox.grid._Grid.set('structure', obj) instead.","2.0");this._setStructureAttr(_46e);},getColumnTogglingItems:function(){return _4.map(this.layout.cells,function(cell){if(!cell.menuItems){cell.menuItems=[];}var self=this;var item=new _5.CheckedMenuItem({label:cell.name,checked:!cell.hidden,_gridCell:cell,onChange:function(_46f){if(self.layout.setColumnVisibility(this._gridCell.index,_46f)){var _470=this._gridCell.menuItems;if(_470.length>1){_4.forEach(_470,function(item){if(item!==this){item.setAttribute("checked",_46f);}},this);}_46f=_4.filter(self.layout.cells,function(c){if(c.menuItems.length>1){_4.forEach(c.menuItems,"item.set('disabled', false);");}else{c.menuItems[0].set("disabled",false);}return !c.hidden;});if(_46f.length==1){_4.forEach(_46f[0].menuItems,"item.set('disabled', true);");}}},destroy:function(){var _471=_4.indexOf(this._gridCell.menuItems,this);this._gridCell.menuItems.splice(_471,1);delete this._gridCell;_5.CheckedMenuItem.prototype.destroy.apply(this,arguments);}});cell.menuItems.push(item);return item;},this);},_setHeaderMenuAttr:function(menu){if(this._placeholders&&this._placeholders.length){_4.forEach(this._placeholders,function(p){p.unReplace(true);});this._placeholders=[];}if(this.headerMenu){this.headerMenu.unBindDomNode(this.viewsHeaderNode);}this.headerMenu=menu;if(!menu){return;}this.headerMenu.bindDomNode(this.viewsHeaderNode);if(this.headerMenu.getPlaceholders){this._placeholders=this.headerMenu.getPlaceholders(this.placeholderLabel);}},setHeaderMenu:function(menu){_4.deprecated("dojox.grid._Grid.setHeaderMenu(obj)","use dojox.grid._Grid.set('headerMenu', obj) instead.","2.0");this._setHeaderMenuAttr(menu);},setupHeaderMenu:function(){if(this._placeholders&&this._placeholders.length){_4.forEach(this._placeholders,function(p){if(p._replaced){p.unReplace(true);}p.replace(this.getColumnTogglingItems());},this);}},_fetch:function(_472){this.setScrollTop(0);},getItem:function(_473){return null;},showMessage:function(_474){if(_474){this.messagesNode.innerHTML=_474;this.messagesNode.style.display="";}else{this.messagesNode.innerHTML="";this.messagesNode.style.display="none";}},_structureChanged:function(){this.buildViews();if(this.autoRender&&this._started){this.render();}},hasLayout:function(){return this.layout.cells.length;},resize:function(_475,_476){this._pendingChangeSize=_475;this._pendingResultSize=_476;this.sizeChange();},_getPadBorder:function(){this._padBorder=this._padBorder||_4._getPadBorderExtents(this.domNode);return this._padBorder;},_getHeaderHeight:function(){var vns=this.viewsHeaderNode.style,t=vns.display=="none"?0:this.views.measureHeader();vns.height=t+"px";this.views.normalizeHeaderNodeHeight();return t;},_resize:function(_477,_478){_477=_477||this._pendingChangeSize;_478=_478||this._pendingResultSize;delete this._pendingChangeSize;delete this._pendingResultSize;if(!this.domNode){return;}var pn=this.domNode.parentNode;if(!pn||pn.nodeType!=1||!this.hasLayout()||pn.style.visibility=="hidden"||pn.style.display=="none"){return;}var _479=this._getPadBorder();var hh=undefined;var h;if(this._autoHeight){this.domNode.style.height="auto";}else{if(typeof this.autoHeight=="number"){h=hh=this._getHeaderHeight();h+=(this.scroller.averageRowHeight*this.autoHeight);this.domNode.style.height=h+"px";}else{if(this.domNode.clientHeight<=_479.h){if(pn==document.body){this.domNode.style.height=this.defaultHeight;}else{if(this.height){this.domNode.style.height=this.height;}else{this.fitTo="parent";}}}}}if(_478){_477=_478;}if(_477){_4.marginBox(this.domNode,_477);this.height=this.domNode.style.height;delete this.fitTo;}else{if(this.fitTo=="parent"){h=this._parentContentBoxHeight=this._parentContentBoxHeight||_4._getContentBox(pn).h;this.domNode.style.height=Math.max(0,h)+"px";}}var _47a=_4.some(this.views.views,function(v){return v.flexCells;});if(!this._autoHeight&&(h||_4._getContentBox(this.domNode).h)===0){this.viewsHeaderNode.style.display="none";}else{this.viewsHeaderNode.style.display="block";if(!_47a&&hh===undefined){hh=this._getHeaderHeight();}}if(_47a){hh=undefined;}this.adaptWidth();this.adaptHeight(hh);this.postresize();},adaptWidth:function(){var _47b=(!this.initialWidth&&this.autoWidth);var w=_47b?0:this.domNode.clientWidth||(this.domNode.offsetWidth-this._getPadBorder().w),vw=this.views.arrange(1,w);this.views.onEach("adaptWidth");if(_47b){this.domNode.style.width=vw+"px";}},adaptHeight:function(_47c){var t=_47c===undefined?this._getHeaderHeight():_47c;var h=(this._autoHeight?-1:Math.max(this.domNode.clientHeight-t,0)||0);this.views.onEach("setSize",[0,h]);this.views.onEach("adaptHeight");if(!this._autoHeight){var _47d=0,_47e=0;var _47f=_4.filter(this.views.views,function(v){var has=v.hasHScrollbar();if(has){_47d++;}else{_47e++;}return (!has);});if(_47d>0&&_47e>0){_4.forEach(_47f,function(v){v.adaptHeight(true);});}}if(this.autoHeight===true||h!=-1||(typeof this.autoHeight=="number"&&this.autoHeight>=this.get("rowCount"))){this.scroller.windowHeight=h;}else{this.scroller.windowHeight=Math.max(this.domNode.clientHeight-t,0);}},startup:function(){if(this._started){return;}this.inherited(arguments);if(this.autoRender){this.render();}},render:function(){if(!this.domNode){return;}if(!this._started){return;}if(!this.hasLayout()){this.scroller.init(0,this.keepRows,this.rowsPerPage);return;}this.update=this.defaultUpdate;this._render();},_render:function(){this.scroller.init(this.get("rowCount"),this.keepRows,this.rowsPerPage);this.prerender();this.setScrollTop(0);this.postrender();},prerender:function(){this.keepRows=this._autoHeight?0:this.keepRows;this.scroller.setKeepInfo(this.keepRows);this.views.render();this._resize();},postrender:function(){this.postresize();this.focus.initFocusView();_4.setSelectable(this.domNode,this.selectable);},postresize:function(){if(this._autoHeight){var size=Math.max(this.views.measureContent())+"px";this.viewsNode.style.height=size;}},renderRow:function(_480,_481){this.views.renderRow(_480,_481,this._skipRowRenormalize);},rowRemoved:function(_482){this.views.rowRemoved(_482);},invalidated:null,updating:false,beginUpdate:function(){this.invalidated=[];this.updating=true;},endUpdate:function(){this.updating=false;var i=this.invalidated,r;if(i.all){this.update();}else{if(i.rowCount!=undefined){this.updateRowCount(i.rowCount);}else{for(r in i){this.updateRow(Number(r));}}}this.invalidated=[];},defaultUpdate:function(){if(!this.domNode){return;}if(this.updating){this.invalidated.all=true;return;}this.lastScrollTop=this.scrollTop;this.prerender();this.scroller.invalidateNodes();this.setScrollTop(this.lastScrollTop);this.postrender();},update:function(){this.render();},updateRow:function(_483){_483=Number(_483);if(this.updating){this.invalidated[_483]=true;}else{this.views.updateRow(_483);this.scroller.rowHeightChanged(_483);}},updateRows:function(_484,_485){_484=Number(_484);_485=Number(_485);var i;if(this.updating){for(i=0;i<_485;i++){this.invalidated[i+_484]=true;}}else{for(i=0;i<_485;i++){this.views.updateRow(i+_484,this._skipRowRenormalize);}this.scroller.rowHeightChanged(_484);}},updateRowCount:function(_486){if(this.updating){this.invalidated.rowCount=_486;}else{this.rowCount=_486;this._setAutoHeightAttr(this.autoHeight,true);if(this.layout.cells.length){this.scroller.updateRowCount(_486);}this._resize();if(this.layout.cells.length){this.setScrollTop(this.scrollTop);}}},updateRowStyles:function(_487){this.views.updateRowStyles(_487);},getRowNode:function(_488){if(this.focus.focusView&&!(this.focus.focusView instanceof _6.grid._RowSelector)){return this.focus.focusView.rowNodes[_488];}else{for(var i=0,_489;(_489=this.views.views[i]);i++){if(!(_489 instanceof _6.grid._RowSelector)){return _489.rowNodes[_488];}}}return null;},rowHeightChanged:function(_48a){this.views.renormalizeRow(_48a);this.scroller.rowHeightChanged(_48a);},fastScroll:true,delayScroll:false,scrollRedrawThreshold:(_4.isIE?100:50),scrollTo:function(_48b){if(!this.fastScroll){this.setScrollTop(_48b);return;}var _48c=Math.abs(this.lastScrollTop-_48b);this.lastScrollTop=_48b;if(_48c>this.scrollRedrawThreshold||this.delayScroll){this.delayScroll=true;this.scrollTop=_48b;this.views.setScrollTop(_48b);if(this._pendingScroll){window.clearTimeout(this._pendingScroll);}var _48d=this;this._pendingScroll=window.setTimeout(function(){delete _48d._pendingScroll;_48d.finishScrollJob();},200);}else{this.setScrollTop(_48b);}},finishScrollJob:function(){this.delayScroll=false;this.setScrollTop(this.scrollTop);},setScrollTop:function(_48e){this.scroller.scroll(this.views.setScrollTop(_48e));},scrollToRow:function(_48f){this.setScrollTop(this.scroller.findScrollTop(_48f)+1);},styleRowNode:function(_490,_491){if(_491){this.rows.styleRowNode(_490,_491);}},_mouseOut:function(e){this.rows.setOverRow(-2);},getCell:function(_492){return this.layout.cells[_492];},setCellWidth:function(_493,_494){this.getCell(_493).unitWidth=_494;},getCellName:function(_495){return "Cell "+_495.index;},canSort:function(_496){},sort:function(){},getSortAsc:function(_497){_497=_497==undefined?this.sortInfo:_497;return Boolean(_497>0);},getSortIndex:function(_498){_498=_498==undefined?this.sortInfo:_498;return Math.abs(_498)-1;},setSortIndex:function(_499,_49a){var si=_499+1;if(_49a!=undefined){si*=(_49a?1:-1);}else{if(this.getSortIndex()==_499){si=-this.sortInfo;}}this.setSortInfo(si);},setSortInfo:function(_49b){if(this.canSort(_49b)){this.sortInfo=_49b;this.sort();this.update();}},doKeyEvent:function(e){e.dispatch="do"+e.type;this.onKeyEvent(e);},_dispatch:function(m,e){if(m in this){return this[m](e);}return false;},dispatchKeyEvent:function(e){this._dispatch(e.dispatch,e);},dispatchContentEvent:function(e){this.edit.dispatchEvent(e)||e.sourceView.dispatchContentEvent(e)||this._dispatch(e.dispatch,e);},dispatchHeaderEvent:function(e){e.sourceView.dispatchHeaderEvent(e)||this._dispatch("doheader"+e.type,e);},dokeydown:function(e){this.onKeyDown(e);},doclick:function(e){if(e.cellNode){this.onCellClick(e);}else{this.onRowClick(e);}},dodblclick:function(e){if(e.cellNode){this.onCellDblClick(e);}else{this.onRowDblClick(e);}},docontextmenu:function(e){if(e.cellNode){this.onCellContextMenu(e);}else{this.onRowContextMenu(e);}},doheaderclick:function(e){if(e.cellNode){this.onHeaderCellClick(e);}else{this.onHeaderClick(e);}},doheaderdblclick:function(e){if(e.cellNode){this.onHeaderCellDblClick(e);}else{this.onHeaderDblClick(e);}},doheadercontextmenu:function(e){if(e.cellNode){this.onHeaderCellContextMenu(e);}else{this.onHeaderContextMenu(e);}},doStartEdit:function(_49c,_49d){this.onStartEdit(_49c,_49d);},doApplyCellEdit:function(_49e,_49f,_4a0){this.onApplyCellEdit(_49e,_49f,_4a0);},doCancelEdit:function(_4a1){this.onCancelEdit(_4a1);},doApplyEdit:function(_4a2){this.onApplyEdit(_4a2);},addRow:function(){this.updateRowCount(this.get("rowCount")+1);},removeSelectedRows:function(){if(this.allItemsSelected){this.updateRowCount(0);}else{this.updateRowCount(Math.max(0,this.get("rowCount")-this.selection.getSelected().length));}this.selection.clear();}});_6.grid._Grid.markupFactory=function(_4a3,node,ctor,_4a4){var d=_4;var _4a5=function(n){var w=d.attr(n,"width")||"auto";if((w!="auto")&&(w.slice(-2)!="em")&&(w.slice(-1)!="%")){w=parseInt(w,10)+"px";}return w;};if(!_4a3.structure&&node.nodeName.toLowerCase()=="table"){_4a3.structure=d.query("> colgroup",node).map(function(cg){var sv=d.attr(cg,"span");var v={noscroll:(d.attr(cg,"noscroll")=="true")?true:false,__span:(!!sv?parseInt(sv,10):1),cells:[]};if(d.hasAttr(cg,"width")){v.width=_4a5(cg);}return v;});if(!_4a3.structure.length){_4a3.structure.push({__span:Infinity,cells:[]});}d.query("thead > tr",node).forEach(function(tr,_4a6){var _4a7=0;var _4a8=0;var _4a9;var _4aa=null;d.query("> th",tr).map(function(th){if(!_4aa){_4a9=0;_4aa=_4a3.structure[0];}else{if(_4a7>=(_4a9+_4aa.__span)){_4a8++;_4a9+=_4aa.__span;var _4ab=_4aa;_4aa=_4a3.structure[_4a8];}}var cell={name:d.trim(d.attr(th,"name")||th.innerHTML),colSpan:parseInt(d.attr(th,"colspan")||1,10),type:d.trim(d.attr(th,"cellType")||""),id:d.trim(d.attr(th,"id")||"")};_4a7+=cell.colSpan;var _4ac=d.attr(th,"rowspan");if(_4ac){cell.rowSpan=_4ac;}if(d.hasAttr(th,"width")){cell.width=_4a5(th);}if(d.hasAttr(th,"relWidth")){cell.relWidth=window.parseInt(_4.attr(th,"relWidth"),10);}if(d.hasAttr(th,"hidden")){cell.hidden=(d.attr(th,"hidden")=="true"||d.attr(th,"hidden")===true);}if(_4a4){_4a4(th,cell);}cell.type=cell.type?_4.getObject(cell.type):_6.grid.cells.Cell;if(cell.type&&cell.type.markupFactory){cell.type.markupFactory(th,cell);}if(!_4aa.cells[_4a6]){_4aa.cells[_4a6]=[];}_4aa.cells[_4a6].push(cell);});});}return new ctor(_4a3,node);};})();}if(!_4._hasResource["dojox.grid.DataSelection"]){_4._hasResource["dojox.grid.DataSelection"]=true;_4.provide("dojox.grid.DataSelection");_4.declare("dojox.grid.DataSelection",_6.grid.Selection,{getFirstSelected:function(){var idx=_6.grid.Selection.prototype.getFirstSelected.call(this);if(idx==-1){return null;}return this.grid.getItem(idx);},getNextSelected:function(_4ad){var _4ae=this.grid.getItemIndex(_4ad);var idx=_6.grid.Selection.prototype.getNextSelected.call(this,_4ae);if(idx==-1){return null;}return this.grid.getItem(idx);},getSelected:function(){var _4af=[];for(var i=0,l=this.selected.length;i<l;i++){if(this.selected[i]){_4af.push(this.grid.getItem(i));}}return _4af;},addToSelection:function(_4b0){if(this.mode=="none"){return;}var idx=null;if(typeof _4b0=="number"||typeof _4b0=="string"){idx=_4b0;}else{idx=this.grid.getItemIndex(_4b0);}_6.grid.Selection.prototype.addToSelection.call(this,idx);},deselect:function(_4b1){if(this.mode=="none"){return;}var idx=null;if(typeof _4b1=="number"||typeof _4b1=="string"){idx=_4b1;}else{idx=this.grid.getItemIndex(_4b1);}_6.grid.Selection.prototype.deselect.call(this,idx);},deselectAll:function(_4b2){var idx=null;if(_4b2||typeof _4b2=="number"){if(typeof _4b2=="number"||typeof _4b2=="string"){idx=_4b2;}else{idx=this.grid.getItemIndex(_4b2);}_6.grid.Selection.prototype.deselectAll.call(this,idx);}else{this.inherited(arguments);}}});}if(!_4._hasResource["dojox.grid.DataGrid"]){_4._hasResource["dojox.grid.DataGrid"]=true;_4.provide("dojox.grid.DataGrid");_4.declare("dojox.grid.DataGrid",_6.grid._Grid,{store:null,query:null,queryOptions:null,fetchText:"...",sortFields:null,updateDelay:1,items:null,_store_connects:null,_by_idty:null,_by_idx:null,_cache:null,_pages:null,_pending_requests:null,_bop:-1,_eop:-1,_requests:0,rowCount:0,_isLoaded:false,_isLoading:false,postCreate:function(){this._pages=[];this._store_connects=[];this._by_idty={};this._by_idx=[];this._cache=[];this._pending_requests={};this._setStore(this.store);this.inherited(arguments);},createSelection:function(){this.selection=new _6.grid.DataSelection(this);},get:function(_4b3,_4b4){if(_4b4&&this.field=="_item"&&!this.fields){return _4b4;}else{if(_4b4&&this.fields){var ret=[];var s=this.grid.store;_4.forEach(this.fields,function(f){ret=ret.concat(s.getValues(_4b4,f));});return ret;}else{if(!_4b4&&typeof _4b3==="string"){return this.inherited(arguments);}}}return (!_4b4?this.defaultValue:(!this.field?this.value:(this.field=="_item"?_4b4:this.grid.store.getValue(_4b4,this.field))));},_checkUpdateStatus:function(){if(this.updateDelay>0){var _4b5=false;if(this._endUpdateDelay){clearTimeout(this._endUpdateDelay);delete this._endUpdateDelay;_4b5=true;}if(!this.updating){this.beginUpdate();_4b5=true;}if(_4b5){var _4b6=this;this._endUpdateDelay=setTimeout(function(){delete _4b6._endUpdateDelay;_4b6.endUpdate();},this.updateDelay);}}},_onSet:function(item,_4b7,_4b8,_4b9){this._checkUpdateStatus();var idx=this.getItemIndex(item);if(idx>-1){this.updateRow(idx);}},_createItem:function(item,_4ba){var idty=this._hasIdentity?this.store.getIdentity(item):_4.toJson(this.query)+":idx:"+_4ba+":sort:"+_4.toJson(this.getSortProps());var o=this._by_idty[idty]={idty:idty,item:item};return o;},_addItem:function(item,_4bb,_4bc){this._by_idx[_4bb]=this._createItem(item,_4bb);if(!_4bc){this.updateRow(_4bb);}},_onNew:function(item,_4bd){this._checkUpdateStatus();var _4be=this.get("rowCount");this._addingItem=true;this.updateRowCount(_4be+1);this._addingItem=false;this._addItem(item,_4be);this.showMessage();},_onDelete:function(item){this._checkUpdateStatus();var idx=this._getItemIndex(item,true);if(idx>=0){this._pages=[];this._bop=-1;this._eop=-1;var o=this._by_idx[idx];this._by_idx.splice(idx,1);delete this._by_idty[o.idty];this.updateRowCount(this.get("rowCount")-1);if(this.get("rowCount")===0){this.showMessage(this.noDataMessage);}}},_onRevert:function(){this._refresh();},setStore:function(_4bf,_4c0,_4c1){this._setQuery(_4c0,_4c1);this._setStore(_4bf);this._refresh(true);},setQuery:function(_4c2,_4c3){this._setQuery(_4c2,_4c3);this._refresh(true);},setItems:function(_4c4){this.items=_4c4;this._setStore(this.store);this._refresh(true);},_setQuery:function(_4c5,_4c6){this.query=_4c5;this.queryOptions=_4c6||this.queryOptions;},_setStore:function(_4c7){if(this.store&&this._store_connects){_4.forEach(this._store_connects,this.disconnect,this);}this.store=_4c7;if(this.store){var f=this.store.getFeatures();var h=[];this._canEdit=!!f["dojo.data.api.Write"]&&!!f["dojo.data.api.Identity"];this._hasIdentity=!!f["dojo.data.api.Identity"];if(!!f["dojo.data.api.Notification"]&&!this.items){h.push(this.connect(this.store,"onSet","_onSet"));h.push(this.connect(this.store,"onNew","_onNew"));h.push(this.connect(this.store,"onDelete","_onDelete"));}if(this._canEdit){h.push(this.connect(this.store,"revert","_onRevert"));}this._store_connects=h;}},_onFetchBegin:function(size,req){if(!this.scroller){return;}if(this.rowCount!=size){if(req.isRender){this.scroller.init(size,this.keepRows,this.rowsPerPage);this.rowCount=size;this._setAutoHeightAttr(this.autoHeight,true);this._skipRowRenormalize=true;this.prerender();this._skipRowRenormalize=false;}else{this.updateRowCount(size);}}if(!size){this.views.render();this._resize();this.showMessage(this.noDataMessage);this.focus.initFocusView();}else{this.showMessage();}},_onFetchComplete:function(_4c8,req){if(!this.scroller){return;}if(_4c8&&_4c8.length>0){_4.forEach(_4c8,function(item,idx){this._addItem(item,req.start+idx,true);},this);this.updateRows(req.start,_4c8.length);if(req.isRender){this.setScrollTop(0);this.postrender();}else{if(this._lastScrollTop){this.setScrollTop(this._lastScrollTop);}}}delete this._lastScrollTop;if(!this._isLoaded){this._isLoading=false;this._isLoaded=true;}this._pending_requests[req.start]=false;},_onFetchError:function(err,req){delete this._lastScrollTop;if(!this._isLoaded){this._isLoading=false;this._isLoaded=true;this.showMessage(this.errorMessage);}this._pending_requests[req.start]=false;this.onFetchError(err,req);},onFetchError:function(err,req){},_fetch:function(_4c9,_4ca){_4c9=_4c9||0;if(this.store&&!this._pending_requests[_4c9]){if(!this._isLoaded&&!this._isLoading){this._isLoading=true;this.showMessage(this.loadingMessage);}this._pending_requests[_4c9]=true;try{if(this.items){var _4cb=this.items;var _4cc=this.store;this.rowsPerPage=_4cb.length;var req={start:_4c9,count:this.rowsPerPage,isRender:_4ca};this._onFetchBegin(_4cb.length,req);var _4cd=0;_4.forEach(_4cb,function(i){if(!_4cc.isItemLoaded(i)){_4cd++;}});if(_4cd===0){this._onFetchComplete(_4cb,req);}else{var _4ce=function(item){_4cd--;if(_4cd===0){this._onFetchComplete(_4cb,req);}};_4.forEach(_4cb,function(i){if(!_4cc.isItemLoaded(i)){_4cc.loadItem({item:i,onItem:_4ce,scope:this});}},this);}}else{this.store.fetch({start:_4c9,count:this.rowsPerPage,query:this.query,sort:this.getSortProps(),queryOptions:this.queryOptions,isRender:_4ca,onBegin:_4.hitch(this,"_onFetchBegin"),onComplete:_4.hitch(this,"_onFetchComplete"),onError:_4.hitch(this,"_onFetchError")});}}catch(e){this._onFetchError(e,{start:_4c9,count:this.rowsPerPage});}}},_clearData:function(){this.updateRowCount(0);this._by_idty={};this._by_idx=[];this._pages=[];this._bop=this._eop=-1;this._isLoaded=false;this._isLoading=false;},getItem:function(idx){var data=this._by_idx[idx];if(!data||(data&&!data.item)){this._preparePage(idx);return null;}return data.item;},getItemIndex:function(item){return this._getItemIndex(item,false);},_getItemIndex:function(item,_4cf){if(!_4cf&&!this.store.isItem(item)){return -1;}var idty=this._hasIdentity?this.store.getIdentity(item):null;for(var i=0,l=this._by_idx.length;i<l;i++){var d=this._by_idx[i];if(d&&((idty&&d.idty==idty)||(d.item===item))){return i;}}return -1;},filter:function(_4d0,_4d1){this.query=_4d0;if(_4d1){this._clearData();}this._fetch();},_getItemAttr:function(idx,attr){var item=this.getItem(idx);return (!item?this.fetchText:this.store.getValue(item,attr));},_render:function(){if(this.domNode.parentNode){this.scroller.init(this.get("rowCount"),this.keepRows,this.rowsPerPage);this.prerender();this._fetch(0,true);}},_requestsPending:function(_4d2){return this._pending_requests[_4d2];},_rowToPage:function(_4d3){return (this.rowsPerPage?Math.floor(_4d3/this.rowsPerPage):_4d3);},_pageToRow:function(_4d4){return (this.rowsPerPage?this.rowsPerPage*_4d4:_4d4);},_preparePage:function(_4d5){if((_4d5<this._bop||_4d5>=this._eop)&&!this._addingItem){var _4d6=this._rowToPage(_4d5);this._needPage(_4d6);this._bop=_4d6*this.rowsPerPage;this._eop=this._bop+(this.rowsPerPage||this.get("rowCount"));}},_needPage:function(_4d7){if(!this._pages[_4d7]){this._pages[_4d7]=true;this._requestPage(_4d7);}},_requestPage:function(_4d8){var row=this._pageToRow(_4d8);var _4d9=Math.min(this.rowsPerPage,this.get("rowCount")-row);if(_4d9>0){this._requests++;if(!this._requestsPending(row)){setTimeout(_4.hitch(this,"_fetch",row,false),1);}}},getCellName:function(_4da){return _4da.field;},_refresh:function(_4db){this._clearData();this._fetch(0,_4db);},sort:function(){this.edit.apply();this._lastScrollTop=this.scrollTop;this._refresh();},canSort:function(){return (!this._isLoading);},getSortProps:function(){var c=this.getCell(this.getSortIndex());if(!c){if(this.sortFields){return this.sortFields;}return null;}else{var desc=c["sortDesc"];var si=!(this.sortInfo>0);if(typeof desc=="undefined"){desc=si;}else{desc=si?!desc:desc;}return [{attribute:c.field,descending:desc}];}},styleRowState:function(_4dc){if(this.store&&this.store.getState){var _4dd=this.store.getState(_4dc.index),c="";for(var i=0,ss=["inflight","error","inserting"],s;s=ss[i];i++){if(_4dd[s]){c=" dojoxGridRow-"+s;break;}}_4dc.customClasses+=c;}},onStyleRow:function(_4de){this.styleRowState(_4de);this.inherited(arguments);},canEdit:function(_4df,_4e0){return this._canEdit;},_copyAttr:function(idx,attr){var row={};var _4e1={};var src=this.getItem(idx);return this.store.getValue(src,attr);},doStartEdit:function(_4e2,_4e3){if(!this._cache[_4e3]){this._cache[_4e3]=this._copyAttr(_4e3,_4e2.field);}this.onStartEdit(_4e2,_4e3);},doApplyCellEdit:function(_4e4,_4e5,_4e6){this.store.fetchItemByIdentity({identity:this._by_idx[_4e5].idty,onItem:_4.hitch(this,function(item){var _4e7=this.store.getValue(item,_4e6);if(typeof _4e7=="number"){_4e4=isNaN(_4e4)?_4e4:parseFloat(_4e4);}else{if(typeof _4e7=="boolean"){_4e4=_4e4=="true"?true:_4e4=="false"?false:_4e4;}else{if(_4e7 instanceof Date){var _4e8=new Date(_4e4);_4e4=isNaN(_4e8.getTime())?_4e4:_4e8;}}}this.store.setValue(item,_4e6,_4e4);this.onApplyCellEdit(_4e4,_4e5,_4e6);})});},doCancelEdit:function(_4e9){var _4ea=this._cache[_4e9];if(_4ea){this.updateRow(_4e9);delete this._cache[_4e9];}this.onCancelEdit.apply(this,arguments);},doApplyEdit:function(_4eb,_4ec){var _4ed=this._cache[_4eb];this.onApplyEdit(_4eb);},removeSelectedRows:function(){if(this._canEdit){this.edit.apply();var fx=_4.hitch(this,function(_4ee){if(_4ee.length){_4.forEach(_4ee,this.store.deleteItem,this.store);this.selection.clear();}});if(this.allItemsSelected){this.store.fetch({query:this.query,queryOptions:this.queryOptions,onComplete:fx});}else{fx(this.selection.getSelected());}}}});_6.grid.DataGrid.cell_markupFactory=function(_4ef,node,_4f0){var _4f1=_4.trim(_4.attr(node,"field")||"");if(_4f1){_4f0.field=_4f1;}_4f0.field=_4f0.field||_4f0.name;var _4f2=_4.trim(_4.attr(node,"fields")||"");if(_4f2){_4f0.fields=_4f2.split(",");}if(_4ef){_4ef(node,_4f0);}};_6.grid.DataGrid.markupFactory=function(_4f3,node,ctor,_4f4){return _6.grid._Grid.markupFactory(_4f3,node,ctor,_4.partial(_6.grid.DataGrid.cell_markupFactory,_4f4));};}}};});
diff --git a/js/dojo-1.6/dojox/grid/DataGrid.xd.js.uncompressed.js b/js/dojo-1.6/dojox/grid/DataGrid.xd.js.uncompressed.js
new file mode 100644
index 0000000..83fb0bd
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/DataGrid.xd.js.uncompressed.js
@@ -0,0 +1,17090 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojo.window"],
+["provide", "dijit._base.manager"],
+["provide", "dijit._base.focus"],
+["provide", "dojo.AdapterRegistry"],
+["provide", "dijit._base.place"],
+["provide", "dijit._base.window"],
+["provide", "dijit._base.popup"],
+["provide", "dijit._base.scroll"],
+["provide", "dojo.uacss"],
+["provide", "dijit._base.sniff"],
+["provide", "dijit._base.typematic"],
+["provide", "dijit._base.wai"],
+["provide", "dijit._base"],
+["provide", "dojo.date.stamp"],
+["provide", "dojo.parser"],
+["provide", "dojo.Stateful"],
+["provide", "dijit._WidgetBase"],
+["provide", "dijit._Widget"],
+["provide", "dojo.string"],
+["provide", "dojo.cache"],
+["provide", "dijit._Templated"],
+["provide", "dijit._Container"],
+["provide", "dijit._Contained"],
+["provide", "dijit.layout._LayoutWidget"],
+["provide", "dijit._CssStateMixin"],
+["provide", "dijit.form._FormWidget"],
+["provide", "dijit.dijit"],
+["provide", "dijit._KeyNavContainer"],
+["provide", "dijit.MenuItem"],
+["provide", "dijit.PopupMenuItem"],
+["provide", "dijit.CheckedMenuItem"],
+["provide", "dijit.MenuSeparator"],
+["provide", "dijit.Menu"],
+["provide", "dojox.html.metrics"],
+["provide", "dojox.grid.util"],
+["provide", "dojox.grid._Scroller"],
+["provide", "dojox.grid.cells._base"],
+["provide", "dojox.grid.cells"],
+["provide", "dojo.dnd.common"],
+["provide", "dojo.dnd.autoscroll"],
+["provide", "dojo.dnd.Mover"],
+["provide", "dojo.dnd.Moveable"],
+["provide", "dojox.grid._Builder"],
+["provide", "dojo.dnd.Container"],
+["provide", "dojo.dnd.Selector"],
+["provide", "dojo.dnd.Avatar"],
+["provide", "dojo.dnd.Manager"],
+["provide", "dojo.dnd.Source"],
+["provide", "dojox.grid._View"],
+["provide", "dojox.grid._RowSelector"],
+["provide", "dojox.grid._Layout"],
+["provide", "dojox.grid._ViewManager"],
+["provide", "dojox.grid._RowManager"],
+["provide", "dojox.grid._FocusManager"],
+["provide", "dojox.grid._EditManager"],
+["provide", 'dojox.grid.Selection'],
+["provide", "dojox.grid._Events"],
+["provide", "dojox.grid._Grid"],
+["provide", "dojox.grid.DataSelection"],
+["provide", "dojox.grid.DataGrid"],
+["i18n._preloadLocalizations", "dojox.grid.nls.DataGrid", ["ROOT","ar","ca","cs","da","de","de-de","el","en","en-gb","en-us","es","es-es","fi","fi-fi","fr","fr-fr","he","he-il","hu","it","it-it","ja","ja-jp","ko","ko-kr","nb","nl","nl-nl","pl","pt","pt-br","pt-pt","ru","sk","sl","sv","th","tr","xx","zh","zh-cn","zh-tw"]]],
+defineResource: function(dojo, dijit, dojox){/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+/*
+ This is an optimized version of Dojo, built for deployment and not for
+ development. To get sources and documentation, please visit:
+
+ http://dojotoolkit.org
+*/
+
+if(!dojo._hasResource["dojo.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.window"] = true;
+dojo.provide("dojo.window");
+
+
+dojo.getObject("window", true, dojo);
+
+dojo.window.getBox = function(){
+ // summary:
+ // Returns the dimensions and scroll position of the viewable area of a browser window
+
+ var scrollRoot = (dojo.doc.compatMode == 'BackCompat') ? dojo.body() : dojo.doc.documentElement;
+
+ // get scroll position
+ var scroll = dojo._docScroll(); // scrollRoot.scrollTop/Left should work
+ return { w: scrollRoot.clientWidth, h: scrollRoot.clientHeight, l: scroll.x, t: scroll.y };
+};
+
+dojo.window.get = function(doc){
+ // summary:
+ // Get window object associated with document doc
+
+ // In some IE versions (at least 6.0), document.parentWindow does not return a
+ // reference to the real window object (maybe a copy), so we must fix it as well
+ // We use IE specific execScript to attach the real window reference to
+ // document._parentWindow for later use
+ if(dojo.isIE && window !== document.parentWindow){
+ /*
+ In IE 6, only the variable "window" can be used to connect events (others
+ may be only copies).
+ */
+ doc.parentWindow.execScript("document._parentWindow = window;", "Javascript");
+ //to prevent memory leak, unset it after use
+ //another possibility is to add an onUnload handler which seems overkill to me (liucougar)
+ var win = doc._parentWindow;
+ doc._parentWindow = null;
+ return win; // Window
+ }
+
+ return doc.parentWindow || doc.defaultView; // Window
+};
+
+dojo.window.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
+ // summary:
+ // Scroll the passed node into view, if it is not already.
+
+ // don't rely on node.scrollIntoView working just because the function is there
+
+ try{ // catch unexpected/unrecreatable errors (#7808) since we can recover using a semi-acceptable native method
+ node = dojo.byId(node);
+ var doc = node.ownerDocument || dojo.doc,
+ body = doc.body || dojo.body(),
+ html = doc.documentElement || body.parentNode,
+ isIE = dojo.isIE, isWK = dojo.isWebKit;
+ // if an untested browser, then use the native method
+ if((!(dojo.isMoz || isIE || isWK || dojo.isOpera) || node == body || node == html) && (typeof node.scrollIntoView != "undefined")){
+ node.scrollIntoView(false); // short-circuit to native if possible
+ return;
+ }
+ var backCompat = doc.compatMode == 'BackCompat',
+ clientAreaRoot = backCompat? body : html,
+ scrollRoot = isWK ? body : clientAreaRoot,
+ rootWidth = clientAreaRoot.clientWidth,
+ rootHeight = clientAreaRoot.clientHeight,
+ rtl = !dojo._isBodyLtr(),
+ nodePos = pos || dojo.position(node),
+ el = node.parentNode,
+ isFixed = function(el){
+ return ((isIE <= 6 || (isIE && backCompat))? false : (dojo.style(el, 'position').toLowerCase() == "fixed"));
+ };
+ if(isFixed(node)){ return; } // nothing to do
+
+ while(el){
+ if(el == body){ el = scrollRoot; }
+ var elPos = dojo.position(el),
+ fixedPos = isFixed(el);
+
+ if(el == scrollRoot){
+ elPos.w = rootWidth; elPos.h = rootHeight;
+ if(scrollRoot == html && isIE && rtl){ elPos.x += scrollRoot.offsetWidth-elPos.w; } // IE workaround where scrollbar causes negative x
+ if(elPos.x < 0 || !isIE){ elPos.x = 0; } // IE can have values > 0
+ if(elPos.y < 0 || !isIE){ elPos.y = 0; }
+ }else{
+ var pb = dojo._getPadBorderExtents(el);
+ elPos.w -= pb.w; elPos.h -= pb.h; elPos.x += pb.l; elPos.y += pb.t;
+ }
+
+ if(el != scrollRoot){ // body, html sizes already have the scrollbar removed
+ var clientSize = el.clientWidth,
+ scrollBarSize = elPos.w - clientSize;
+ if(clientSize > 0 && scrollBarSize > 0){
+ elPos.w = clientSize;
+ if(isIE && rtl){ elPos.x += scrollBarSize; }
+ }
+ clientSize = el.clientHeight;
+ scrollBarSize = elPos.h - clientSize;
+ if(clientSize > 0 && scrollBarSize > 0){
+ elPos.h = clientSize;
+ }
+ }
+ if(fixedPos){ // bounded by viewport, not parents
+ if(elPos.y < 0){
+ elPos.h += elPos.y; elPos.y = 0;
+ }
+ if(elPos.x < 0){
+ elPos.w += elPos.x; elPos.x = 0;
+ }
+ if(elPos.y + elPos.h > rootHeight){
+ elPos.h = rootHeight - elPos.y;
+ }
+ if(elPos.x + elPos.w > rootWidth){
+ elPos.w = rootWidth - elPos.x;
+ }
+ }
+ // calculate overflow in all 4 directions
+ var l = nodePos.x - elPos.x, // beyond left: < 0
+ t = nodePos.y - Math.max(elPos.y, 0), // beyond top: < 0
+ r = l + nodePos.w - elPos.w, // beyond right: > 0
+ bot = t + nodePos.h - elPos.h; // beyond bottom: > 0
+ if(r * l > 0){
+ var s = Math[l < 0? "max" : "min"](l, r);
+ nodePos.x += el.scrollLeft;
+ el.scrollLeft += (isIE >= 8 && !backCompat && rtl)? -s : s;
+ nodePos.x -= el.scrollLeft;
+ }
+ if(bot * t > 0){
+ nodePos.y += el.scrollTop;
+ el.scrollTop += Math[t < 0? "max" : "min"](t, bot);
+ nodePos.y -= el.scrollTop;
+ }
+ el = (el != scrollRoot) && !fixedPos && el.parentNode;
+ }
+ }catch(error){
+ console.error('scrollIntoView: ' + error);
+ node.scrollIntoView(false);
+ }
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.manager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.manager"] = true;
+dojo.provide("dijit._base.manager");
+
+
+
+dojo.declare("dijit.WidgetSet", null, {
+ // summary:
+ // A set of widgets indexed by id. A default instance of this class is
+ // available as `dijit.registry`
+ //
+ // example:
+ // Create a small list of widgets:
+ // | var ws = new dijit.WidgetSet();
+ // | ws.add(dijit.byId("one"));
+ // | ws.add(dijit.byId("two"));
+ // | // destroy both:
+ // | ws.forEach(function(w){ w.destroy(); });
+ //
+ // example:
+ // Using dijit.registry:
+ // | dijit.registry.forEach(function(w){ /* do something */ });
+
+ constructor: function(){
+ this._hash = {};
+ this.length = 0;
+ },
+
+ add: function(/*dijit._Widget*/ widget){
+ // summary:
+ // Add a widget to this list. If a duplicate ID is detected, a error is thrown.
+ //
+ // widget: dijit._Widget
+ // Any dijit._Widget subclass.
+ if(this._hash[widget.id]){
+ throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
+ }
+ this._hash[widget.id] = widget;
+ this.length++;
+ },
+
+ remove: function(/*String*/ id){
+ // summary:
+ // Remove a widget from this WidgetSet. Does not destroy the widget; simply
+ // removes the reference.
+ if(this._hash[id]){
+ delete this._hash[id];
+ this.length--;
+ }
+ },
+
+ forEach: function(/*Function*/ func, /* Object? */thisObj){
+ // summary:
+ // Call specified function for each widget in this set.
+ //
+ // func:
+ // A callback function to run for each item. Is passed the widget, the index
+ // in the iteration, and the full hash, similar to `dojo.forEach`.
+ //
+ // thisObj:
+ // An optional scope parameter
+ //
+ // example:
+ // Using the default `dijit.registry` instance:
+ // | dijit.registry.forEach(function(widget){
+ // | console.log(widget.declaredClass);
+ // | });
+ //
+ // returns:
+ // Returns self, in order to allow for further chaining.
+
+ thisObj = thisObj || dojo.global;
+ var i = 0, id;
+ for(id in this._hash){
+ func.call(thisObj, this._hash[id], i++, this._hash);
+ }
+ return this; // dijit.WidgetSet
+ },
+
+ filter: function(/*Function*/ filter, /* Object? */thisObj){
+ // summary:
+ // Filter down this WidgetSet to a smaller new WidgetSet
+ // Works the same as `dojo.filter` and `dojo.NodeList.filter`
+ //
+ // filter:
+ // Callback function to test truthiness. Is passed the widget
+ // reference and the pseudo-index in the object.
+ //
+ // thisObj: Object?
+ // Option scope to use for the filter function.
+ //
+ // example:
+ // Arbitrary: select the odd widgets in this list
+ // | dijit.registry.filter(function(w, i){
+ // | return i % 2 == 0;
+ // | }).forEach(function(w){ /* odd ones */ });
+
+ thisObj = thisObj || dojo.global;
+ var res = new dijit.WidgetSet(), i = 0, id;
+ for(id in this._hash){
+ var w = this._hash[id];
+ if(filter.call(thisObj, w, i++, this._hash)){
+ res.add(w);
+ }
+ }
+ return res; // dijit.WidgetSet
+ },
+
+ byId: function(/*String*/ id){
+ // summary:
+ // Find a widget in this list by it's id.
+ // example:
+ // Test if an id is in a particular WidgetSet
+ // | var ws = new dijit.WidgetSet();
+ // | ws.add(dijit.byId("bar"));
+ // | var t = ws.byId("bar") // returns a widget
+ // | var x = ws.byId("foo"); // returns undefined
+
+ return this._hash[id]; // dijit._Widget
+ },
+
+ byClass: function(/*String*/ cls){
+ // summary:
+ // Reduce this widgetset to a new WidgetSet of a particular `declaredClass`
+ //
+ // cls: String
+ // The Class to scan for. Full dot-notated string.
+ //
+ // example:
+ // Find all `dijit.TitlePane`s in a page:
+ // | dijit.registry.byClass("dijit.TitlePane").forEach(function(tp){ tp.close(); });
+
+ var res = new dijit.WidgetSet(), id, widget;
+ for(id in this._hash){
+ widget = this._hash[id];
+ if(widget.declaredClass == cls){
+ res.add(widget);
+ }
+ }
+ return res; // dijit.WidgetSet
+},
+
+ toArray: function(){
+ // summary:
+ // Convert this WidgetSet into a true Array
+ //
+ // example:
+ // Work with the widget .domNodes in a real Array
+ // | dojo.map(dijit.registry.toArray(), function(w){ return w.domNode; });
+
+ var ar = [];
+ for(var id in this._hash){
+ ar.push(this._hash[id]);
+ }
+ return ar; // dijit._Widget[]
+},
+
+ map: function(/* Function */func, /* Object? */thisObj){
+ // summary:
+ // Create a new Array from this WidgetSet, following the same rules as `dojo.map`
+ // example:
+ // | var nodes = dijit.registry.map(function(w){ return w.domNode; });
+ //
+ // returns:
+ // A new array of the returned values.
+ return dojo.map(this.toArray(), func, thisObj); // Array
+ },
+
+ every: function(func, thisObj){
+ // summary:
+ // A synthetic clone of `dojo.every` acting explicitly on this WidgetSet
+ //
+ // func: Function
+ // A callback function run for every widget in this list. Exits loop
+ // when the first false return is encountered.
+ //
+ // thisObj: Object?
+ // Optional scope parameter to use for the callback
+
+ thisObj = thisObj || dojo.global;
+ var x = 0, i;
+ for(i in this._hash){
+ if(!func.call(thisObj, this._hash[i], x++, this._hash)){
+ return false; // Boolean
+ }
+ }
+ return true; // Boolean
+ },
+
+ some: function(func, thisObj){
+ // summary:
+ // A synthetic clone of `dojo.some` acting explictly on this WidgetSet
+ //
+ // func: Function
+ // A callback function run for every widget in this list. Exits loop
+ // when the first true return is encountered.
+ //
+ // thisObj: Object?
+ // Optional scope parameter to use for the callback
+
+ thisObj = thisObj || dojo.global;
+ var x = 0, i;
+ for(i in this._hash){
+ if(func.call(thisObj, this._hash[i], x++, this._hash)){
+ return true; // Boolean
+ }
+ }
+ return false; // Boolean
+ }
+
+});
+
+(function(){
+
+ /*=====
+ dijit.registry = {
+ // summary:
+ // A list of widgets on a page.
+ // description:
+ // Is an instance of `dijit.WidgetSet`
+ };
+ =====*/
+ dijit.registry = new dijit.WidgetSet();
+
+ var hash = dijit.registry._hash,
+ attr = dojo.attr,
+ hasAttr = dojo.hasAttr,
+ style = dojo.style;
+
+ dijit.byId = function(/*String|dijit._Widget*/ id){
+ // summary:
+ // Returns a widget by it's id, or if passed a widget, no-op (like dojo.byId())
+ return typeof id == "string" ? hash[id] : id; // dijit._Widget
+ };
+
+ var _widgetTypeCtr = {};
+ dijit.getUniqueId = function(/*String*/widgetType){
+ // summary:
+ // Generates a unique id for a given widgetType
+
+ var id;
+ do{
+ id = widgetType + "_" +
+ (widgetType in _widgetTypeCtr ?
+ ++_widgetTypeCtr[widgetType] : _widgetTypeCtr[widgetType] = 0);
+ }while(hash[id]);
+ return dijit._scopeName == "dijit" ? id : dijit._scopeName + "_" + id; // String
+ };
+
+ dijit.findWidgets = function(/*DomNode*/ root){
+ // summary:
+ // Search subtree under root returning widgets found.
+ // Doesn't search for nested widgets (ie, widgets inside other widgets).
+
+ var outAry = [];
+
+ function getChildrenHelper(root){
+ for(var node = root.firstChild; node; node = node.nextSibling){
+ if(node.nodeType == 1){
+ var widgetId = node.getAttribute("widgetId");
+ if(widgetId){
+ var widget = hash[widgetId];
+ if(widget){ // may be null on page w/multiple dojo's loaded
+ outAry.push(widget);
+ }
+ }else{
+ getChildrenHelper(node);
+ }
+ }
+ }
+ }
+
+ getChildrenHelper(root);
+ return outAry;
+ };
+
+ dijit._destroyAll = function(){
+ // summary:
+ // Code to destroy all widgets and do other cleanup on page unload
+
+ // Clean up focus manager lingering references to widgets and nodes
+ dijit._curFocus = null;
+ dijit._prevFocus = null;
+ dijit._activeStack = [];
+
+ // Destroy all the widgets, top down
+ dojo.forEach(dijit.findWidgets(dojo.body()), function(widget){
+ // Avoid double destroy of widgets like Menu that are attached to <body>
+ // even though they are logically children of other widgets.
+ if(!widget._destroyed){
+ if(widget.destroyRecursive){
+ widget.destroyRecursive();
+ }else if(widget.destroy){
+ widget.destroy();
+ }
+ }
+ });
+ };
+
+ if(dojo.isIE){
+ // Only run _destroyAll() for IE because we think it's only necessary in that case,
+ // and because it causes problems on FF. See bug #3531 for details.
+ dojo.addOnWindowUnload(function(){
+ dijit._destroyAll();
+ });
+ }
+
+ dijit.byNode = function(/*DOMNode*/ node){
+ // summary:
+ // Returns the widget corresponding to the given DOMNode
+ return hash[node.getAttribute("widgetId")]; // dijit._Widget
+ };
+
+ dijit.getEnclosingWidget = function(/*DOMNode*/ node){
+ // summary:
+ // Returns the widget whose DOM tree contains the specified DOMNode, or null if
+ // the node is not contained within the DOM tree of any widget
+ while(node){
+ var id = node.getAttribute && node.getAttribute("widgetId");
+ if(id){
+ return hash[id];
+ }
+ node = node.parentNode;
+ }
+ return null;
+ };
+
+ var shown = (dijit._isElementShown = function(/*Element*/ elem){
+ var s = style(elem);
+ return (s.visibility != "hidden")
+ && (s.visibility != "collapsed")
+ && (s.display != "none")
+ && (attr(elem, "type") != "hidden");
+ });
+
+ dijit.hasDefaultTabStop = function(/*Element*/ elem){
+ // summary:
+ // Tests if element is tab-navigable even without an explicit tabIndex setting
+
+ // No explicit tabIndex setting, need to investigate node type
+ switch(elem.nodeName.toLowerCase()){
+ case "a":
+ // An <a> w/out a tabindex is only navigable if it has an href
+ return hasAttr(elem, "href");
+ case "area":
+ case "button":
+ case "input":
+ case "object":
+ case "select":
+ case "textarea":
+ // These are navigable by default
+ return true;
+ case "iframe":
+ // If it's an editor <iframe> then it's tab navigable.
+ var body;
+ try{
+ // non-IE
+ var contentDocument = elem.contentDocument;
+ if("designMode" in contentDocument && contentDocument.designMode == "on"){
+ return true;
+ }
+ body = contentDocument.body;
+ }catch(e1){
+ // contentWindow.document isn't accessible within IE7/8
+ // if the iframe.src points to a foreign url and this
+ // page contains an element, that could get focus
+ try{
+ body = elem.contentWindow.document.body;
+ }catch(e2){
+ return false;
+ }
+ }
+ return body.contentEditable == 'true' || (body.firstChild && body.firstChild.contentEditable == 'true');
+ default:
+ return elem.contentEditable == 'true';
+ }
+ };
+
+ var isTabNavigable = (dijit.isTabNavigable = function(/*Element*/ elem){
+ // summary:
+ // Tests if an element is tab-navigable
+
+ // TODO: convert (and rename method) to return effective tabIndex; will save time in _getTabNavigable()
+ if(attr(elem, "disabled")){
+ return false;
+ }else if(hasAttr(elem, "tabIndex")){
+ // Explicit tab index setting
+ return attr(elem, "tabIndex") >= 0; // boolean
+ }else{
+ // No explicit tabIndex setting, so depends on node type
+ return dijit.hasDefaultTabStop(elem);
+ }
+ });
+
+ dijit._getTabNavigable = function(/*DOMNode*/ root){
+ // summary:
+ // Finds descendants of the specified root node.
+ //
+ // description:
+ // Finds the following descendants of the specified root node:
+ // * the first tab-navigable element in document order
+ // without a tabIndex or with tabIndex="0"
+ // * the last tab-navigable element in document order
+ // without a tabIndex or with tabIndex="0"
+ // * the first element in document order with the lowest
+ // positive tabIndex value
+ // * the last element in document order with the highest
+ // positive tabIndex value
+ var first, last, lowest, lowestTabindex, highest, highestTabindex, radioSelected = {};
+ function radioName(node) {
+ // If this element is part of a radio button group, return the name for that group.
+ return node && node.tagName.toLowerCase() == "input" &&
+ node.type && node.type.toLowerCase() == "radio" &&
+ node.name && node.name.toLowerCase();
+ }
+ var walkTree = function(/*DOMNode*/parent){
+ dojo.query("> *", parent).forEach(function(child){
+ // Skip hidden elements, and also non-HTML elements (those in custom namespaces) in IE,
+ // since show() invokes getAttribute("type"), which crash on VML nodes in IE.
+ if((dojo.isIE && child.scopeName!=="HTML") || !shown(child)){
+ return;
+ }
+
+ if(isTabNavigable(child)){
+ var tabindex = attr(child, "tabIndex");
+ if(!hasAttr(child, "tabIndex") || tabindex == 0){
+ if(!first){ first = child; }
+ last = child;
+ }else if(tabindex > 0){
+ if(!lowest || tabindex < lowestTabindex){
+ lowestTabindex = tabindex;
+ lowest = child;
+ }
+ if(!highest || tabindex >= highestTabindex){
+ highestTabindex = tabindex;
+ highest = child;
+ }
+ }
+ var rn = radioName(child);
+ if(dojo.attr(child, "checked") && rn) {
+ radioSelected[rn] = child;
+ }
+ }
+ if(child.nodeName.toUpperCase() != 'SELECT'){
+ walkTree(child);
+ }
+ });
+ };
+ if(shown(root)){ walkTree(root) }
+ function rs(node) {
+ // substitute checked radio button for unchecked one, if there is a checked one with the same name.
+ return radioSelected[radioName(node)] || node;
+ }
+ return { first: rs(first), last: rs(last), lowest: rs(lowest), highest: rs(highest) };
+ }
+ dijit.getFirstInTabbingOrder = function(/*String|DOMNode*/ root){
+ // summary:
+ // Finds the descendant of the specified root node
+ // that is first in the tabbing order
+ var elems = dijit._getTabNavigable(dojo.byId(root));
+ return elems.lowest ? elems.lowest : elems.first; // DomNode
+ };
+
+ dijit.getLastInTabbingOrder = function(/*String|DOMNode*/ root){
+ // summary:
+ // Finds the descendant of the specified root node
+ // that is last in the tabbing order
+ var elems = dijit._getTabNavigable(dojo.byId(root));
+ return elems.last ? elems.last : elems.highest; // DomNode
+ };
+
+ /*=====
+ dojo.mixin(dijit, {
+ // defaultDuration: Integer
+ // The default animation speed (in ms) to use for all Dijit
+ // transitional animations, unless otherwise specified
+ // on a per-instance basis. Defaults to 200, overrided by
+ // `djConfig.defaultDuration`
+ defaultDuration: 200
+ });
+ =====*/
+
+ dijit.defaultDuration = dojo.config["defaultDuration"] || 200;
+
+})();
+
+}
+
+if(!dojo._hasResource["dijit._base.focus"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.focus"] = true;
+dojo.provide("dijit._base.focus");
+
+
+
+
+
+// summary:
+// These functions are used to query or set the focus and selection.
+//
+// Also, they trace when widgets become activated/deactivated,
+// so that the widget can fire _onFocus/_onBlur events.
+// "Active" here means something similar to "focused", but
+// "focus" isn't quite the right word because we keep track of
+// a whole stack of "active" widgets. Example: ComboButton --> Menu -->
+// MenuItem. The onBlur event for ComboButton doesn't fire due to focusing
+// on the Menu or a MenuItem, since they are considered part of the
+// ComboButton widget. It only happens when focus is shifted
+// somewhere completely different.
+
+dojo.mixin(dijit, {
+ // _curFocus: DomNode
+ // Currently focused item on screen
+ _curFocus: null,
+
+ // _prevFocus: DomNode
+ // Previously focused item on screen
+ _prevFocus: null,
+
+ isCollapsed: function(){
+ // summary:
+ // Returns true if there is no text selected
+ return dijit.getBookmark().isCollapsed;
+ },
+
+ getBookmark: function(){
+ // summary:
+ // Retrieves a bookmark that can be used with moveToBookmark to return to the same range
+ var bm, rg, tg, sel = dojo.doc.selection, cf = dijit._curFocus;
+
+ if(dojo.global.getSelection){
+ //W3C Range API for selections.
+ sel = dojo.global.getSelection();
+ if(sel){
+ if(sel.isCollapsed){
+ tg = cf? cf.tagName : "";
+ if(tg){
+ //Create a fake rangelike item to restore selections.
+ tg = tg.toLowerCase();
+ if(tg == "textarea" ||
+ (tg == "input" && (!cf.type || cf.type.toLowerCase() == "text"))){
+ sel = {
+ start: cf.selectionStart,
+ end: cf.selectionEnd,
+ node: cf,
+ pRange: true
+ };
+ return {isCollapsed: (sel.end <= sel.start), mark: sel}; //Object.
+ }
+ }
+ bm = {isCollapsed:true};
+ }else{
+ rg = sel.getRangeAt(0);
+ bm = {isCollapsed: false, mark: rg.cloneRange()};
+ }
+ }
+ }else if(sel){
+ // If the current focus was a input of some sort and no selection, don't bother saving
+ // a native bookmark. This is because it causes issues with dialog/page selection restore.
+ // So, we need to create psuedo bookmarks to work with.
+ tg = cf ? cf.tagName : "";
+ tg = tg.toLowerCase();
+ if(cf && tg && (tg == "button" || tg == "textarea" || tg == "input")){
+ if(sel.type && sel.type.toLowerCase() == "none"){
+ return {
+ isCollapsed: true,
+ mark: null
+ }
+ }else{
+ rg = sel.createRange();
+ return {
+ isCollapsed: rg.text && rg.text.length?false:true,
+ mark: {
+ range: rg,
+ pRange: true
+ }
+ };
+ }
+ }
+ bm = {};
+
+ //'IE' way for selections.
+ try{
+ // createRange() throws exception when dojo in iframe
+ //and nothing selected, see #9632
+ rg = sel.createRange();
+ bm.isCollapsed = !(sel.type == 'Text' ? rg.htmlText.length : rg.length);
+ }catch(e){
+ bm.isCollapsed = true;
+ return bm;
+ }
+ if(sel.type.toUpperCase() == 'CONTROL'){
+ if(rg.length){
+ bm.mark=[];
+ var i=0,len=rg.length;
+ while(i<len){
+ bm.mark.push(rg.item(i++));
+ }
+ }else{
+ bm.isCollapsed = true;
+ bm.mark = null;
+ }
+ }else{
+ bm.mark = rg.getBookmark();
+ }
+ }else{
+ console.warn("No idea how to store the current selection for this browser!");
+ }
+ return bm; // Object
+ },
+
+ moveToBookmark: function(/*Object*/bookmark){
+ // summary:
+ // Moves current selection to a bookmark
+ // bookmark:
+ // This should be a returned object from dijit.getBookmark()
+
+ var _doc = dojo.doc,
+ mark = bookmark.mark;
+ if(mark){
+ if(dojo.global.getSelection){
+ //W3C Rangi API (FF, WebKit, Opera, etc)
+ var sel = dojo.global.getSelection();
+ if(sel && sel.removeAllRanges){
+ if(mark.pRange){
+ var r = mark;
+ var n = r.node;
+ n.selectionStart = r.start;
+ n.selectionEnd = r.end;
+ }else{
+ sel.removeAllRanges();
+ sel.addRange(mark);
+ }
+ }else{
+ console.warn("No idea how to restore selection for this browser!");
+ }
+ }else if(_doc.selection && mark){
+ //'IE' way.
+ var rg;
+ if(mark.pRange){
+ rg = mark.range;
+ }else if(dojo.isArray(mark)){
+ rg = _doc.body.createControlRange();
+ //rg.addElement does not have call/apply method, so can not call it directly
+ //rg is not available in "range.addElement(item)", so can't use that either
+ dojo.forEach(mark, function(n){
+ rg.addElement(n);
+ });
+ }else{
+ rg = _doc.body.createTextRange();
+ rg.moveToBookmark(mark);
+ }
+ rg.select();
+ }
+ }
+ },
+
+ getFocus: function(/*Widget?*/ menu, /*Window?*/ openedForWindow){
+ // summary:
+ // Called as getFocus(), this returns an Object showing the current focus
+ // and selected text.
+ //
+ // Called as getFocus(widget), where widget is a (widget representing) a button
+ // that was just pressed, it returns where focus was before that button
+ // was pressed. (Pressing the button may have either shifted focus to the button,
+ // or removed focus altogether.) In this case the selected text is not returned,
+ // since it can't be accurately determined.
+ //
+ // menu: dijit._Widget or {domNode: DomNode} structure
+ // The button that was just pressed. If focus has disappeared or moved
+ // to this button, returns the previous focus. In this case the bookmark
+ // information is already lost, and null is returned.
+ //
+ // openedForWindow:
+ // iframe in which menu was opened
+ //
+ // returns:
+ // A handle to restore focus/selection, to be passed to `dijit.focus`
+ var node = !dijit._curFocus || (menu && dojo.isDescendant(dijit._curFocus, menu.domNode)) ? dijit._prevFocus : dijit._curFocus;
+ return {
+ node: node,
+ bookmark: (node == dijit._curFocus) && dojo.withGlobal(openedForWindow || dojo.global, dijit.getBookmark),
+ openedForWindow: openedForWindow
+ }; // Object
+ },
+
+ focus: function(/*Object || DomNode */ handle){
+ // summary:
+ // Sets the focused node and the selection according to argument.
+ // To set focus to an iframe's content, pass in the iframe itself.
+ // handle:
+ // object returned by get(), or a DomNode
+
+ if(!handle){ return; }
+
+ var node = "node" in handle ? handle.node : handle, // because handle is either DomNode or a composite object
+ bookmark = handle.bookmark,
+ openedForWindow = handle.openedForWindow,
+ collapsed = bookmark ? bookmark.isCollapsed : false;
+
+ // Set the focus
+ // Note that for iframe's we need to use the <iframe> to follow the parentNode chain,
+ // but we need to set focus to iframe.contentWindow
+ if(node){
+ var focusNode = (node.tagName.toLowerCase() == "iframe") ? node.contentWindow : node;
+ if(focusNode && focusNode.focus){
+ try{
+ // Gecko throws sometimes if setting focus is impossible,
+ // node not displayed or something like that
+ focusNode.focus();
+ }catch(e){/*quiet*/}
+ }
+ dijit._onFocusNode(node);
+ }
+
+ // set the selection
+ // do not need to restore if current selection is not empty
+ // (use keyboard to select a menu item) or if previous selection was collapsed
+ // as it may cause focus shift (Esp in IE).
+ if(bookmark && dojo.withGlobal(openedForWindow || dojo.global, dijit.isCollapsed) && !collapsed){
+ if(openedForWindow){
+ openedForWindow.focus();
+ }
+ try{
+ dojo.withGlobal(openedForWindow || dojo.global, dijit.moveToBookmark, null, [bookmark]);
+ }catch(e2){
+ /*squelch IE internal error, see http://trac.dojotoolkit.org/ticket/1984 */
+ }
+ }
+ },
+
+ // _activeStack: dijit._Widget[]
+ // List of currently active widgets (focused widget and it's ancestors)
+ _activeStack: [],
+
+ registerIframe: function(/*DomNode*/ iframe){
+ // summary:
+ // Registers listeners on the specified iframe so that any click
+ // or focus event on that iframe (or anything in it) is reported
+ // as a focus/click event on the <iframe> itself.
+ // description:
+ // Currently only used by editor.
+ // returns:
+ // Handle to pass to unregisterIframe()
+ return dijit.registerWin(iframe.contentWindow, iframe);
+ },
+
+ unregisterIframe: function(/*Object*/ handle){
+ // summary:
+ // Unregisters listeners on the specified iframe created by registerIframe.
+ // After calling be sure to delete or null out the handle itself.
+ // handle:
+ // Handle returned by registerIframe()
+
+ dijit.unregisterWin(handle);
+ },
+
+ registerWin: function(/*Window?*/targetWindow, /*DomNode?*/ effectiveNode){
+ // summary:
+ // Registers listeners on the specified window (either the main
+ // window or an iframe's window) to detect when the user has clicked somewhere
+ // or focused somewhere.
+ // description:
+ // Users should call registerIframe() instead of this method.
+ // targetWindow:
+ // If specified this is the window associated with the iframe,
+ // i.e. iframe.contentWindow.
+ // effectiveNode:
+ // If specified, report any focus events inside targetWindow as
+ // an event on effectiveNode, rather than on evt.target.
+ // returns:
+ // Handle to pass to unregisterWin()
+
+ // TODO: make this function private in 2.0; Editor/users should call registerIframe(),
+
+ var mousedownListener = function(evt){
+ dijit._justMouseDowned = true;
+ setTimeout(function(){ dijit._justMouseDowned = false; }, 0);
+
+ // workaround weird IE bug where the click is on an orphaned node
+ // (first time clicking a Select/DropDownButton inside a TooltipDialog)
+ if(dojo.isIE && evt && evt.srcElement && evt.srcElement.parentNode == null){
+ return;
+ }
+
+ dijit._onTouchNode(effectiveNode || evt.target || evt.srcElement, "mouse");
+ };
+ //dojo.connect(targetWindow, "onscroll", ???);
+
+ // Listen for blur and focus events on targetWindow's document.
+ // IIRC, I'm using attachEvent() rather than dojo.connect() because focus/blur events don't bubble
+ // through dojo.connect(), and also maybe to catch the focus events early, before onfocus handlers
+ // fire.
+ // Connect to <html> (rather than document) on IE to avoid memory leaks, but document on other browsers because
+ // (at least for FF) the focus event doesn't fire on <html> or <body>.
+ var doc = dojo.isIE ? targetWindow.document.documentElement : targetWindow.document;
+ if(doc){
+ if(dojo.isIE){
+ targetWindow.document.body.attachEvent('onmousedown', mousedownListener);
+ var activateListener = function(evt){
+ // IE reports that nodes like <body> have gotten focus, even though they have tabIndex=-1,
+ // Should consider those more like a mouse-click than a focus....
+ if(evt.srcElement.tagName.toLowerCase() != "#document" &&
+ dijit.isTabNavigable(evt.srcElement)){
+ dijit._onFocusNode(effectiveNode || evt.srcElement);
+ }else{
+ dijit._onTouchNode(effectiveNode || evt.srcElement);
+ }
+ };
+ doc.attachEvent('onactivate', activateListener);
+ var deactivateListener = function(evt){
+ dijit._onBlurNode(effectiveNode || evt.srcElement);
+ };
+ doc.attachEvent('ondeactivate', deactivateListener);
+
+ return function(){
+ targetWindow.document.detachEvent('onmousedown', mousedownListener);
+ doc.detachEvent('onactivate', activateListener);
+ doc.detachEvent('ondeactivate', deactivateListener);
+ doc = null; // prevent memory leak (apparent circular reference via closure)
+ };
+ }else{
+ doc.body.addEventListener('mousedown', mousedownListener, true);
+ var focusListener = function(evt){
+ dijit._onFocusNode(effectiveNode || evt.target);
+ };
+ doc.addEventListener('focus', focusListener, true);
+ var blurListener = function(evt){
+ dijit._onBlurNode(effectiveNode || evt.target);
+ };
+ doc.addEventListener('blur', blurListener, true);
+
+ return function(){
+ doc.body.removeEventListener('mousedown', mousedownListener, true);
+ doc.removeEventListener('focus', focusListener, true);
+ doc.removeEventListener('blur', blurListener, true);
+ doc = null; // prevent memory leak (apparent circular reference via closure)
+ };
+ }
+ }
+ },
+
+ unregisterWin: function(/*Handle*/ handle){
+ // summary:
+ // Unregisters listeners on the specified window (either the main
+ // window or an iframe's window) according to handle returned from registerWin().
+ // After calling be sure to delete or null out the handle itself.
+
+ // Currently our handle is actually a function
+ handle && handle();
+ },
+
+ _onBlurNode: function(/*DomNode*/ node){
+ // summary:
+ // Called when focus leaves a node.
+ // Usually ignored, _unless_ it *isn't* follwed by touching another node,
+ // which indicates that we tabbed off the last field on the page,
+ // in which case every widget is marked inactive
+ dijit._prevFocus = dijit._curFocus;
+ dijit._curFocus = null;
+
+ if(dijit._justMouseDowned){
+ // the mouse down caused a new widget to be marked as active; this blur event
+ // is coming late, so ignore it.
+ return;
+ }
+
+ // if the blur event isn't followed by a focus event then mark all widgets as inactive.
+ if(dijit._clearActiveWidgetsTimer){
+ clearTimeout(dijit._clearActiveWidgetsTimer);
+ }
+ dijit._clearActiveWidgetsTimer = setTimeout(function(){
+ delete dijit._clearActiveWidgetsTimer;
+ dijit._setStack([]);
+ dijit._prevFocus = null;
+ }, 100);
+ },
+
+ _onTouchNode: function(/*DomNode*/ node, /*String*/ by){
+ // summary:
+ // Callback when node is focused or mouse-downed
+ // node:
+ // The node that was touched.
+ // by:
+ // "mouse" if the focus/touch was caused by a mouse down event
+
+ // ignore the recent blurNode event
+ if(dijit._clearActiveWidgetsTimer){
+ clearTimeout(dijit._clearActiveWidgetsTimer);
+ delete dijit._clearActiveWidgetsTimer;
+ }
+
+ // compute stack of active widgets (ex: ComboButton --> Menu --> MenuItem)
+ var newStack=[];
+ try{
+ while(node){
+ var popupParent = dojo.attr(node, "dijitPopupParent");
+ if(popupParent){
+ node=dijit.byId(popupParent).domNode;
+ }else if(node.tagName && node.tagName.toLowerCase() == "body"){
+ // is this the root of the document or just the root of an iframe?
+ if(node === dojo.body()){
+ // node is the root of the main document
+ break;
+ }
+ // otherwise, find the iframe this node refers to (can't access it via parentNode,
+ // need to do this trick instead). window.frameElement is supported in IE/FF/Webkit
+ node=dojo.window.get(node.ownerDocument).frameElement;
+ }else{
+ // if this node is the root node of a widget, then add widget id to stack,
+ // except ignore clicks on disabled widgets (actually focusing a disabled widget still works,
+ // to support MenuItem)
+ var id = node.getAttribute && node.getAttribute("widgetId"),
+ widget = id && dijit.byId(id);
+ if(widget && !(by == "mouse" && widget.get("disabled"))){
+ newStack.unshift(id);
+ }
+ node=node.parentNode;
+ }
+ }
+ }catch(e){ /* squelch */ }
+
+ dijit._setStack(newStack, by);
+ },
+
+ _onFocusNode: function(/*DomNode*/ node){
+ // summary:
+ // Callback when node is focused
+
+ if(!node){
+ return;
+ }
+
+ if(node.nodeType == 9){
+ // Ignore focus events on the document itself. This is here so that
+ // (for example) clicking the up/down arrows of a spinner
+ // (which don't get focus) won't cause that widget to blur. (FF issue)
+ return;
+ }
+
+ dijit._onTouchNode(node);
+
+ if(node == dijit._curFocus){ return; }
+ if(dijit._curFocus){
+ dijit._prevFocus = dijit._curFocus;
+ }
+ dijit._curFocus = node;
+ dojo.publish("focusNode", [node]);
+ },
+
+ _setStack: function(/*String[]*/ newStack, /*String*/ by){
+ // summary:
+ // The stack of active widgets has changed. Send out appropriate events and records new stack.
+ // newStack:
+ // array of widget id's, starting from the top (outermost) widget
+ // by:
+ // "mouse" if the focus/touch was caused by a mouse down event
+
+ var oldStack = dijit._activeStack;
+ dijit._activeStack = newStack;
+
+ // compare old stack to new stack to see how many elements they have in common
+ for(var nCommon=0; nCommon<Math.min(oldStack.length, newStack.length); nCommon++){
+ if(oldStack[nCommon] != newStack[nCommon]){
+ break;
+ }
+ }
+
+ var widget;
+ // for all elements that have gone out of focus, send blur event
+ for(var i=oldStack.length-1; i>=nCommon; i--){
+ widget = dijit.byId(oldStack[i]);
+ if(widget){
+ widget._focused = false;
+ widget.set("focused", false);
+ widget._hasBeenBlurred = true;
+ if(widget._onBlur){
+ widget._onBlur(by);
+ }
+ dojo.publish("widgetBlur", [widget, by]);
+ }
+ }
+
+ // for all element that have come into focus, send focus event
+ for(i=nCommon; i<newStack.length; i++){
+ widget = dijit.byId(newStack[i]);
+ if(widget){
+ widget._focused = true;
+ widget.set("focused", true);
+ if(widget._onFocus){
+ widget._onFocus(by);
+ }
+ dojo.publish("widgetFocus", [widget, by]);
+ }
+ }
+ }
+});
+
+// register top window and all the iframes it contains
+dojo.addOnLoad(function(){
+ var handle = dijit.registerWin(window);
+ if(dojo.isIE){
+ dojo.addOnWindowUnload(function(){
+ dijit.unregisterWin(handle);
+ handle = null;
+ })
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojo.AdapterRegistry"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.AdapterRegistry"] = true;
+dojo.provide("dojo.AdapterRegistry");
+
+
+
+dojo.AdapterRegistry = function(/*Boolean?*/ returnWrappers){
+ // summary:
+ // A registry to make contextual calling/searching easier.
+ // description:
+ // Objects of this class keep list of arrays in the form [name, check,
+ // wrap, directReturn] that are used to determine what the contextual
+ // result of a set of checked arguments is. All check/wrap functions
+ // in this registry should be of the same arity.
+ // example:
+ // | // create a new registry
+ // | var reg = new dojo.AdapterRegistry();
+ // | reg.register("handleString",
+ // | dojo.isString,
+ // | function(str){
+ // | // do something with the string here
+ // | }
+ // | );
+ // | reg.register("handleArr",
+ // | dojo.isArray,
+ // | function(arr){
+ // | // do something with the array here
+ // | }
+ // | );
+ // |
+ // | // now we can pass reg.match() *either* an array or a string and
+ // | // the value we pass will get handled by the right function
+ // | reg.match("someValue"); // will call the first function
+ // | reg.match(["someValue"]); // will call the second
+
+ this.pairs = [];
+ this.returnWrappers = returnWrappers || false; // Boolean
+};
+
+dojo.extend(dojo.AdapterRegistry, {
+ register: function(/*String*/ name, /*Function*/ check, /*Function*/ wrap, /*Boolean?*/ directReturn, /*Boolean?*/ override){
+ // summary:
+ // register a check function to determine if the wrap function or
+ // object gets selected
+ // name:
+ // a way to identify this matcher.
+ // check:
+ // a function that arguments are passed to from the adapter's
+ // match() function. The check function should return true if the
+ // given arguments are appropriate for the wrap function.
+ // directReturn:
+ // If directReturn is true, the value passed in for wrap will be
+ // returned instead of being called. Alternately, the
+ // AdapterRegistry can be set globally to "return not call" using
+ // the returnWrappers property. Either way, this behavior allows
+ // the registry to act as a "search" function instead of a
+ // function interception library.
+ // override:
+ // If override is given and true, the check function will be given
+ // highest priority. Otherwise, it will be the lowest priority
+ // adapter.
+ this.pairs[((override) ? "unshift" : "push")]([name, check, wrap, directReturn]);
+ },
+
+ match: function(/* ... */){
+ // summary:
+ // Find an adapter for the given arguments. If no suitable adapter
+ // is found, throws an exception. match() accepts any number of
+ // arguments, all of which are passed to all matching functions
+ // from the registered pairs.
+ for(var i = 0; i < this.pairs.length; i++){
+ var pair = this.pairs[i];
+ if(pair[1].apply(this, arguments)){
+ if((pair[3])||(this.returnWrappers)){
+ return pair[2];
+ }else{
+ return pair[2].apply(this, arguments);
+ }
+ }
+ }
+ throw new Error("No match found");
+ },
+
+ unregister: function(name){
+ // summary: Remove a named adapter from the registry
+
+ // FIXME: this is kind of a dumb way to handle this. On a large
+ // registry this will be slow-ish and we can use the name as a lookup
+ // should we choose to trade memory for speed.
+ for(var i = 0; i < this.pairs.length; i++){
+ var pair = this.pairs[i];
+ if(pair[0] == name){
+ this.pairs.splice(i, 1);
+ return true;
+ }
+ }
+ return false;
+ }
+});
+
+}
+
+if(!dojo._hasResource["dijit._base.place"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.place"] = true;
+dojo.provide("dijit._base.place");
+
+
+
+
+
+dijit.getViewport = function(){
+ // summary:
+ // Returns the dimensions and scroll position of the viewable area of a browser window
+
+ return dojo.window.getBox();
+};
+
+/*=====
+dijit.__Position = function(){
+ // x: Integer
+ // horizontal coordinate in pixels, relative to document body
+ // y: Integer
+ // vertical coordinate in pixels, relative to document body
+
+ thix.x = x;
+ this.y = y;
+}
+=====*/
+
+
+dijit.placeOnScreen = function(
+ /* DomNode */ node,
+ /* dijit.__Position */ pos,
+ /* String[] */ corners,
+ /* dijit.__Position? */ padding){
+ // summary:
+ // Positions one of the node's corners at specified position
+ // such that node is fully visible in viewport.
+ // description:
+ // NOTE: node is assumed to be absolutely or relatively positioned.
+ // pos:
+ // Object like {x: 10, y: 20}
+ // corners:
+ // Array of Strings representing order to try corners in, like ["TR", "BL"].
+ // Possible values are:
+ // * "BL" - bottom left
+ // * "BR" - bottom right
+ // * "TL" - top left
+ // * "TR" - top right
+ // padding:
+ // set padding to put some buffer around the element you want to position.
+ // example:
+ // Try to place node's top right corner at (10,20).
+ // If that makes node go (partially) off screen, then try placing
+ // bottom left corner at (10,20).
+ // | placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])
+
+ var choices = dojo.map(corners, function(corner){
+ var c = { corner: corner, pos: {x:pos.x,y:pos.y} };
+ if(padding){
+ c.pos.x += corner.charAt(1) == 'L' ? padding.x : -padding.x;
+ c.pos.y += corner.charAt(0) == 'T' ? padding.y : -padding.y;
+ }
+ return c;
+ });
+
+ return dijit._place(node, choices);
+}
+
+dijit._place = function(/*DomNode*/ node, choices, layoutNode, /*Object*/ aroundNodeCoords){
+ // summary:
+ // Given a list of spots to put node, put it at the first spot where it fits,
+ // of if it doesn't fit anywhere then the place with the least overflow
+ // choices: Array
+ // Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} }
+ // Above example says to put the top-left corner of the node at (10,20)
+ // layoutNode: Function(node, aroundNodeCorner, nodeCorner, size)
+ // for things like tooltip, they are displayed differently (and have different dimensions)
+ // based on their orientation relative to the parent. This adjusts the popup based on orientation.
+ // It also passes in the available size for the popup, which is useful for tooltips to
+ // tell them that their width is limited to a certain amount. layoutNode() may return a value expressing
+ // how much the popup had to be modified to fit into the available space. This is used to determine
+ // what the best placement is.
+ // aroundNodeCoords: Object
+ // Size of aroundNode, ex: {w: 200, h: 50}
+
+ // get {x: 10, y: 10, w: 100, h:100} type obj representing position of
+ // viewport over document
+ var view = dojo.window.getBox();
+
+ // This won't work if the node is inside a <div style="position: relative">,
+ // so reattach it to dojo.doc.body. (Otherwise, the positioning will be wrong
+ // and also it might get cutoff)
+ if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){
+ dojo.body().appendChild(node);
+ }
+
+ var best = null;
+ dojo.some(choices, function(choice){
+ var corner = choice.corner;
+ var pos = choice.pos;
+ var overflow = 0;
+
+ // calculate amount of space available given specified position of node
+ var spaceAvailable = {
+ w: corner.charAt(1) == 'L' ? (view.l + view.w) - pos.x : pos.x - view.l,
+ h: corner.charAt(1) == 'T' ? (view.t + view.h) - pos.y : pos.y - view.t
+ };
+
+ // configure node to be displayed in given position relative to button
+ // (need to do this in order to get an accurate size for the node, because
+ // a tooltip's size changes based on position, due to triangle)
+ if(layoutNode){
+ var res = layoutNode(node, choice.aroundCorner, corner, spaceAvailable, aroundNodeCoords);
+ overflow = typeof res == "undefined" ? 0 : res;
+ }
+
+ // get node's size
+ var style = node.style;
+ var oldDisplay = style.display;
+ var oldVis = style.visibility;
+ style.visibility = "hidden";
+ style.display = "";
+ var mb = dojo.marginBox(node);
+ style.display = oldDisplay;
+ style.visibility = oldVis;
+
+ // coordinates and size of node with specified corner placed at pos,
+ // and clipped by viewport
+ var startX = Math.max(view.l, corner.charAt(1) == 'L' ? pos.x : (pos.x - mb.w)),
+ startY = Math.max(view.t, corner.charAt(0) == 'T' ? pos.y : (pos.y - mb.h)),
+ endX = Math.min(view.l + view.w, corner.charAt(1) == 'L' ? (startX + mb.w) : pos.x),
+ endY = Math.min(view.t + view.h, corner.charAt(0) == 'T' ? (startY + mb.h) : pos.y),
+ width = endX - startX,
+ height = endY - startY;
+
+ overflow += (mb.w - width) + (mb.h - height);
+
+ if(best == null || overflow < best.overflow){
+ best = {
+ corner: corner,
+ aroundCorner: choice.aroundCorner,
+ x: startX,
+ y: startY,
+ w: width,
+ h: height,
+ overflow: overflow,
+ spaceAvailable: spaceAvailable
+ };
+ }
+
+ return !overflow;
+ });
+
+ // In case the best position is not the last one we checked, need to call
+ // layoutNode() again.
+ if(best.overflow && layoutNode){
+ layoutNode(node, best.aroundCorner, best.corner, best.spaceAvailable, aroundNodeCoords);
+ }
+
+ // And then position the node. Do this last, after the layoutNode() above
+ // has sized the node, due to browser quirks when the viewport is scrolled
+ // (specifically that a Tooltip will shrink to fit as though the window was
+ // scrolled to the left).
+ //
+ // In RTL mode, set style.right rather than style.left so in the common case,
+ // window resizes move the popup along with the aroundNode.
+ var l = dojo._isBodyLtr(),
+ s = node.style;
+ s.top = best.y + "px";
+ s[l ? "left" : "right"] = (l ? best.x : view.w - best.x - best.w) + "px";
+
+ return best;
+}
+
+dijit.placeOnScreenAroundNode = function(
+ /* DomNode */ node,
+ /* DomNode */ aroundNode,
+ /* Object */ aroundCorners,
+ /* Function? */ layoutNode){
+
+ // summary:
+ // Position node adjacent or kitty-corner to aroundNode
+ // such that it's fully visible in viewport.
+ //
+ // description:
+ // Place node such that corner of node touches a corner of
+ // aroundNode, and that node is fully visible.
+ //
+ // aroundCorners:
+ // Ordered list of pairs of corners to try matching up.
+ // Each pair of corners is represented as a key/value in the hash,
+ // where the key corresponds to the aroundNode's corner, and
+ // the value corresponds to the node's corner:
+ //
+ // | { aroundNodeCorner1: nodeCorner1, aroundNodeCorner2: nodeCorner2, ...}
+ //
+ // The following strings are used to represent the four corners:
+ // * "BL" - bottom left
+ // * "BR" - bottom right
+ // * "TL" - top left
+ // * "TR" - top right
+ //
+ // layoutNode: Function(node, aroundNodeCorner, nodeCorner)
+ // For things like tooltip, they are displayed differently (and have different dimensions)
+ // based on their orientation relative to the parent. This adjusts the popup based on orientation.
+ //
+ // example:
+ // | dijit.placeOnScreenAroundNode(node, aroundNode, {'BL':'TL', 'TR':'BR'});
+ // This will try to position node such that node's top-left corner is at the same position
+ // as the bottom left corner of the aroundNode (ie, put node below
+ // aroundNode, with left edges aligned). If that fails it will try to put
+ // the bottom-right corner of node where the top right corner of aroundNode is
+ // (ie, put node above aroundNode, with right edges aligned)
+ //
+
+ // get coordinates of aroundNode
+ aroundNode = dojo.byId(aroundNode);
+ var aroundNodePos = dojo.position(aroundNode, true);
+
+ // place the node around the calculated rectangle
+ return dijit._placeOnScreenAroundRect(node,
+ aroundNodePos.x, aroundNodePos.y, aroundNodePos.w, aroundNodePos.h, // rectangle
+ aroundCorners, layoutNode);
+};
+
+/*=====
+dijit.__Rectangle = function(){
+ // x: Integer
+ // horizontal offset in pixels, relative to document body
+ // y: Integer
+ // vertical offset in pixels, relative to document body
+ // width: Integer
+ // width in pixels
+ // height: Integer
+ // height in pixels
+
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+}
+=====*/
+
+
+dijit.placeOnScreenAroundRectangle = function(
+ /* DomNode */ node,
+ /* dijit.__Rectangle */ aroundRect,
+ /* Object */ aroundCorners,
+ /* Function */ layoutNode){
+
+ // summary:
+ // Like dijit.placeOnScreenAroundNode(), except that the "around"
+ // parameter is an arbitrary rectangle on the screen (x, y, width, height)
+ // instead of a dom node.
+
+ return dijit._placeOnScreenAroundRect(node,
+ aroundRect.x, aroundRect.y, aroundRect.width, aroundRect.height, // rectangle
+ aroundCorners, layoutNode);
+};
+
+dijit._placeOnScreenAroundRect = function(
+ /* DomNode */ node,
+ /* Number */ x,
+ /* Number */ y,
+ /* Number */ width,
+ /* Number */ height,
+ /* Object */ aroundCorners,
+ /* Function */ layoutNode){
+
+ // summary:
+ // Like dijit.placeOnScreenAroundNode(), except it accepts coordinates
+ // of a rectangle to place node adjacent to.
+
+ // TODO: combine with placeOnScreenAroundRectangle()
+
+ // Generate list of possible positions for node
+ var choices = [];
+ for(var nodeCorner in aroundCorners){
+ choices.push( {
+ aroundCorner: nodeCorner,
+ corner: aroundCorners[nodeCorner],
+ pos: {
+ x: x + (nodeCorner.charAt(1) == 'L' ? 0 : width),
+ y: y + (nodeCorner.charAt(0) == 'T' ? 0 : height)
+ }
+ });
+ }
+
+ return dijit._place(node, choices, layoutNode, {w: width, h: height});
+};
+
+dijit.placementRegistry= new dojo.AdapterRegistry();
+dijit.placementRegistry.register("node",
+ function(n, x){
+ return typeof x == "object" &&
+ typeof x.offsetWidth != "undefined" && typeof x.offsetHeight != "undefined";
+ },
+ dijit.placeOnScreenAroundNode);
+dijit.placementRegistry.register("rect",
+ function(n, x){
+ return typeof x == "object" &&
+ "x" in x && "y" in x && "width" in x && "height" in x;
+ },
+ dijit.placeOnScreenAroundRectangle);
+
+dijit.placeOnScreenAroundElement = function(
+ /* DomNode */ node,
+ /* Object */ aroundElement,
+ /* Object */ aroundCorners,
+ /* Function */ layoutNode){
+
+ // summary:
+ // Like dijit.placeOnScreenAroundNode(), except it accepts an arbitrary object
+ // for the "around" argument and finds a proper processor to place a node.
+
+ return dijit.placementRegistry.match.apply(dijit.placementRegistry, arguments);
+};
+
+dijit.getPopupAroundAlignment = function(/*Array*/ position, /*Boolean*/ leftToRight){
+ // summary:
+ // Transforms the passed array of preferred positions into a format suitable for passing as the aroundCorners argument to dijit.placeOnScreenAroundElement.
+ //
+ // position: String[]
+ // This variable controls the position of the drop down.
+ // It's an array of strings with the following values:
+ //
+ // * before: places drop down to the left of the target node/widget, or to the right in
+ // the case of RTL scripts like Hebrew and Arabic
+ // * after: places drop down to the right of the target node/widget, or to the left in
+ // the case of RTL scripts like Hebrew and Arabic
+ // * above: drop down goes above target node
+ // * below: drop down goes below target node
+ //
+ // The list is positions is tried, in order, until a position is found where the drop down fits
+ // within the viewport.
+ //
+ // leftToRight: Boolean
+ // Whether the popup will be displaying in leftToRight mode.
+ //
+ var align = {};
+ dojo.forEach(position, function(pos){
+ switch(pos){
+ case "after":
+ align[leftToRight ? "BR" : "BL"] = leftToRight ? "BL" : "BR";
+ break;
+ case "before":
+ align[leftToRight ? "BL" : "BR"] = leftToRight ? "BR" : "BL";
+ break;
+ case "below-alt":
+ leftToRight = !leftToRight;
+ // fall through
+ case "below":
+ // first try to align left borders, next try to align right borders (or reverse for RTL mode)
+ align[leftToRight ? "BL" : "BR"] = leftToRight ? "TL" : "TR";
+ align[leftToRight ? "BR" : "BL"] = leftToRight ? "TR" : "TL";
+ break;
+ case "above-alt":
+ leftToRight = !leftToRight;
+ // fall through
+ case "above":
+ default:
+ // first try to align left borders, next try to align right borders (or reverse for RTL mode)
+ align[leftToRight ? "TL" : "TR"] = leftToRight ? "BL" : "BR";
+ align[leftToRight ? "TR" : "TL"] = leftToRight ? "BR" : "BL";
+ break;
+ }
+ });
+ return align;
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.window"] = true;
+dojo.provide("dijit._base.window");
+
+
+
+
+dijit.getDocumentWindow = function(doc){
+ return dojo.window.get(doc);
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.popup"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.popup"] = true;
+dojo.provide("dijit._base.popup");
+
+
+
+
+
+
+/*=====
+dijit.popup.__OpenArgs = function(){
+ // popup: Widget
+ // widget to display
+ // parent: Widget
+ // the button etc. that is displaying this popup
+ // around: DomNode
+ // DOM node (typically a button); place popup relative to this node. (Specify this *or* "x" and "y" parameters.)
+ // x: Integer
+ // Absolute horizontal position (in pixels) to place node at. (Specify this *or* "around" parameter.)
+ // y: Integer
+ // Absolute vertical position (in pixels) to place node at. (Specify this *or* "around" parameter.)
+ // orient: Object|String
+ // When the around parameter is specified, orient should be an
+ // ordered list of tuples of the form (around-node-corner, popup-node-corner).
+ // dijit.popup.open() tries to position the popup according to each tuple in the list, in order,
+ // until the popup appears fully within the viewport.
+ //
+ // The default value is {BL:'TL', TL:'BL'}, which represents a list of two tuples:
+ // 1. (BL, TL)
+ // 2. (TL, BL)
+ // where BL means "bottom left" and "TL" means "top left".
+ // So by default, it first tries putting the popup below the around node, left-aligning them,
+ // and then tries to put it above the around node, still left-aligning them. Note that the
+ // default is horizontally reversed when in RTL mode.
+ //
+ // When an (x,y) position is specified rather than an around node, orient is either
+ // "R" or "L". R (for right) means that it tries to put the popup to the right of the mouse,
+ // specifically positioning the popup's top-right corner at the mouse position, and if that doesn't
+ // fit in the viewport, then it tries, in order, the bottom-right corner, the top left corner,
+ // and the top-right corner.
+ // onCancel: Function
+ // callback when user has canceled the popup by
+ // 1. hitting ESC or
+ // 2. by using the popup widget's proprietary cancel mechanism (like a cancel button in a dialog);
+ // i.e. whenever popupWidget.onCancel() is called, args.onCancel is called
+ // onClose: Function
+ // callback whenever this popup is closed
+ // onExecute: Function
+ // callback when user "executed" on the popup/sub-popup by selecting a menu choice, etc. (top menu only)
+ // padding: dijit.__Position
+ // adding a buffer around the opening position. This is only useful when around is not set.
+ this.popup = popup;
+ this.parent = parent;
+ this.around = around;
+ this.x = x;
+ this.y = y;
+ this.orient = orient;
+ this.onCancel = onCancel;
+ this.onClose = onClose;
+ this.onExecute = onExecute;
+ this.padding = padding;
+}
+=====*/
+
+dijit.popup = {
+ // summary:
+ // This singleton is used to show/hide widgets as popups.
+
+ // _stack: dijit._Widget[]
+ // Stack of currently popped up widgets.
+ // (someone opened _stack[0], and then it opened _stack[1], etc.)
+ _stack: [],
+
+ // _beginZIndex: Number
+ // Z-index of the first popup. (If first popup opens other
+ // popups they get a higher z-index.)
+ _beginZIndex: 1000,
+
+ _idGen: 1,
+
+ _createWrapper: function(/*Widget || DomNode*/ widget){
+ // summary:
+ // Initialization for widgets that will be used as popups.
+ // Puts widget inside a wrapper DIV (if not already in one),
+ // and returns pointer to that wrapper DIV.
+
+ var wrapper = widget.declaredClass ? widget._popupWrapper : (dojo.hasClass(widget.parentNode, "dijitPopup") && widget.parentNode),
+ node = widget.domNode || widget;
+
+ if(!wrapper){
+ // Create wrapper <div> for when this widget [in the future] will be used as a popup.
+ // This is done early because of IE bugs where creating/moving DOM nodes causes focus
+ // to go wonky, see tests/robot/Toolbar.html to reproduce
+ wrapper = dojo.create("div",{
+ "class":"dijitPopup",
+ style:{ display: "none"},
+ role: "presentation"
+ }, dojo.body());
+ wrapper.appendChild(node);
+
+ var s = node.style;
+ s.display = "";
+ s.visibility = "";
+ s.position = "";
+ s.top = "0px";
+
+ if(widget.declaredClass){ // TODO: in 2.0 change signature to always take widget, then remove if()
+ widget._popupWrapper = wrapper;
+ dojo.connect(widget, "destroy", function(){
+ dojo.destroy(wrapper);
+ delete widget._popupWrapper;
+ });
+ }
+ }
+
+ return wrapper;
+ },
+
+ moveOffScreen: function(/*Widget || DomNode*/ widget){
+ // summary:
+ // Moves the popup widget off-screen.
+ // Do not use this method to hide popups when not in use, because
+ // that will create an accessibility issue: the offscreen popup is
+ // still in the tabbing order.
+
+ // Create wrapper if not already there
+ var wrapper = this._createWrapper(widget);
+
+ dojo.style(wrapper, {
+ visibility: "hidden",
+ top: "-9999px", // prevent transient scrollbar causing misalign (#5776), and initial flash in upper left (#10111)
+ display: ""
+ });
+ },
+
+ hide: function(/*dijit._Widget*/ widget){
+ // summary:
+ // Hide this popup widget (until it is ready to be shown).
+ // Initialization for widgets that will be used as popups
+ //
+ // Also puts widget inside a wrapper DIV (if not already in one)
+ //
+ // If popup widget needs to layout it should
+ // do so when it is made visible, and popup._onShow() is called.
+
+ // Create wrapper if not already there
+ var wrapper = this._createWrapper(widget);
+
+ dojo.style(wrapper, "display", "none");
+ },
+
+ getTopPopup: function(){
+ // summary:
+ // Compute the closest ancestor popup that's *not* a child of another popup.
+ // Ex: For a TooltipDialog with a button that spawns a tree of menus, find the popup of the button.
+ var stack = this._stack;
+ for(var pi=stack.length-1; pi > 0 && stack[pi].parent === stack[pi-1].widget; pi--){
+ /* do nothing, just trying to get right value for pi */
+ }
+ return stack[pi];
+ },
+
+ open: function(/*dijit.popup.__OpenArgs*/ args){
+ // summary:
+ // Popup the widget at the specified position
+ //
+ // example:
+ // opening at the mouse position
+ // | dijit.popup.open({popup: menuWidget, x: evt.pageX, y: evt.pageY});
+ //
+ // example:
+ // opening the widget as a dropdown
+ // | dijit.popup.open({parent: this, popup: menuWidget, around: this.domNode, onClose: function(){...}});
+ //
+ // Note that whatever widget called dijit.popup.open() should also listen to its own _onBlur callback
+ // (fired from _base/focus.js) to know that focus has moved somewhere else and thus the popup should be closed.
+
+ var stack = this._stack,
+ widget = args.popup,
+ orient = args.orient || (
+ (args.parent ? args.parent.isLeftToRight() : dojo._isBodyLtr()) ?
+ {'BL':'TL', 'BR':'TR', 'TL':'BL', 'TR':'BR'} :
+ {'BR':'TR', 'BL':'TL', 'TR':'BR', 'TL':'BL'}
+ ),
+ around = args.around,
+ id = (args.around && args.around.id) ? (args.around.id+"_dropdown") : ("popup_"+this._idGen++);
+
+ // If we are opening a new popup that isn't a child of a currently opened popup, then
+ // close currently opened popup(s). This should happen automatically when the old popups
+ // gets the _onBlur() event, except that the _onBlur() event isn't reliable on IE, see [22198].
+ while(stack.length && (!args.parent || !dojo.isDescendant(args.parent.domNode, stack[stack.length-1].widget.domNode))){
+ dijit.popup.close(stack[stack.length-1].widget);
+ }
+
+ // Get pointer to popup wrapper, and create wrapper if it doesn't exist
+ var wrapper = this._createWrapper(widget);
+
+
+ dojo.attr(wrapper, {
+ id: id,
+ style: {
+ zIndex: this._beginZIndex + stack.length
+ },
+ "class": "dijitPopup " + (widget.baseClass || widget["class"] || "").split(" ")[0] +"Popup",
+ dijitPopupParent: args.parent ? args.parent.id : ""
+ });
+
+ if(dojo.isIE || dojo.isMoz){
+ if(!widget.bgIframe){
+ // setting widget.bgIframe triggers cleanup in _Widget.destroy()
+ widget.bgIframe = new dijit.BackgroundIframe(wrapper);
+ }
+ }
+
+ // position the wrapper node and make it visible
+ var best = around ?
+ dijit.placeOnScreenAroundElement(wrapper, around, orient, widget.orient ? dojo.hitch(widget, "orient") : null) :
+ dijit.placeOnScreen(wrapper, args, orient == 'R' ? ['TR','BR','TL','BL'] : ['TL','BL','TR','BR'], args.padding);
+
+ wrapper.style.display = "";
+ wrapper.style.visibility = "visible";
+ widget.domNode.style.visibility = "visible"; // counteract effects from _HasDropDown
+
+ var handlers = [];
+
+ // provide default escape and tab key handling
+ // (this will work for any widget, not just menu)
+ handlers.push(dojo.connect(wrapper, "onkeypress", this, function(evt){
+ if(evt.charOrCode == dojo.keys.ESCAPE && args.onCancel){
+ dojo.stopEvent(evt);
+ args.onCancel();
+ }else if(evt.charOrCode === dojo.keys.TAB){
+ dojo.stopEvent(evt);
+ var topPopup = this.getTopPopup();
+ if(topPopup && topPopup.onCancel){
+ topPopup.onCancel();
+ }
+ }
+ }));
+
+ // watch for cancel/execute events on the popup and notify the caller
+ // (for a menu, "execute" means clicking an item)
+ if(widget.onCancel){
+ handlers.push(dojo.connect(widget, "onCancel", args.onCancel));
+ }
+
+ handlers.push(dojo.connect(widget, widget.onExecute ? "onExecute" : "onChange", this, function(){
+ var topPopup = this.getTopPopup();
+ if(topPopup && topPopup.onExecute){
+ topPopup.onExecute();
+ }
+ }));
+
+ stack.push({
+ widget: widget,
+ parent: args.parent,
+ onExecute: args.onExecute,
+ onCancel: args.onCancel,
+ onClose: args.onClose,
+ handlers: handlers
+ });
+
+ if(widget.onOpen){
+ // TODO: in 2.0 standardize onShow() (used by StackContainer) and onOpen() (used here)
+ widget.onOpen(best);
+ }
+
+ return best;
+ },
+
+ close: function(/*dijit._Widget?*/ popup){
+ // summary:
+ // Close specified popup and any popups that it parented.
+ // If no popup is specified, closes all popups.
+
+ var stack = this._stack;
+
+ // Basically work backwards from the top of the stack closing popups
+ // until we hit the specified popup, but IIRC there was some issue where closing
+ // a popup would cause others to close too. Thus if we are trying to close B in [A,B,C]
+ // closing C might close B indirectly and then the while() condition will run where stack==[A]...
+ // so the while condition is constructed defensively.
+ while((popup && dojo.some(stack, function(elem){return elem.widget == popup;})) ||
+ (!popup && stack.length)){
+ var top = stack.pop(),
+ widget = top.widget,
+ onClose = top.onClose;
+
+ if(widget.onClose){
+ // TODO: in 2.0 standardize onHide() (used by StackContainer) and onClose() (used here)
+ widget.onClose();
+ }
+ dojo.forEach(top.handlers, dojo.disconnect);
+
+ // Hide the widget and it's wrapper unless it has already been destroyed in above onClose() etc.
+ if(widget && widget.domNode){
+ this.hide(widget);
+ }
+
+ if(onClose){
+ onClose();
+ }
+ }
+ }
+};
+
+// TODO: remove dijit._frames, it isn't being used much, since popups never release their
+// iframes (see [22236])
+dijit._frames = new function(){
+ // summary:
+ // cache of iframes
+
+ var queue = [];
+
+ this.pop = function(){
+ var iframe;
+ if(queue.length){
+ iframe = queue.pop();
+ iframe.style.display="";
+ }else{
+ if(dojo.isIE < 9){
+ var burl = dojo.config["dojoBlankHtmlUrl"] || (dojo.moduleUrl("dojo", "resources/blank.html")+"") || "javascript:\"\"";
+ var html="<iframe src='" + burl + "'"
+ + " style='position: absolute; left: 0px; top: 0px;"
+ + "z-index: -1; filter:Alpha(Opacity=\"0\");'>";
+ iframe = dojo.doc.createElement(html);
+ }else{
+ iframe = dojo.create("iframe");
+ iframe.src = 'javascript:""';
+ iframe.className = "dijitBackgroundIframe";
+ dojo.style(iframe, "opacity", 0.1);
+ }
+ iframe.tabIndex = -1; // Magic to prevent iframe from getting focus on tab keypress - as style didn't work.
+ dijit.setWaiRole(iframe,"presentation");
+ }
+ return iframe;
+ };
+
+ this.push = function(iframe){
+ iframe.style.display="none";
+ queue.push(iframe);
+ }
+}();
+
+
+dijit.BackgroundIframe = function(/*DomNode*/ node){
+ // summary:
+ // For IE/FF z-index schenanigans. id attribute is required.
+ //
+ // description:
+ // new dijit.BackgroundIframe(node)
+ // Makes a background iframe as a child of node, that fills
+ // area (and position) of node
+
+ if(!node.id){ throw new Error("no id"); }
+ if(dojo.isIE || dojo.isMoz){
+ var iframe = (this.iframe = dijit._frames.pop());
+ node.appendChild(iframe);
+ if(dojo.isIE<7 || dojo.isQuirks){
+ this.resize(node);
+ this._conn = dojo.connect(node, 'onresize', this, function(){
+ this.resize(node);
+ });
+ }else{
+ dojo.style(iframe, {
+ width: '100%',
+ height: '100%'
+ });
+ }
+ }
+};
+
+dojo.extend(dijit.BackgroundIframe, {
+ resize: function(node){
+ // summary:
+ // Resize the iframe so it's the same size as node.
+ // Needed on IE6 and IE/quirks because height:100% doesn't work right.
+ if(this.iframe){
+ dojo.style(this.iframe, {
+ width: node.offsetWidth + 'px',
+ height: node.offsetHeight + 'px'
+ });
+ }
+ },
+ destroy: function(){
+ // summary:
+ // destroy the iframe
+ if(this._conn){
+ dojo.disconnect(this._conn);
+ this._conn = null;
+ }
+ if(this.iframe){
+ dijit._frames.push(this.iframe);
+ delete this.iframe;
+ }
+ }
+});
+
+}
+
+if(!dojo._hasResource["dijit._base.scroll"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.scroll"] = true;
+dojo.provide("dijit._base.scroll");
+
+
+
+
+dijit.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
+ // summary:
+ // Scroll the passed node into view, if it is not already.
+ // Deprecated, use `dojo.window.scrollIntoView` instead.
+
+ dojo.window.scrollIntoView(node, pos);
+};
+
+}
+
+if(!dojo._hasResource["dojo.uacss"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.uacss"] = true;
+dojo.provide("dojo.uacss");
+
+
+
+(function(){
+ // summary:
+ // Applies pre-set CSS classes to the top-level HTML node, based on:
+ // - browser (ex: dj_ie)
+ // - browser version (ex: dj_ie6)
+ // - box model (ex: dj_contentBox)
+ // - text direction (ex: dijitRtl)
+ //
+ // In addition, browser, browser version, and box model are
+ // combined with an RTL flag when browser text is RTL. ex: dj_ie-rtl.
+
+ var d = dojo,
+ html = d.doc.documentElement,
+ ie = d.isIE,
+ opera = d.isOpera,
+ maj = Math.floor,
+ ff = d.isFF,
+ boxModel = d.boxModel.replace(/-/,''),
+
+ classes = {
+ dj_ie: ie,
+ dj_ie6: maj(ie) == 6,
+ dj_ie7: maj(ie) == 7,
+ dj_ie8: maj(ie) == 8,
+ dj_ie9: maj(ie) == 9,
+ dj_quirks: d.isQuirks,
+ dj_iequirks: ie && d.isQuirks,
+
+ // NOTE: Opera not supported by dijit
+ dj_opera: opera,
+
+ dj_khtml: d.isKhtml,
+
+ dj_webkit: d.isWebKit,
+ dj_safari: d.isSafari,
+ dj_chrome: d.isChrome,
+
+ dj_gecko: d.isMozilla,
+ dj_ff3: maj(ff) == 3
+ }; // no dojo unsupported browsers
+
+ classes["dj_" + boxModel] = true;
+
+ // apply browser, browser version, and box model class names
+ var classStr = "";
+ for(var clz in classes){
+ if(classes[clz]){
+ classStr += clz + " ";
+ }
+ }
+ html.className = d.trim(html.className + " " + classStr);
+
+ // If RTL mode, then add dj_rtl flag plus repeat existing classes with -rtl extension.
+ // We can't run the code below until the <body> tag has loaded (so we can check for dir=rtl).
+ // Unshift() is to run sniff code before the parser.
+ dojo._loaders.unshift(function(){
+ if(!dojo._isBodyLtr()){
+ var rtlClassStr = "dj_rtl dijitRtl " + classStr.replace(/ /g, "-rtl ")
+ html.className = d.trim(html.className + " " + rtlClassStr);
+ }
+ });
+})();
+
+}
+
+if(!dojo._hasResource["dijit._base.sniff"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.sniff"] = true;
+dojo.provide("dijit._base.sniff");
+
+
+
+
+// summary:
+// Applies pre-set CSS classes to the top-level HTML node, see
+// `dojo.uacss` for details.
+//
+// Simply doing a require on this module will
+// establish this CSS. Modified version of Morris' CSS hack.
+
+}
+
+if(!dojo._hasResource["dijit._base.typematic"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.typematic"] = true;
+dojo.provide("dijit._base.typematic");
+
+
+
+dijit.typematic = {
+ // summary:
+ // These functions are used to repetitively call a user specified callback
+ // method when a specific key or mouse click over a specific DOM node is
+ // held down for a specific amount of time.
+ // Only 1 such event is allowed to occur on the browser page at 1 time.
+
+ _fireEventAndReload: function(){
+ this._timer = null;
+ this._callback(++this._count, this._node, this._evt);
+
+ // Schedule next event, timer is at most minDelay (default 10ms) to avoid
+ // browser overload (particularly avoiding starving DOH robot so it never gets to send a mouseup)
+ this._currentTimeout = Math.max(
+ this._currentTimeout < 0 ? this._initialDelay :
+ (this._subsequentDelay > 1 ? this._subsequentDelay : Math.round(this._currentTimeout * this._subsequentDelay)),
+ this._minDelay);
+ this._timer = setTimeout(dojo.hitch(this, "_fireEventAndReload"), this._currentTimeout);
+ },
+
+ trigger: function(/*Event*/ evt, /*Object*/ _this, /*DOMNode*/ node, /*Function*/ callback, /*Object*/ obj, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
+ // summary:
+ // Start a timed, repeating callback sequence.
+ // If already started, the function call is ignored.
+ // This method is not normally called by the user but can be
+ // when the normal listener code is insufficient.
+ // evt:
+ // key or mouse event object to pass to the user callback
+ // _this:
+ // pointer to the user's widget space.
+ // node:
+ // the DOM node object to pass the the callback function
+ // callback:
+ // function to call until the sequence is stopped called with 3 parameters:
+ // count:
+ // integer representing number of repeated calls (0..n) with -1 indicating the iteration has stopped
+ // node:
+ // the DOM node object passed in
+ // evt:
+ // key or mouse event object
+ // obj:
+ // user space object used to uniquely identify each typematic sequence
+ // subsequentDelay (optional):
+ // if > 1, the number of milliseconds until the 3->n events occur
+ // or else the fractional time multiplier for the next event's delay, default=0.9
+ // initialDelay (optional):
+ // the number of milliseconds until the 2nd event occurs, default=500ms
+ // minDelay (optional):
+ // the maximum delay in milliseconds for event to fire, default=10ms
+ if(obj != this._obj){
+ this.stop();
+ this._initialDelay = initialDelay || 500;
+ this._subsequentDelay = subsequentDelay || 0.90;
+ this._minDelay = minDelay || 10;
+ this._obj = obj;
+ this._evt = evt;
+ this._node = node;
+ this._currentTimeout = -1;
+ this._count = -1;
+ this._callback = dojo.hitch(_this, callback);
+ this._fireEventAndReload();
+ this._evt = dojo.mixin({faux: true}, evt);
+ }
+ },
+
+ stop: function(){
+ // summary:
+ // Stop an ongoing timed, repeating callback sequence.
+ if(this._timer){
+ clearTimeout(this._timer);
+ this._timer = null;
+ }
+ if(this._obj){
+ this._callback(-1, this._node, this._evt);
+ this._obj = null;
+ }
+ },
+
+ addKeyListener: function(/*DOMNode*/ node, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
+ // summary:
+ // Start listening for a specific typematic key.
+ // See also the trigger method for other parameters.
+ // keyObject:
+ // an object defining the key to listen for:
+ // charOrCode:
+ // the printable character (string) or keyCode (number) to listen for.
+ // keyCode:
+ // (deprecated - use charOrCode) the keyCode (number) to listen for (implies charCode = 0).
+ // charCode:
+ // (deprecated - use charOrCode) the charCode (number) to listen for.
+ // ctrlKey:
+ // desired ctrl key state to initiate the callback sequence:
+ // - pressed (true)
+ // - released (false)
+ // - either (unspecified)
+ // altKey:
+ // same as ctrlKey but for the alt key
+ // shiftKey:
+ // same as ctrlKey but for the shift key
+ // returns:
+ // an array of dojo.connect handles
+ if(keyObject.keyCode){
+ keyObject.charOrCode = keyObject.keyCode;
+ dojo.deprecated("keyCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.", "", "2.0");
+ }else if(keyObject.charCode){
+ keyObject.charOrCode = String.fromCharCode(keyObject.charCode);
+ dojo.deprecated("charCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.", "", "2.0");
+ }
+ return [
+ dojo.connect(node, "onkeypress", this, function(evt){
+ if(evt.charOrCode == keyObject.charOrCode &&
+ (keyObject.ctrlKey === undefined || keyObject.ctrlKey == evt.ctrlKey) &&
+ (keyObject.altKey === undefined || keyObject.altKey == evt.altKey) &&
+ (keyObject.metaKey === undefined || keyObject.metaKey == (evt.metaKey || false)) && // IE doesn't even set metaKey
+ (keyObject.shiftKey === undefined || keyObject.shiftKey == evt.shiftKey)){
+ dojo.stopEvent(evt);
+ dijit.typematic.trigger(evt, _this, node, callback, keyObject, subsequentDelay, initialDelay, minDelay);
+ }else if(dijit.typematic._obj == keyObject){
+ dijit.typematic.stop();
+ }
+ }),
+ dojo.connect(node, "onkeyup", this, function(evt){
+ if(dijit.typematic._obj == keyObject){
+ dijit.typematic.stop();
+ }
+ })
+ ];
+ },
+
+ addMouseListener: function(/*DOMNode*/ node, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
+ // summary:
+ // Start listening for a typematic mouse click.
+ // See the trigger method for other parameters.
+ // returns:
+ // an array of dojo.connect handles
+ var dc = dojo.connect;
+ return [
+ dc(node, "mousedown", this, function(evt){
+ dojo.stopEvent(evt);
+ dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay, minDelay);
+ }),
+ dc(node, "mouseup", this, function(evt){
+ dojo.stopEvent(evt);
+ dijit.typematic.stop();
+ }),
+ dc(node, "mouseout", this, function(evt){
+ dojo.stopEvent(evt);
+ dijit.typematic.stop();
+ }),
+ dc(node, "mousemove", this, function(evt){
+ evt.preventDefault();
+ }),
+ dc(node, "dblclick", this, function(evt){
+ dojo.stopEvent(evt);
+ if(dojo.isIE){
+ dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay, minDelay);
+ setTimeout(dojo.hitch(this, dijit.typematic.stop), 50);
+ }
+ })
+ ];
+ },
+
+ addListener: function(/*Node*/ mouseNode, /*Node*/ keyNode, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
+ // summary:
+ // Start listening for a specific typematic key and mouseclick.
+ // This is a thin wrapper to addKeyListener and addMouseListener.
+ // See the addMouseListener and addKeyListener methods for other parameters.
+ // mouseNode:
+ // the DOM node object to listen on for mouse events.
+ // keyNode:
+ // the DOM node object to listen on for key events.
+ // returns:
+ // an array of dojo.connect handles
+ return this.addKeyListener(keyNode, keyObject, _this, callback, subsequentDelay, initialDelay, minDelay).concat(
+ this.addMouseListener(mouseNode, _this, callback, subsequentDelay, initialDelay, minDelay));
+ }
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.wai"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.wai"] = true;
+dojo.provide("dijit._base.wai");
+
+
+
+dijit.wai = {
+ onload: function(){
+ // summary:
+ // Detects if we are in high-contrast mode or not
+
+ // This must be a named function and not an anonymous
+ // function, so that the widget parsing code can make sure it
+ // registers its onload function after this function.
+ // DO NOT USE "this" within this function.
+
+ // create div for testing if high contrast mode is on or images are turned off
+ var div = dojo.create("div",{
+ id: "a11yTestNode",
+ style:{
+ cssText:'border: 1px solid;'
+ + 'border-color:red green;'
+ + 'position: absolute;'
+ + 'height: 5px;'
+ + 'top: -999px;'
+ + 'background-image: url("' + (dojo.config.blankGif || dojo.moduleUrl("dojo", "resources/blank.gif")) + '");'
+ }
+ }, dojo.body());
+
+ // test it
+ var cs = dojo.getComputedStyle(div);
+ if(cs){
+ var bkImg = cs.backgroundImage;
+ var needsA11y = (cs.borderTopColor == cs.borderRightColor) || (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" ));
+ dojo[needsA11y ? "addClass" : "removeClass"](dojo.body(), "dijit_a11y");
+ if(dojo.isIE){
+ div.outerHTML = ""; // prevent mixed-content warning, see http://support.microsoft.com/kb/925014
+ }else{
+ dojo.body().removeChild(div);
+ }
+ }
+ }
+};
+
+// Test if computer is in high contrast mode.
+// Make sure the a11y test runs first, before widgets are instantiated.
+if(dojo.isIE || dojo.isMoz){ // NOTE: checking in Safari messes things up
+ dojo._loaders.unshift(dijit.wai.onload);
+}
+
+dojo.mixin(dijit, {
+ hasWaiRole: function(/*Element*/ elem, /*String?*/ role){
+ // summary:
+ // Determines if an element has a particular role.
+ // returns:
+ // True if elem has the specific role attribute and false if not.
+ // For backwards compatibility if role parameter not provided,
+ // returns true if has a role
+ var waiRole = this.getWaiRole(elem);
+ return role ? (waiRole.indexOf(role) > -1) : (waiRole.length > 0);
+ },
+
+ getWaiRole: function(/*Element*/ elem){
+ // summary:
+ // Gets the role for an element (which should be a wai role).
+ // returns:
+ // The role of elem or an empty string if elem
+ // does not have a role.
+ return dojo.trim((dojo.attr(elem, "role") || "").replace("wairole:",""));
+ },
+
+ setWaiRole: function(/*Element*/ elem, /*String*/ role){
+ // summary:
+ // Sets the role on an element.
+ // description:
+ // Replace existing role attribute with new role.
+
+ dojo.attr(elem, "role", role);
+ },
+
+ removeWaiRole: function(/*Element*/ elem, /*String*/ role){
+ // summary:
+ // Removes the specified role from an element.
+ // Removes role attribute if no specific role provided (for backwards compat.)
+
+ var roleValue = dojo.attr(elem, "role");
+ if(!roleValue){ return; }
+ if(role){
+ var t = dojo.trim((" " + roleValue + " ").replace(" " + role + " ", " "));
+ dojo.attr(elem, "role", t);
+ }else{
+ elem.removeAttribute("role");
+ }
+ },
+
+ hasWaiState: function(/*Element*/ elem, /*String*/ state){
+ // summary:
+ // Determines if an element has a given state.
+ // description:
+ // Checks for an attribute called "aria-"+state.
+ // returns:
+ // true if elem has a value for the given state and
+ // false if it does not.
+
+ return elem.hasAttribute ? elem.hasAttribute("aria-"+state) : !!elem.getAttribute("aria-"+state);
+ },
+
+ getWaiState: function(/*Element*/ elem, /*String*/ state){
+ // summary:
+ // Gets the value of a state on an element.
+ // description:
+ // Checks for an attribute called "aria-"+state.
+ // returns:
+ // The value of the requested state on elem
+ // or an empty string if elem has no value for state.
+
+ return elem.getAttribute("aria-"+state) || "";
+ },
+
+ setWaiState: function(/*Element*/ elem, /*String*/ state, /*String*/ value){
+ // summary:
+ // Sets a state on an element.
+ // description:
+ // Sets an attribute called "aria-"+state.
+
+ elem.setAttribute("aria-"+state, value);
+ },
+
+ removeWaiState: function(/*Element*/ elem, /*String*/ state){
+ // summary:
+ // Removes a state from an element.
+ // description:
+ // Sets an attribute called "aria-"+state.
+
+ elem.removeAttribute("aria-"+state);
+ }
+});
+
+}
+
+if(!dojo._hasResource["dijit._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base"] = true;
+dojo.provide("dijit._base");
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+if(!dojo._hasResource["dojo.date.stamp"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.date.stamp"] = true;
+dojo.provide("dojo.date.stamp");
+
+
+dojo.getObject("date.stamp", true, dojo);
+
+// Methods to convert dates to or from a wire (string) format using well-known conventions
+
+dojo.date.stamp.fromISOString = function(/*String*/formattedString, /*Number?*/defaultTime){
+ // summary:
+ // Returns a Date object given a string formatted according to a subset of the ISO-8601 standard.
+ //
+ // description:
+ // Accepts a string formatted according to a profile of ISO8601 as defined by
+ // [RFC3339](http://www.ietf.org/rfc/rfc3339.txt), except that partial input is allowed.
+ // Can also process dates as specified [by the W3C](http://www.w3.org/TR/NOTE-datetime)
+ // The following combinations are valid:
+ //
+ // * dates only
+ // | * yyyy
+ // | * yyyy-MM
+ // | * yyyy-MM-dd
+ // * times only, with an optional time zone appended
+ // | * THH:mm
+ // | * THH:mm:ss
+ // | * THH:mm:ss.SSS
+ // * and "datetimes" which could be any combination of the above
+ //
+ // timezones may be specified as Z (for UTC) or +/- followed by a time expression HH:mm
+ // Assumes the local time zone if not specified. Does not validate. Improperly formatted
+ // input may return null. Arguments which are out of bounds will be handled
+ // by the Date constructor (e.g. January 32nd typically gets resolved to February 1st)
+ // Only years between 100 and 9999 are supported.
+ //
+ // formattedString:
+ // A string such as 2005-06-30T08:05:00-07:00 or 2005-06-30 or T08:05:00
+ //
+ // defaultTime:
+ // Used for defaults for fields omitted in the formattedString.
+ // Uses 1970-01-01T00:00:00.0Z by default.
+
+ if(!dojo.date.stamp._isoRegExp){
+ dojo.date.stamp._isoRegExp =
+//TODO: could be more restrictive and check for 00-59, etc.
+ /^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(.\d+)?)?((?:[+-](\d{2}):(\d{2}))|Z)?)?$/;
+ }
+
+ var match = dojo.date.stamp._isoRegExp.exec(formattedString),
+ result = null;
+
+ if(match){
+ match.shift();
+ if(match[1]){match[1]--;} // Javascript Date months are 0-based
+ if(match[6]){match[6] *= 1000;} // Javascript Date expects fractional seconds as milliseconds
+
+ if(defaultTime){
+ // mix in defaultTime. Relatively expensive, so use || operators for the fast path of defaultTime === 0
+ defaultTime = new Date(defaultTime);
+ dojo.forEach(dojo.map(["FullYear", "Month", "Date", "Hours", "Minutes", "Seconds", "Milliseconds"], function(prop){
+ return defaultTime["get" + prop]();
+ }), function(value, index){
+ match[index] = match[index] || value;
+ });
+ }
+ result = new Date(match[0]||1970, match[1]||0, match[2]||1, match[3]||0, match[4]||0, match[5]||0, match[6]||0); //TODO: UTC defaults
+ if(match[0] < 100){
+ result.setFullYear(match[0] || 1970);
+ }
+
+ var offset = 0,
+ zoneSign = match[7] && match[7].charAt(0);
+ if(zoneSign != 'Z'){
+ offset = ((match[8] || 0) * 60) + (Number(match[9]) || 0);
+ if(zoneSign != '-'){ offset *= -1; }
+ }
+ if(zoneSign){
+ offset -= result.getTimezoneOffset();
+ }
+ if(offset){
+ result.setTime(result.getTime() + offset * 60000);
+ }
+ }
+
+ return result; // Date or null
+};
+
+/*=====
+ dojo.date.stamp.__Options = function(){
+ // selector: String
+ // "date" or "time" for partial formatting of the Date object.
+ // Both date and time will be formatted by default.
+ // zulu: Boolean
+ // if true, UTC/GMT is used for a timezone
+ // milliseconds: Boolean
+ // if true, output milliseconds
+ this.selector = selector;
+ this.zulu = zulu;
+ this.milliseconds = milliseconds;
+ }
+=====*/
+
+dojo.date.stamp.toISOString = function(/*Date*/dateObject, /*dojo.date.stamp.__Options?*/options){
+ // summary:
+ // Format a Date object as a string according a subset of the ISO-8601 standard
+ //
+ // description:
+ // When options.selector is omitted, output follows [RFC3339](http://www.ietf.org/rfc/rfc3339.txt)
+ // The local time zone is included as an offset from GMT, except when selector=='time' (time without a date)
+ // Does not check bounds. Only years between 100 and 9999 are supported.
+ //
+ // dateObject:
+ // A Date object
+
+ var _ = function(n){ return (n < 10) ? "0" + n : n; };
+ options = options || {};
+ var formattedDate = [],
+ getter = options.zulu ? "getUTC" : "get",
+ date = "";
+ if(options.selector != "time"){
+ var year = dateObject[getter+"FullYear"]();
+ date = ["0000".substr((year+"").length)+year, _(dateObject[getter+"Month"]()+1), _(dateObject[getter+"Date"]())].join('-');
+ }
+ formattedDate.push(date);
+ if(options.selector != "date"){
+ var time = [_(dateObject[getter+"Hours"]()), _(dateObject[getter+"Minutes"]()), _(dateObject[getter+"Seconds"]())].join(':');
+ var millis = dateObject[getter+"Milliseconds"]();
+ if(options.milliseconds){
+ time += "."+ (millis < 100 ? "0" : "") + _(millis);
+ }
+ if(options.zulu){
+ time += "Z";
+ }else if(options.selector != "time"){
+ var timezoneOffset = dateObject.getTimezoneOffset();
+ var absOffset = Math.abs(timezoneOffset);
+ time += (timezoneOffset > 0 ? "-" : "+") +
+ _(Math.floor(absOffset/60)) + ":" + _(absOffset%60);
+ }
+ formattedDate.push(time);
+ }
+ return formattedDate.join('T'); // String
+};
+
+}
+
+if(!dojo._hasResource["dojo.parser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.parser"] = true;
+dojo.provide("dojo.parser");
+
+
+
+
+new Date("X"); // workaround for #11279, new Date("") == NaN
+
+dojo.parser = new function(){
+ // summary:
+ // The Dom/Widget parsing package
+
+ var d = dojo;
+
+ function val2type(/*Object*/ value){
+ // summary:
+ // Returns name of type of given value.
+
+ if(d.isString(value)){ return "string"; }
+ if(typeof value == "number"){ return "number"; }
+ if(typeof value == "boolean"){ return "boolean"; }
+ if(d.isFunction(value)){ return "function"; }
+ if(d.isArray(value)){ return "array"; } // typeof [] == "object"
+ if(value instanceof Date) { return "date"; } // assume timestamp
+ if(value instanceof d._Url){ return "url"; }
+ return "object";
+ }
+
+ function str2obj(/*String*/ value, /*String*/ type){
+ // summary:
+ // Convert given string value to given type
+ switch(type){
+ case "string":
+ return value;
+ case "number":
+ return value.length ? Number(value) : NaN;
+ case "boolean":
+ // for checked/disabled value might be "" or "checked". interpret as true.
+ return typeof value == "boolean" ? value : !(value.toLowerCase()=="false");
+ case "function":
+ if(d.isFunction(value)){
+ // IE gives us a function, even when we say something like onClick="foo"
+ // (in which case it gives us an invalid function "function(){ foo }").
+ // Therefore, convert to string
+ value=value.toString();
+ value=d.trim(value.substring(value.indexOf('{')+1, value.length-1));
+ }
+ try{
+ if(value === "" || value.search(/[^\w\.]+/i) != -1){
+ // The user has specified some text for a function like "return x+5"
+ return new Function(value);
+ }else{
+ // The user has specified the name of a function like "myOnClick"
+ // or a single word function "return"
+ return d.getObject(value, false) || new Function(value);
+ }
+ }catch(e){ return new Function(); }
+ case "array":
+ return value ? value.split(/\s*,\s*/) : [];
+ case "date":
+ switch(value){
+ case "": return new Date(""); // the NaN of dates
+ case "now": return new Date(); // current date
+ default: return d.date.stamp.fromISOString(value);
+ }
+ case "url":
+ return d.baseUrl + value;
+ default:
+ return d.fromJson(value);
+ }
+ }
+
+ var dummyClass = {}, instanceClasses = {
+ // map from fully qualified name (like "dijit.Button") to structure like
+ // { cls: dijit.Button, params: {label: "string", disabled: "boolean"} }
+ };
+
+ // Widgets like BorderContainer add properties to _Widget via dojo.extend().
+ // If BorderContainer is loaded after _Widget's parameter list has been cached,
+ // we need to refresh that parameter list (for _Widget and all widgets that extend _Widget).
+ // TODO: remove this in 2.0, when we stop caching parameters.
+ d.connect(d, "extend", function(){
+ instanceClasses = {};
+ });
+
+ function getProtoInfo(cls, params){
+ // cls: A prototype
+ // The prototype of the class to check props on
+ // params: Object
+ // The parameters object to mix found parameters onto.
+ for(var name in cls){
+ if(name.charAt(0)=="_"){ continue; } // skip internal properties
+ if(name in dummyClass){ continue; } // skip "constructor" and "toString"
+ params[name] = val2type(cls[name]);
+ }
+ return params;
+ }
+
+ function getClassInfo(/*String*/ className, /*Boolean*/ skipParamsLookup){
+ // summary:
+ // Maps a widget name string like "dijit.form.Button" to the widget constructor itself,
+ // and a list of that widget's parameters and their types
+ // className:
+ // fully qualified name (like "dijit.form.Button")
+ // returns:
+ // structure like
+ // {
+ // cls: dijit.Button,
+ // params: { label: "string", disabled: "boolean"}
+ // }
+
+ var c = instanceClasses[className];
+ if(!c){
+ // get pointer to widget class
+ var cls = d.getObject(className), params = null;
+ if(!cls){ return null; } // class not defined [yet]
+ if(!skipParamsLookup){ // from fastpath, we don't need to lookup the attrs on the proto because they are explicit
+ params = getProtoInfo(cls.prototype, {})
+ }
+ c = { cls: cls, params: params };
+
+ }else if(!skipParamsLookup && !c.params){
+ // if we're calling getClassInfo and have a cls proto, but no params info, scan that cls for params now
+ // and update the pointer in instanceClasses[className]. This happens when a widget appears in another
+ // widget's template which still uses dojoType, but an instance of the widget appears prior with a data-dojo-type,
+ // skipping this lookup the first time.
+ c.params = getProtoInfo(c.cls.prototype, {});
+ }
+
+ return c;
+ }
+
+ this._functionFromScript = function(script, attrData){
+ // summary:
+ // Convert a <script type="dojo/method" args="a, b, c"> ... </script>
+ // into a function
+ // script: DOMNode
+ // The <script> DOMNode
+ // attrData: String
+ // For HTML5 compliance, searches for attrData + "args" (typically
+ // "data-dojo-args") instead of "args"
+ var preamble = "";
+ var suffix = "";
+ var argsStr = (script.getAttribute(attrData + "args") || script.getAttribute("args"));
+ if(argsStr){
+ d.forEach(argsStr.split(/\s*,\s*/), function(part, idx){
+ preamble += "var "+part+" = arguments["+idx+"]; ";
+ });
+ }
+ var withStr = script.getAttribute("with");
+ if(withStr && withStr.length){
+ d.forEach(withStr.split(/\s*,\s*/), function(part){
+ preamble += "with("+part+"){";
+ suffix += "}";
+ });
+ }
+ return new Function(preamble+script.innerHTML+suffix);
+ };
+
+ this.instantiate = function(/* Array */nodes, /* Object? */mixin, /* Object? */args){
+ // summary:
+ // Takes array of nodes, and turns them into class instances and
+ // potentially calls a startup method to allow them to connect with
+ // any children.
+ // nodes: Array
+ // Array of nodes or objects like
+ // | {
+ // | type: "dijit.form.Button",
+ // | node: DOMNode,
+ // | scripts: [ ... ], // array of <script type="dojo/..."> children of node
+ // | inherited: { ... } // settings inherited from ancestors like dir, theme, etc.
+ // | }
+ // mixin: Object?
+ // An object that will be mixed in with each node in the array.
+ // Values in the mixin will override values in the node, if they
+ // exist.
+ // args: Object?
+ // An object used to hold kwArgs for instantiation.
+ // See parse.args argument for details.
+
+ var thelist = [],
+ mixin = mixin||{};
+ args = args||{};
+
+ // TODO: for 2.0 default to data-dojo- regardless of scopeName (or maybe scopeName won't exist in 2.0)
+ var attrName = (args.scope || d._scopeName) + "Type", // typically "dojoType"
+ attrData = "data-" + (args.scope || d._scopeName) + "-"; // typically "data-dojo-"
+
+ d.forEach(nodes, function(obj){
+ if(!obj){ return; }
+
+ // Get pointers to DOMNode, dojoType string, and clsInfo (metadata about the dojoType), etc.
+ var node, type, clsInfo, clazz, scripts, fastpath;
+ if(obj.node){
+ // new format of nodes[] array, object w/lots of properties pre-computed for me
+ node = obj.node;
+ type = obj.type;
+ fastpath = obj.fastpath;
+ clsInfo = obj.clsInfo || (type && getClassInfo(type, fastpath));
+ clazz = clsInfo && clsInfo.cls;
+ scripts = obj.scripts;
+ }else{
+ // old (backwards compatible) format of nodes[] array, simple array of DOMNodes. no fastpath/data-dojo-type support here.
+ node = obj;
+ type = attrName in mixin ? mixin[attrName] : node.getAttribute(attrName);
+ clsInfo = type && getClassInfo(type);
+ clazz = clsInfo && clsInfo.cls;
+ scripts = (clazz && (clazz._noScript || clazz.prototype._noScript) ? [] :
+ d.query("> script[type^='dojo/']", node));
+ }
+ if(!clsInfo){
+ throw new Error("Could not load class '" + type);
+ }
+
+ // Setup hash to hold parameter settings for this widget. Start with the parameter
+ // settings inherited from ancestors ("dir" and "lang").
+ // Inherited setting may later be overridden by explicit settings on node itself.
+ var params = {};
+
+ if(args.defaults){
+ // settings for the document itself (or whatever subtree is being parsed)
+ d._mixin(params, args.defaults);
+ }
+ if(obj.inherited){
+ // settings from dir=rtl or lang=... on a node above this node
+ d._mixin(params, obj.inherited);
+ }
+
+ // mix things found in data-dojo-props into the params
+ if(fastpath){
+ var extra = node.getAttribute(attrData + "props");
+ if(extra && extra.length){
+ try{
+ extra = d.fromJson.call(args.propsThis, "{" + extra + "}");
+ d._mixin(params, extra);
+ }catch(e){
+ // give the user a pointer to their invalid parameters. FIXME: can we kill this in production?
+ throw new Error(e.toString() + " in data-dojo-props='" + extra + "'");
+ }
+ }
+
+ // For the benefit of _Templated, check if node has data-dojo-attach-point/data-dojo-attach-event
+ // and mix those in as though they were parameters
+ var attachPoint = node.getAttribute(attrData + "attach-point");
+ if(attachPoint){
+ params.dojoAttachPoint = attachPoint;
+ }
+ var attachEvent = node.getAttribute(attrData + "attach-event");
+ if(attachEvent){
+ params.dojoAttachEvent = attachEvent;
+ }
+ dojo.mixin(params, mixin);
+ }else{
+ // FIXME: we need something like "deprecateOnce()" to throw dojo.deprecation for something.
+ // remove this logic in 2.0
+ // read parameters (ie, attributes) specified on DOMNode
+
+ var attributes = node.attributes;
+
+ // clsInfo.params lists expected params like {"checked": "boolean", "n": "number"}
+ for(var name in clsInfo.params){
+ var item = name in mixin ? { value:mixin[name], specified:true } : attributes.getNamedItem(name);
+ if(!item || (!item.specified && (!dojo.isIE || name.toLowerCase()!="value"))){ continue; }
+ var value = item.value;
+ // Deal with IE quirks for 'class' and 'style'
+ switch(name){
+ case "class":
+ value = "className" in mixin ? mixin.className : node.className;
+ break;
+ case "style":
+ value = "style" in mixin ? mixin.style : (node.style && node.style.cssText); // FIXME: Opera?
+ }
+ var _type = clsInfo.params[name];
+ if(typeof value == "string"){
+ params[name] = str2obj(value, _type);
+ }else{
+ params[name] = value;
+ }
+ }
+ }
+
+ // Process <script type="dojo/*"> script tags
+ // <script type="dojo/method" event="foo"> tags are added to params, and passed to
+ // the widget on instantiation.
+ // <script type="dojo/method"> tags (with no event) are executed after instantiation
+ // <script type="dojo/connect" event="foo"> tags are dojo.connected after instantiation
+ // note: dojo/* script tags cannot exist in self closing widgets, like <input />
+ var connects = [], // functions to connect after instantiation
+ calls = []; // functions to call after instantiation
+
+ d.forEach(scripts, function(script){
+ node.removeChild(script);
+ // FIXME: drop event="" support in 2.0. use data-dojo-event="" instead
+ var event = (script.getAttribute(attrData + "event") || script.getAttribute("event")),
+ type = script.getAttribute("type"),
+ nf = d.parser._functionFromScript(script, attrData);
+ if(event){
+ if(type == "dojo/connect"){
+ connects.push({event: event, func: nf});
+ }else{
+ params[event] = nf;
+ }
+ }else{
+ calls.push(nf);
+ }
+ });
+
+ var markupFactory = clazz.markupFactory || clazz.prototype && clazz.prototype.markupFactory;
+ // create the instance
+ var instance = markupFactory ? markupFactory(params, node, clazz) : new clazz(params, node);
+ thelist.push(instance);
+
+ // map it to the JS namespace if that makes sense
+ // FIXME: in 2.0, drop jsId support. use data-dojo-id instead
+ var jsname = (node.getAttribute(attrData + "id") || node.getAttribute("jsId"));
+ if(jsname){
+ d.setObject(jsname, instance);
+ }
+
+ // process connections and startup functions
+ d.forEach(connects, function(connect){
+ d.connect(instance, connect.event, null, connect.func);
+ });
+ d.forEach(calls, function(func){
+ func.call(instance);
+ });
+ });
+
+ // Call startup on each top level instance if it makes sense (as for
+ // widgets). Parent widgets will recursively call startup on their
+ // (non-top level) children
+ if(!mixin._started){
+ // TODO: for 2.0, when old instantiate() API is desupported, store parent-child
+ // relationships in the nodes[] array so that no getParent() call is needed.
+ // Note that will require a parse() call from ContentPane setting a param that the
+ // ContentPane is the parent widget (so that the parse doesn't call startup() on the
+ // ContentPane's children)
+ d.forEach(thelist, function(instance){
+ if( !args.noStart && instance &&
+ dojo.isFunction(instance.startup) &&
+ !instance._started &&
+ (!instance.getParent || !instance.getParent())
+ ){
+ instance.startup();
+ }
+ });
+ }
+ return thelist;
+ };
+
+ this.parse = function(rootNode, args){
+ // summary:
+ // Scan the DOM for class instances, and instantiate them.
+ //
+ // description:
+ // Search specified node (or root node) recursively for class instances,
+ // and instantiate them. Searches for either data-dojo-type="Class" or
+ // dojoType="Class" where "Class" is a a fully qualified class name,
+ // like `dijit.form.Button`
+ //
+ // Using `data-dojo-type`:
+ // Attributes using can be mixed into the parameters used to instantitate the
+ // Class by using a `data-dojo-props` attribute on the node being converted.
+ // `data-dojo-props` should be a string attribute to be converted from JSON.
+ //
+ // Using `dojoType`:
+ // Attributes are read from the original domNode and converted to appropriate
+ // types by looking up the Class prototype values. This is the default behavior
+ // from Dojo 1.0 to Dojo 1.5. `dojoType` support is deprecated, and will
+ // go away in Dojo 2.0.
+ //
+ // rootNode: DomNode?
+ // A default starting root node from which to start the parsing. Can be
+ // omitted, defaulting to the entire document. If omitted, the `args`
+ // object can be passed in this place. If the `args` object has a
+ // `rootNode` member, that is used.
+ //
+ // args: Object
+ // a kwArgs object passed along to instantiate()
+ //
+ // * noStart: Boolean?
+ // when set will prevent the parser from calling .startup()
+ // when locating the nodes.
+ // * rootNode: DomNode?
+ // identical to the function's `rootNode` argument, though
+ // allowed to be passed in via this `args object.
+ // * template: Boolean
+ // If true, ignores ContentPane's stopParser flag and parses contents inside of
+ // a ContentPane inside of a template. This allows dojoAttachPoint on widgets/nodes
+ // nested inside the ContentPane to work.
+ // * inherited: Object
+ // Hash possibly containing dir and lang settings to be applied to
+ // parsed widgets, unless there's another setting on a sub-node that overrides
+ // * scope: String
+ // Root for attribute names to search for. If scopeName is dojo,
+ // will search for data-dojo-type (or dojoType). For backwards compatibility
+ // reasons defaults to dojo._scopeName (which is "dojo" except when
+ // multi-version support is used, when it will be something like dojo16, dojo20, etc.)
+ // * propsThis: Object
+ // If specified, "this" referenced from data-dojo-props will refer to propsThis.
+ // Intended for use from the widgets-in-template feature of `dijit._Templated`
+ //
+ // example:
+ // Parse all widgets on a page:
+ // | dojo.parser.parse();
+ //
+ // example:
+ // Parse all classes within the node with id="foo"
+ // | dojo.parser.parse(dojo.byId('foo'));
+ //
+ // example:
+ // Parse all classes in a page, but do not call .startup() on any
+ // child
+ // | dojo.parser.parse({ noStart: true })
+ //
+ // example:
+ // Parse all classes in a node, but do not call .startup()
+ // | dojo.parser.parse(someNode, { noStart:true });
+ // | // or
+ // | dojo.parser.parse({ noStart:true, rootNode: someNode });
+
+ // determine the root node based on the passed arguments.
+ var root;
+ if(!args && rootNode && rootNode.rootNode){
+ args = rootNode;
+ root = args.rootNode;
+ }else{
+ root = rootNode;
+ }
+ args = args || {};
+
+ var attrName = (args.scope || d._scopeName) + "Type", // typically "dojoType"
+ attrData = "data-" + (args.scope || d._scopeName) + "-"; // typically "data-dojo-"
+
+ function scan(parent, list){
+ // summary:
+ // Parent is an Object representing a DOMNode, with or without a dojoType specified.
+ // Scan parent's children looking for nodes with dojoType specified, storing in list[].
+ // If parent has a dojoType, also collects <script type=dojo/*> children and stores in parent.scripts[].
+ // parent: Object
+ // Object representing the parent node, like
+ // | {
+ // | node: DomNode, // scan children of this node
+ // | inherited: {dir: "rtl"}, // dir/lang setting inherited from above node
+ // |
+ // | // attributes only set if node has dojoType specified
+ // | scripts: [], // empty array, put <script type=dojo/*> in here
+ // | clsInfo: { cls: dijit.form.Button, ...}
+ // | }
+ // list: DomNode[]
+ // Output array of objects (same format as parent) representing nodes to be turned into widgets
+
+ // Effective dir and lang settings on parent node, either set directly or inherited from grandparent
+ var inherited = dojo.clone(parent.inherited);
+ dojo.forEach(["dir", "lang"], function(name){
+ // TODO: what if this is a widget and dir/lang are declared in data-dojo-props?
+ var val = parent.node.getAttribute(name);
+ if(val){
+ inherited[name] = val;
+ }
+ });
+
+ // if parent is a widget, then search for <script type=dojo/*> tags and put them in scripts[].
+ var scripts = parent.clsInfo && !parent.clsInfo.cls.prototype._noScript ? parent.scripts : null;
+
+ // unless parent is a widget with the stopParser flag set, continue search for dojoType, recursively
+ var recurse = (!parent.clsInfo || !parent.clsInfo.cls.prototype.stopParser) || (args && args.template);
+
+ // scan parent's children looking for dojoType and <script type=dojo/*>
+ for(var child = parent.node.firstChild; child; child = child.nextSibling){
+ if(child.nodeType == 1){
+ // FIXME: desupport dojoType in 2.0. use data-dojo-type instead
+ var type, html5 = recurse && child.getAttribute(attrData + "type");
+ if(html5){
+ type = html5;
+ }else{
+ // fallback to backward compatible mode, using dojoType. remove in 2.0
+ type = recurse && child.getAttribute(attrName);
+ }
+
+ var fastpath = html5 == type;
+
+ if(type){
+ // if dojoType/data-dojo-type specified, add to output array of nodes to instantiate
+ var params = {
+ "type": type,
+ fastpath: fastpath,
+ clsInfo: getClassInfo(type, fastpath), // note: won't find classes declared via dojo.Declaration
+ node: child,
+ scripts: [], // <script> nodes that are parent's children
+ inherited: inherited // dir & lang attributes inherited from parent
+ };
+ list.push(params);
+
+ // Recurse, collecting <script type="dojo/..."> children, and also looking for
+ // descendant nodes with dojoType specified (unless the widget has the stopParser flag),
+ scan(params, list);
+ }else if(scripts && child.nodeName.toLowerCase() == "script"){
+ // if <script type="dojo/...">, save in scripts[]
+ type = child.getAttribute("type");
+ if (type && /^dojo\/\w/i.test(type)) {
+ scripts.push(child);
+ }
+ }else if(recurse){
+ // Recurse, looking for grandchild nodes with dojoType specified
+ scan({
+ node: child,
+ inherited: inherited
+ }, list);
+ }
+ }
+ }
+ }
+
+ // Make list of all nodes on page w/dojoType specified
+ var list = [];
+ scan({
+ node: root ? dojo.byId(root) : dojo.body(),
+ inherited: (args && args.inherited) || {
+ dir: dojo._isBodyLtr() ? "ltr" : "rtl"
+ }
+ }, list);
+
+ // go build the object instances
+ var mixin = args && args.template ? {template: true} : null;
+ return this.instantiate(list, mixin, args); // Array
+ };
+}();
+
+//Register the parser callback. It should be the first callback
+//after the a11y test.
+
+(function(){
+ var parseRunner = function(){
+ if(dojo.config.parseOnLoad){
+ dojo.parser.parse();
+ }
+ };
+
+ // FIXME: need to clobber cross-dependency!!
+ if(dojo.getObject("dijit.wai.onload") === dojo._loaders[0]){
+ dojo._loaders.splice(1, 0, parseRunner);
+ }else{
+ dojo._loaders.unshift(parseRunner);
+ }
+})();
+
+}
+
+if(!dojo._hasResource["dojo.Stateful"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.Stateful"] = true;
+dojo.provide("dojo.Stateful");
+
+
+
+dojo.declare("dojo.Stateful", null, {
+ // summary:
+ // Base class for objects that provide named properties with optional getter/setter
+ // control and the ability to watch for property changes
+ // example:
+ // | var obj = new dojo.Stateful();
+ // | obj.watch("foo", function(){
+ // | console.log("foo changed to " + this.get("foo"));
+ // | });
+ // | obj.set("foo","bar");
+ postscript: function(mixin){
+ if(mixin){
+ dojo.mixin(this, mixin);
+ }
+ },
+
+ get: function(/*String*/name){
+ // summary:
+ // Get a property on a Stateful instance.
+ // name:
+ // The property to get.
+ // description:
+ // Get a named property on a Stateful object. The property may
+ // potentially be retrieved via a getter method in subclasses. In the base class
+ // this just retrieves the object's property.
+ // For example:
+ // | stateful = new dojo.Stateful({foo: 3});
+ // | stateful.get("foo") // returns 3
+ // | stateful.foo // returns 3
+
+ return this[name];
+ },
+ set: function(/*String*/name, /*Object*/value){
+ // summary:
+ // Set a property on a Stateful instance
+ // name:
+ // The property to set.
+ // value:
+ // The value to set in the property.
+ // description:
+ // Sets named properties on a stateful object and notifies any watchers of
+ // the property. A programmatic setter may be defined in subclasses.
+ // For example:
+ // | stateful = new dojo.Stateful();
+ // | stateful.watch(function(name, oldValue, value){
+ // | // this will be called on the set below
+ // | }
+ // | stateful.set(foo, 5);
+ //
+ // 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 x in name){
+ this.set(x, name[x]);
+ }
+ return this;
+ }
+ var oldValue = this[name];
+ this[name] = value;
+ if(this._watchCallbacks){
+ this._watchCallbacks(name, oldValue, value);
+ }
+ return this;
+ },
+ watch: function(/*String?*/name, /*Function*/callback){
+ // summary:
+ // Watches a property for changes
+ // name:
+ // Indicates the property to watch. This is optional (the callback may be the
+ // only parameter), and if omitted, all the properties will be watched
+ // returns:
+ // An object handle for the watch. The unwatch method of this object
+ // can be used to discontinue watching this property:
+ // | var watchHandle = obj.watch("foo", callback);
+ // | watchHandle.unwatch(); // callback won't be called now
+ // callback:
+ // The function to execute when the property changes. This will be called after
+ // the property has been changed. The callback will be called with the |this|
+ // set to the instance, the first argument as the name of the property, the
+ // second argument as the old value and the third argument as the new value.
+
+ var callbacks = this._watchCallbacks;
+ if(!callbacks){
+ var self = this;
+ callbacks = this._watchCallbacks = function(name, oldValue, value, ignoreCatchall){
+ var notify = function(propertyCallbacks){
+ if(propertyCallbacks){
+ propertyCallbacks = propertyCallbacks.slice();
+ for(var i = 0, l = propertyCallbacks.length; i < l; i++){
+ try{
+ propertyCallbacks[i].call(self, name, oldValue, value);
+ }catch(e){
+ console.error(e);
+ }
+ }
+ }
+ };
+ notify(callbacks['_' + name]);
+ if(!ignoreCatchall){
+ notify(callbacks["*"]); // the catch-all
+ }
+ }; // we use a function instead of an object so it will be ignored by JSON conversion
+ }
+ if(!callback && typeof name === "function"){
+ callback = name;
+ name = "*";
+ }else{
+ // prepend with dash to prevent name conflicts with function (like "name" property)
+ name = '_' + name;
+ }
+ var propertyCallbacks = callbacks[name];
+ if(typeof propertyCallbacks !== "object"){
+ propertyCallbacks = callbacks[name] = [];
+ }
+ propertyCallbacks.push(callback);
+ return {
+ unwatch: function(){
+ propertyCallbacks.splice(dojo.indexOf(propertyCallbacks, callback), 1);
+ }
+ };
+ }
+
+});
+
+}
+
+if(!dojo._hasResource["dijit._WidgetBase"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._WidgetBase"] = true;
+dojo.provide("dijit._WidgetBase");
+
+
+
+
+
+(function(){
+
+dojo.declare("dijit._WidgetBase", dojo.Stateful, {
+ // summary:
+ // Future base class for all Dijit widgets.
+ // _Widget extends this class adding support for various features needed by desktop.
+
+ // id: [const] String
+ // A unique, opaque ID string that can be assigned by users or by the
+ // system. If the developer passes an ID which is known not to be
+ // unique, the specified ID is ignored and the system-generated ID is
+ // used instead.
+ id: "",
+
+ // lang: [const] String
+ // Rarely used. Overrides the default Dojo locale used to render this widget,
+ // as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute.
+ // Value must be among the list of locales specified during by the Dojo bootstrap,
+ // formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us).
+ lang: "",
+
+ // dir: [const] String
+ // Bi-directional support, as defined by the [HTML DIR](http://www.w3.org/TR/html401/struct/dirlang.html#adef-dir)
+ // attribute. Either left-to-right "ltr" or right-to-left "rtl". If undefined, widgets renders in page's
+ // default direction.
+ dir: "",
+
+ // class: String
+ // HTML class attribute
+ "class": "",
+
+ // style: String||Object
+ // HTML style attributes as cssText string or name/value hash
+ style: "",
+
+ // title: String
+ // HTML title attribute.
+ //
+ // For form widgets this specifies a tooltip to display when hovering over
+ // the widget (just like the native HTML title attribute).
+ //
+ // For TitlePane or for when this widget is a child of a TabContainer, AccordionContainer,
+ // etc., it's used to specify the tab label, accordion pane title, etc.
+ title: "",
+
+ // tooltip: String
+ // When this widget's title attribute is used to for a tab label, accordion pane title, etc.,
+ // this specifies the tooltip to appear when the mouse is hovered over that text.
+ tooltip: "",
+
+ // baseClass: [protected] String
+ // Root CSS class of the widget (ex: dijitTextBox), used to construct CSS classes to indicate
+ // widget state.
+ baseClass: "",
+
+ // srcNodeRef: [readonly] DomNode
+ // pointer to original DOM node
+ srcNodeRef: null,
+
+ // domNode: [readonly] DomNode
+ // This is our visible representation of the widget! Other DOM
+ // Nodes may by assigned to other properties, usually through the
+ // template system's dojoAttachPoint syntax, but the domNode
+ // property is the canonical "top level" node in widget UI.
+ domNode: null,
+
+ // containerNode: [readonly] DomNode
+ // Designates where children of the source DOM node will be placed.
+ // "Children" in this case refers to both DOM nodes and widgets.
+ // For example, for myWidget:
+ //
+ // | <div dojoType=myWidget>
+ // | <b> here's a plain DOM node
+ // | <span dojoType=subWidget>and a widget</span>
+ // | <i> and another plain DOM node </i>
+ // | </div>
+ //
+ // containerNode would point to:
+ //
+ // | <b> here's a plain DOM node
+ // | <span dojoType=subWidget>and a widget</span>
+ // | <i> and another plain DOM node </i>
+ //
+ // In templated widgets, "containerNode" is set via a
+ // dojoAttachPoint assignment.
+ //
+ // containerNode must be defined for any widget that accepts innerHTML
+ // (like ContentPane or BorderContainer or even Button), and conversely
+ // is null for widgets that don't, like TextBox.
+ containerNode: null,
+
+/*=====
+ // _started: Boolean
+ // startup() has completed.
+ _started: false,
+=====*/
+
+ // attributeMap: [protected] Object
+ // attributeMap sets up a "binding" between attributes (aka properties)
+ // of the widget and the widget's DOM.
+ // Changes to widget attributes listed in attributeMap will be
+ // reflected into the DOM.
+ //
+ // For example, calling set('title', 'hello')
+ // on a TitlePane will automatically cause the TitlePane's DOM to update
+ // with the new title.
+ //
+ // attributeMap is a hash where the key is an attribute of the widget,
+ // and the value reflects a binding to a:
+ //
+ // - DOM node attribute
+ // | focus: {node: "focusNode", type: "attribute"}
+ // Maps this.focus to this.focusNode.focus
+ //
+ // - DOM node innerHTML
+ // | title: { node: "titleNode", type: "innerHTML" }
+ // Maps this.title to this.titleNode.innerHTML
+ //
+ // - DOM node innerText
+ // | title: { node: "titleNode", type: "innerText" }
+ // Maps this.title to this.titleNode.innerText
+ //
+ // - DOM node CSS class
+ // | myClass: { node: "domNode", type: "class" }
+ // Maps this.myClass to this.domNode.className
+ //
+ // If the value is an array, then each element in the array matches one of the
+ // formats of the above list.
+ //
+ // There are also some shorthands for backwards compatibility:
+ // - string --> { node: string, type: "attribute" }, for example:
+ // | "focusNode" ---> { node: "focusNode", type: "attribute" }
+ // - "" --> { node: "domNode", type: "attribute" }
+ attributeMap: {id:"", dir:"", lang:"", "class":"", style:"", title:""},
+
+ // _blankGif: [protected] String
+ // Path to a blank 1x1 image.
+ // Used by <img> nodes in templates that really get their image via CSS background-image.
+ _blankGif: (dojo.config.blankGif || dojo.moduleUrl("dojo", "resources/blank.gif")).toString(),
+
+ //////////// INITIALIZATION METHODS ///////////////////////////////////////
+
+ postscript: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){
+ // summary:
+ // Kicks off widget instantiation. See create() for details.
+ // tags:
+ // private
+ this.create(params, srcNodeRef);
+ },
+
+ create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
+ // summary:
+ // Kick off the life-cycle of a widget
+ // params:
+ // Hash of initialization parameters for widget, including
+ // scalar values (like title, duration etc.) and functions,
+ // typically callbacks like onClick.
+ // srcNodeRef:
+ // If a srcNodeRef (DOM node) is specified:
+ // - use srcNodeRef.innerHTML as my contents
+ // - if this is a behavioral widget then apply behavior
+ // to that srcNodeRef
+ // - otherwise, replace srcNodeRef with my generated DOM
+ // tree
+ // description:
+ // Create calls a number of widget methods (postMixInProperties, buildRendering, postCreate,
+ // etc.), some of which of you'll want to override. See http://docs.dojocampus.org/dijit/_Widget
+ // for a discussion of the widget creation lifecycle.
+ //
+ // Of course, adventurous developers could override create entirely, but this should
+ // only be done as a last resort.
+ // tags:
+ // private
+
+ // store pointer to original DOM tree
+ this.srcNodeRef = dojo.byId(srcNodeRef);
+
+ // For garbage collection. An array of handles returned by Widget.connect()
+ // Each handle returned from Widget.connect() is an array of handles from dojo.connect()
+ this._connects = [];
+
+ // For garbage collection. An array of handles returned by Widget.subscribe()
+ // The handle returned from Widget.subscribe() is the handle returned from dojo.subscribe()
+ this._subscribes = [];
+
+ // mix in our passed parameters
+ if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){ this.id = this.srcNodeRef.id; }
+ if(params){
+ this.params = params;
+ dojo._mixin(this, params);
+ }
+ this.postMixInProperties();
+
+ // generate an id for the widget if one wasn't specified
+ // (be sure to do this before buildRendering() because that function might
+ // expect the id to be there.)
+ if(!this.id){
+ this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
+ }
+ dijit.registry.add(this);
+
+ this.buildRendering();
+
+ if(this.domNode){
+ // Copy attributes listed in attributeMap into the [newly created] DOM for the widget.
+ // Also calls custom setters for all attributes with custom setters.
+ this._applyAttributes();
+
+ // If srcNodeRef was specified, then swap out original srcNode for this widget's DOM tree.
+ // For 2.0, move this after postCreate(). postCreate() shouldn't depend on the
+ // widget being attached to the DOM since it isn't when a widget is created programmatically like
+ // new MyWidget({}). See #11635.
+ var source = this.srcNodeRef;
+ if(source && source.parentNode && this.domNode !== source){
+ source.parentNode.replaceChild(this.domNode, source);
+ }
+ }
+
+ if(this.domNode){
+ // Note: for 2.0 may want to rename widgetId to dojo._scopeName + "_widgetId",
+ // assuming that dojo._scopeName even exists in 2.0
+ this.domNode.setAttribute("widgetId", this.id);
+ }
+ this.postCreate();
+
+ // If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC.
+ if(this.srcNodeRef && !this.srcNodeRef.parentNode){
+ delete this.srcNodeRef;
+ }
+
+ this._created = true;
+ },
+
+ _applyAttributes: function(){
+ // summary:
+ // Step during widget creation to copy all widget attributes to the
+ // DOM as per attributeMap and _setXXXAttr functions.
+ // description:
+ // Skips over blank/false attribute values, unless they were explicitly specified
+ // as parameters to the widget, since those are the default anyway,
+ // and setting tabIndex="" is different than not setting tabIndex at all.
+ //
+ // It processes the attributes in the attribute map first, and then
+ // it goes through and processes the attributes for the _setXXXAttr
+ // functions that have been specified
+ // tags:
+ // private
+ var condAttrApply = function(attr, scope){
+ if((scope.params && attr in scope.params) || scope[attr]){
+ scope.set(attr, scope[attr]);
+ }
+ };
+
+ // Do the attributes in attributeMap
+ for(var attr in this.attributeMap){
+ condAttrApply(attr, this);
+ }
+
+ // And also any attributes with custom setters
+ dojo.forEach(this._getSetterAttributes(), function(a){
+ if(!(a in this.attributeMap)){
+ condAttrApply(a, this);
+ }
+ }, this);
+ },
+
+ _getSetterAttributes: function(){
+ // summary:
+ // Returns list of attributes with custom setters for this widget
+ var ctor = this.constructor;
+ if(!ctor._setterAttrs){
+ var r = (ctor._setterAttrs = []),
+ attrs,
+ proto = ctor.prototype;
+ for(var fxName in proto){
+ if(dojo.isFunction(proto[fxName]) && (attrs = fxName.match(/^_set([a-zA-Z]*)Attr$/)) && attrs[1]){
+ r.push(attrs[1].charAt(0).toLowerCase() + attrs[1].substr(1));
+ }
+ }
+ }
+ return ctor._setterAttrs; // String[]
+ },
+
+ postMixInProperties: function(){
+ // summary:
+ // Called after the parameters to the widget have been read-in,
+ // but before the widget template is instantiated. Especially
+ // useful to set properties that are referenced in the widget
+ // template.
+ // tags:
+ // protected
+ },
+
+ buildRendering: function(){
+ // summary:
+ // Construct the UI for this widget, setting this.domNode
+ // description:
+ // Most widgets will mixin `dijit._Templated`, which implements this
+ // method.
+ // tags:
+ // protected
+
+ if(!this.domNode){
+ // Create root node if it wasn't created by _Templated
+ this.domNode = this.srcNodeRef || dojo.create('div');
+ }
+
+ // baseClass is a single class name or occasionally a space-separated list of names.
+ // Add those classes to the DOMNode. If RTL mode then also add with Rtl suffix.
+ // TODO: make baseClass custom setter
+ if(this.baseClass){
+ var classes = this.baseClass.split(" ");
+ if(!this.isLeftToRight()){
+ classes = classes.concat( dojo.map(classes, function(name){ return name+"Rtl"; }));
+ }
+ dojo.addClass(this.domNode, classes);
+ }
+ },
+
+ postCreate: function(){
+ // summary:
+ // Processing after the DOM fragment is created
+ // description:
+ // Called after the DOM fragment has been created, but not necessarily
+ // added to the document. Do not include any operations which rely on
+ // node dimensions or placement.
+ // tags:
+ // protected
+ },
+
+ startup: function(){
+ // summary:
+ // Processing after the DOM fragment is added to the document
+ // description:
+ // Called after a widget and its children have been created and added to the page,
+ // and all related widgets have finished their create() cycle, up through postCreate().
+ // This is useful for composite widgets that need to control or layout sub-widgets.
+ // Many layout widgets can use this as a wiring phase.
+ this._started = true;
+ },
+
+ //////////// DESTROY FUNCTIONS ////////////////////////////////
+
+ destroyRecursive: function(/*Boolean?*/ preserveDom){
+ // summary:
+ // Destroy this widget and its descendants
+ // description:
+ // This is the generic "destructor" function that all widget users
+ // should call to cleanly discard with a widget. Once a widget is
+ // destroyed, it is removed from the manager object.
+ // preserveDom:
+ // If true, this method will leave the original DOM structure
+ // alone of descendant Widgets. Note: This will NOT work with
+ // dijit._Templated widgets.
+
+ this._beingDestroyed = true;
+ this.destroyDescendants(preserveDom);
+ this.destroy(preserveDom);
+ },
+
+ destroy: function(/*Boolean*/ preserveDom){
+ // summary:
+ // Destroy this widget, but not its descendants.
+ // This method will, however, destroy internal widgets such as those used within a template.
+ // preserveDom: Boolean
+ // If true, this method will leave the original DOM structure alone.
+ // Note: This will not yet work with _Templated widgets
+
+ this._beingDestroyed = true;
+ this.uninitialize();
+ var d = dojo,
+ dfe = d.forEach,
+ dun = d.unsubscribe;
+ dfe(this._connects, function(array){
+ dfe(array, d.disconnect);
+ });
+ dfe(this._subscribes, function(handle){
+ dun(handle);
+ });
+
+ // destroy widgets created as part of template, etc.
+ dfe(this._supportingWidgets || [], function(w){
+ if(w.destroyRecursive){
+ w.destroyRecursive();
+ }else if(w.destroy){
+ w.destroy();
+ }
+ });
+
+ this.destroyRendering(preserveDom);
+ dijit.registry.remove(this.id);
+ this._destroyed = true;
+ },
+
+ destroyRendering: function(/*Boolean?*/ preserveDom){
+ // summary:
+ // Destroys the DOM nodes associated with this widget
+ // preserveDom:
+ // If true, this method will leave the original DOM structure alone
+ // during tear-down. Note: this will not work with _Templated
+ // widgets yet.
+ // tags:
+ // protected
+
+ if(this.bgIframe){
+ this.bgIframe.destroy(preserveDom);
+ delete this.bgIframe;
+ }
+
+ if(this.domNode){
+ if(preserveDom){
+ dojo.removeAttr(this.domNode, "widgetId");
+ }else{
+ dojo.destroy(this.domNode);
+ }
+ delete this.domNode;
+ }
+
+ if(this.srcNodeRef){
+ if(!preserveDom){
+ dojo.destroy(this.srcNodeRef);
+ }
+ delete this.srcNodeRef;
+ }
+ },
+
+ destroyDescendants: function(/*Boolean?*/ preserveDom){
+ // summary:
+ // Recursively destroy the children of this widget and their
+ // descendants.
+ // preserveDom:
+ // If true, the preserveDom attribute is passed to all descendant
+ // widget's .destroy() method. Not for use with _Templated
+ // widgets.
+
+ // get all direct descendants and destroy them recursively
+ dojo.forEach(this.getChildren(), function(widget){
+ if(widget.destroyRecursive){
+ widget.destroyRecursive(preserveDom);
+ }
+ });
+ },
+
+ uninitialize: function(){
+ // summary:
+ // Stub function. Override to implement custom widget tear-down
+ // behavior.
+ // tags:
+ // protected
+ return false;
+ },
+
+ ////////////////// GET/SET, CUSTOM SETTERS, ETC. ///////////////////
+
+ _setClassAttr: function(/*String*/ value){
+ // summary:
+ // Custom setter for the CSS "class" attribute
+ // tags:
+ // protected
+ var mapNode = this[this.attributeMap["class"] || 'domNode'];
+ dojo.replaceClass(mapNode, value, this["class"]);
+ this._set("class", value);
+ },
+
+ _setStyleAttr: function(/*String||Object*/ value){
+ // summary:
+ // Sets the style attribute of the widget according to value,
+ // which is either a hash like {height: "5px", width: "3px"}
+ // or a plain string
+ // description:
+ // Determines which node to set the style on based on style setting
+ // in attributeMap.
+ // tags:
+ // protected
+
+ var mapNode = this[this.attributeMap.style || 'domNode'];
+
+ // Note: technically we should revert any style setting made in a previous call
+ // to his method, but that's difficult to keep track of.
+
+ if(dojo.isObject(value)){
+ dojo.style(mapNode, value);
+ }else{
+ if(mapNode.style.cssText){
+ mapNode.style.cssText += "; " + value;
+ }else{
+ mapNode.style.cssText = value;
+ }
+ }
+
+ this._set("style", value);
+ },
+
+ _attrToDom: function(/*String*/ attr, /*String*/ value){
+ // summary:
+ // Reflect a widget attribute (title, tabIndex, duration etc.) to
+ // the widget DOM, as specified in attributeMap.
+ // Note some attributes like "type"
+ // cannot be processed this way as they are not mutable.
+ //
+ // tags:
+ // private
+
+ var commands = this.attributeMap[attr];
+ dojo.forEach(dojo.isArray(commands) ? commands : [commands], function(command){
+
+ // Get target node and what we are doing to that node
+ var mapNode = this[command.node || command || "domNode"]; // DOM node
+ var type = command.type || "attribute"; // class, innerHTML, innerText, or attribute
+
+ switch(type){
+ case "attribute":
+ if(dojo.isFunction(value)){ // functions execute in the context of the widget
+ value = dojo.hitch(this, value);
+ }
+
+ // Get the name of the DOM node attribute; usually it's the same
+ // as the name of the attribute in the widget (attr), but can be overridden.
+ // Also maps handler names to lowercase, like onSubmit --> onsubmit
+ var attrName = command.attribute ? command.attribute :
+ (/^on[A-Z][a-zA-Z]*$/.test(attr) ? attr.toLowerCase() : attr);
+
+ dojo.attr(mapNode, attrName, value);
+ break;
+ case "innerText":
+ mapNode.innerHTML = "";
+ mapNode.appendChild(dojo.doc.createTextNode(value));
+ break;
+ case "innerHTML":
+ mapNode.innerHTML = value;
+ break;
+ case "class":
+ dojo.replaceClass(mapNode, value, this[attr]);
+ break;
+ }
+ }, this);
+ },
+
+ get: function(name){
+ // summary:
+ // Get a property from a widget.
+ // name:
+ // The property to get.
+ // description:
+ // Get a named property from a widget. The property may
+ // potentially be retrieved via a getter method. If no getter is defined, this
+ // just retrieves the object's property.
+ // For example, if the widget has a properties "foo"
+ // and "bar" and a method named "_getFooAttr", calling:
+ // | myWidget.get("foo");
+ // would be equivalent to writing:
+ // | widget._getFooAttr();
+ // and:
+ // | myWidget.get("bar");
+ // would be equivalent to writing:
+ // | widget.bar;
+ var names = this._getAttrNames(name);
+ return this[names.g] ? this[names.g]() : this[name];
+ },
+
+ set: function(name, value){
+ // summary:
+ // Set a property on a widget
+ // name:
+ // The property to set.
+ // value:
+ // The value to set in the property.
+ // description:
+ // Sets named properties on a widget which may potentially be handled by a
+ // setter in the widget.
+ // For example, if the widget has a properties "foo"
+ // and "bar" and a method named "_setFooAttr", calling:
+ // | myWidget.set("foo", "Howdy!");
+ // would be equivalent to writing:
+ // | widget._setFooAttr("Howdy!");
+ // and:
+ // | myWidget.set("bar", 3);
+ // would be equivalent to writing:
+ // | widget.bar = 3;
+ //
+ // set() may also be called with a hash of name/value pairs, ex:
+ // | myWidget.set({
+ // | foo: "Howdy",
+ // | bar: 3
+ // | })
+ // This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
+
+ if(typeof name === "object"){
+ for(var x in name){
+ this.set(x, name[x]);
+ }
+ return this;
+ }
+ var names = this._getAttrNames(name);
+ if(this[names.s]){
+ // use the explicit setter
+ var result = this[names.s].apply(this, Array.prototype.slice.call(arguments, 1));
+ }else{
+ // if param is specified as DOM node attribute, copy it
+ if(name in this.attributeMap){
+ this._attrToDom(name, value);
+ }
+ this._set(name, value);
+ }
+ return result || this;
+ },
+
+ _attrPairNames: {}, // shared between all widgets
+ _getAttrNames: function(name){
+ // summary:
+ // Helper function for get() and set().
+ // Caches attribute name values so we don't do the string ops every time.
+ // tags:
+ // private
+
+ var apn = this._attrPairNames;
+ if(apn[name]){ return apn[name]; }
+ var uc = name.charAt(0).toUpperCase() + name.substr(1);
+ return (apn[name] = {
+ n: name+"Node",
+ s: "_set"+uc+"Attr",
+ g: "_get"+uc+"Attr"
+ });
+ },
+
+ _set: function(/*String*/ name, /*anything*/ value){
+ // summary:
+ // Helper function to set new value for specified attribute, and call handlers
+ // registered with watch() if the value has changed.
+ var oldValue = this[name];
+ this[name] = value;
+ if(this._watchCallbacks && this._created && value !== oldValue){
+ this._watchCallbacks(name, oldValue, value);
+ }
+ },
+
+ toString: function(){
+ // summary:
+ // Returns a string that represents the widget
+ // description:
+ // When a widget is cast to a string, this method will be used to generate the
+ // output. Currently, it does not implement any sort of reversible
+ // serialization.
+ return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
+ },
+
+ getDescendants: function(){
+ // summary:
+ // Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
+ // This method should generally be avoided as it returns widgets declared in templates, which are
+ // supposed to be internal/hidden, but it's left here for back-compat reasons.
+
+ return this.containerNode ? dojo.query('[widgetId]', this.containerNode).map(dijit.byNode) : []; // dijit._Widget[]
+ },
+
+ getChildren: function(){
+ // summary:
+ // Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
+ // Does not return nested widgets, nor widgets that are part of this widget's template.
+ return this.containerNode ? dijit.findWidgets(this.containerNode) : []; // dijit._Widget[]
+ },
+
+ connect: function(
+ /*Object|null*/ obj,
+ /*String|Function*/ event,
+ /*String|Function*/ method){
+ // summary:
+ // Connects specified obj/event to specified method of this object
+ // and registers for disconnect() on widget destroy.
+ // description:
+ // Provide widget-specific analog to dojo.connect, except with the
+ // implicit use of this widget as the target object.
+ // Events connected with `this.connect` are disconnected upon
+ // destruction.
+ // returns:
+ // A handle that can be passed to `disconnect` in order to disconnect before
+ // the widget is destroyed.
+ // example:
+ // | var btn = new dijit.form.Button();
+ // | // when foo.bar() is called, call the listener we're going to
+ // | // provide in the scope of btn
+ // | btn.connect(foo, "bar", function(){
+ // | console.debug(this.toString());
+ // | });
+ // tags:
+ // protected
+
+ var handles = [dojo._connect(obj, event, this, method)];
+ this._connects.push(handles);
+ return handles; // _Widget.Handle
+ },
+
+ disconnect: function(/* _Widget.Handle */ handles){
+ // summary:
+ // Disconnects handle created by `connect`.
+ // Also removes handle from this widget's list of connects.
+ // tags:
+ // protected
+ for(var i=0; i<this._connects.length; i++){
+ if(this._connects[i] == handles){
+ dojo.forEach(handles, dojo.disconnect);
+ this._connects.splice(i, 1);
+ return;
+ }
+ }
+ },
+
+ subscribe: function(
+ /*String*/ topic,
+ /*String|Function*/ method){
+ // summary:
+ // Subscribes to the specified topic and calls the specified method
+ // of this object and registers for unsubscribe() on widget destroy.
+ // description:
+ // Provide widget-specific analog to dojo.subscribe, except with the
+ // implicit use of this widget as the target object.
+ // example:
+ // | var btn = new dijit.form.Button();
+ // | // when /my/topic is published, this button changes its label to
+ // | // be the parameter of the topic.
+ // | btn.subscribe("/my/topic", function(v){
+ // | this.set("label", v);
+ // | });
+ var handle = dojo.subscribe(topic, this, method);
+
+ // return handles for Any widget that may need them
+ this._subscribes.push(handle);
+ return handle;
+ },
+
+ unsubscribe: function(/*Object*/ handle){
+ // summary:
+ // Unsubscribes handle created by this.subscribe.
+ // Also removes handle from this widget's list of subscriptions
+ for(var i=0; i<this._subscribes.length; i++){
+ if(this._subscribes[i] == handle){
+ dojo.unsubscribe(handle);
+ this._subscribes.splice(i, 1);
+ return;
+ }
+ }
+ },
+
+ isLeftToRight: function(){
+ // summary:
+ // Return this widget's explicit or implicit orientation (true for LTR, false for RTL)
+ // tags:
+ // protected
+ return this.dir ? (this.dir == "ltr") : dojo._isBodyLtr(); //Boolean
+ },
+
+ placeAt: function(/* String|DomNode|_Widget */reference, /* String?|Int? */position){
+ // summary:
+ // Place this widget's domNode reference somewhere in the DOM based
+ // on standard dojo.place conventions, or passing a Widget reference that
+ // contains and addChild member.
+ //
+ // description:
+ // A convenience function provided in all _Widgets, providing a simple
+ // shorthand mechanism to put an existing (or newly created) Widget
+ // somewhere in the dom, and allow chaining.
+ //
+ // reference:
+ // The String id of a domNode, a domNode reference, or a reference to a Widget posessing
+ // an addChild method.
+ //
+ // position:
+ // If passed a string or domNode reference, the position argument
+ // accepts a string just as dojo.place does, one of: "first", "last",
+ // "before", or "after".
+ //
+ // If passed a _Widget reference, and that widget reference has an ".addChild" method,
+ // it will be called passing this widget instance into that method, supplying the optional
+ // position index passed.
+ //
+ // returns:
+ // dijit._Widget
+ // Provides a useful return of the newly created dijit._Widget instance so you
+ // can "chain" this function by instantiating, placing, then saving the return value
+ // to a variable.
+ //
+ // example:
+ // | // create a Button with no srcNodeRef, and place it in the body:
+ // | var button = new dijit.form.Button({ label:"click" }).placeAt(dojo.body());
+ // | // now, 'button' is still the widget reference to the newly created button
+ // | dojo.connect(button, "onClick", function(e){ console.log('click'); });
+ //
+ // example:
+ // | // create a button out of a node with id="src" and append it to id="wrapper":
+ // | var button = new dijit.form.Button({},"src").placeAt("wrapper");
+ //
+ // example:
+ // | // place a new button as the first element of some div
+ // | var button = new dijit.form.Button({ label:"click" }).placeAt("wrapper","first");
+ //
+ // example:
+ // | // create a contentpane and add it to a TabContainer
+ // | var tc = dijit.byId("myTabs");
+ // | new dijit.layout.ContentPane({ href:"foo.html", title:"Wow!" }).placeAt(tc)
+
+ if(reference.declaredClass && reference.addChild){
+ reference.addChild(this, position);
+ }else{
+ dojo.place(this.domNode, reference, position);
+ }
+ return this;
+ }
+});
+
+})();
+
+}
+
+if(!dojo._hasResource["dijit._Widget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Widget"] = true;
+dojo.provide("dijit._Widget");
+
+
+
+
+
+
+////////////////// DEFERRED CONNECTS ///////////////////
+
+// This code is to assist deferring dojo.connect() calls in widgets (connecting to events on the widgets'
+// DOM nodes) until someone actually needs to monitor that event.
+dojo.connect(dojo, "_connect",
+ function(/*dijit._Widget*/ widget, /*String*/ event){
+ if(widget && dojo.isFunction(widget._onConnect)){
+ widget._onConnect(event);
+ }
+ });
+
+dijit._connectOnUseEventHandler = function(/*Event*/ event){};
+
+////////////////// ONDIJITCLICK SUPPORT ///////////////////
+
+// Keep track of where the last keydown event was, to help avoid generating
+// spurious ondijitclick events when:
+// 1. focus is on a <button> or <a>
+// 2. user presses then releases the ENTER key
+// 3. onclick handler fires and shifts focus to another node, with an ondijitclick handler
+// 4. onkeyup event fires, causing the ondijitclick handler to fire
+dijit._lastKeyDownNode = null;
+if(dojo.isIE){
+ (function(){
+ var keydownCallback = function(evt){
+ dijit._lastKeyDownNode = evt.srcElement;
+ };
+ dojo.doc.attachEvent('onkeydown', keydownCallback);
+ dojo.addOnWindowUnload(function(){
+ dojo.doc.detachEvent('onkeydown', keydownCallback);
+ });
+ })();
+}else{
+ dojo.doc.addEventListener('keydown', function(evt){
+ dijit._lastKeyDownNode = evt.target;
+ }, true);
+}
+
+(function(){
+
+dojo.declare("dijit._Widget", dijit._WidgetBase, {
+ // summary:
+ // Base class for all Dijit widgets.
+ //
+ // Extends _WidgetBase, adding support for:
+ // - deferred connections
+ // A call like dojo.connect(myWidget, "onMouseMove", func)
+ // will essentially do a dojo.connect(myWidget.domNode, "onMouseMove", func)
+ // - ondijitclick
+ // Support new dojoAttachEvent="ondijitclick: ..." that is triggered by a mouse click or a SPACE/ENTER keypress
+ // - focus related functions
+ // In particular, the onFocus()/onBlur() callbacks. Driven internally by
+ // dijit/_base/focus.js.
+ // - deprecated methods
+ // - onShow(), onHide(), onClose()
+ //
+ // Also, by loading code in dijit/_base, turns on:
+ // - browser sniffing (putting browser id like .dj_ie on <html> node)
+ // - high contrast mode sniffing (add .dijit_a11y class to <body> if machine is in high contrast mode)
+
+
+ ////////////////// DEFERRED CONNECTS ///////////////////
+
+ // _deferredConnects: [protected] Object
+ // attributeMap addendum for event handlers that should be connected only on first use
+ _deferredConnects: {
+ onClick: "",
+ onDblClick: "",
+ onKeyDown: "",
+ onKeyPress: "",
+ onKeyUp: "",
+ onMouseMove: "",
+ onMouseDown: "",
+ onMouseOut: "",
+ onMouseOver: "",
+ onMouseLeave: "",
+ onMouseEnter: "",
+ onMouseUp: ""
+ },
+
+ onClick: dijit._connectOnUseEventHandler,
+ /*=====
+ onClick: function(event){
+ // summary:
+ // Connect to this function to receive notifications of mouse click events.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onDblClick: dijit._connectOnUseEventHandler,
+ /*=====
+ onDblClick: function(event){
+ // summary:
+ // Connect to this function to receive notifications of mouse double click events.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onKeyDown: dijit._connectOnUseEventHandler,
+ /*=====
+ onKeyDown: function(event){
+ // summary:
+ // Connect to this function to receive notifications of keys being pressed down.
+ // event:
+ // key Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onKeyPress: dijit._connectOnUseEventHandler,
+ /*=====
+ onKeyPress: function(event){
+ // summary:
+ // Connect to this function to receive notifications of printable keys being typed.
+ // event:
+ // key Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onKeyUp: dijit._connectOnUseEventHandler,
+ /*=====
+ onKeyUp: function(event){
+ // summary:
+ // Connect to this function to receive notifications of keys being released.
+ // event:
+ // key Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseDown: dijit._connectOnUseEventHandler,
+ /*=====
+ onMouseDown: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse button is pressed down.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseMove: dijit._connectOnUseEventHandler,
+ /*=====
+ onMouseMove: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse moves over nodes contained within this widget.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseOut: dijit._connectOnUseEventHandler,
+ /*=====
+ onMouseOut: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse moves off of nodes contained within this widget.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseOver: dijit._connectOnUseEventHandler,
+ /*=====
+ onMouseOver: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse moves onto nodes contained within this widget.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseLeave: dijit._connectOnUseEventHandler,
+ /*=====
+ onMouseLeave: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse moves off of this widget.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseEnter: dijit._connectOnUseEventHandler,
+ /*=====
+ onMouseEnter: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse moves onto this widget.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseUp: dijit._connectOnUseEventHandler,
+ /*=====
+ onMouseUp: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse button is released.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+
+ create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
+ // To avoid double-connects, remove entries from _deferredConnects
+ // that have been setup manually by a subclass (ex, by dojoAttachEvent).
+ // If a subclass has redefined a callback (ex: onClick) then assume it's being
+ // connected to manually.
+ this._deferredConnects = dojo.clone(this._deferredConnects);
+ for(var attr in this.attributeMap){
+ delete this._deferredConnects[attr]; // can't be in both attributeMap and _deferredConnects
+ }
+ for(attr in this._deferredConnects){
+ if(this[attr] !== dijit._connectOnUseEventHandler){
+ delete this._deferredConnects[attr]; // redefined, probably dojoAttachEvent exists
+ }
+ }
+
+ this.inherited(arguments);
+
+ if(this.domNode){
+ // If the developer has specified a handler as a widget parameter
+ // (ex: new Button({onClick: ...})
+ // then naturally need to connect from DOM node to that handler immediately,
+ for(attr in this.params){
+ this._onConnect(attr);
+ }
+ }
+ },
+
+ _onConnect: function(/*String*/ event){
+ // summary:
+ // Called when someone connects to one of my handlers.
+ // "Turn on" that handler if it isn't active yet.
+ //
+ // This is also called for every single initialization parameter
+ // so need to do nothing for parameters like "id".
+ // tags:
+ // private
+ if(event in this._deferredConnects){
+ var mapNode = this[this._deferredConnects[event] || 'domNode'];
+ this.connect(mapNode, event.toLowerCase(), event);
+ delete this._deferredConnects[event];
+ }
+ },
+
+ ////////////////// FOCUS RELATED ///////////////////
+ // _onFocus() and _onBlur() are called by the focus manager
+
+ // focused: [readonly] Boolean
+ // This widget or a widget it contains has focus, or is "active" because
+ // it was recently clicked.
+ focused: false,
+
+ isFocusable: function(){
+ // summary:
+ // Return true if this widget can currently be focused
+ // and false if not
+ return this.focus && (dojo.style(this.domNode, "display") != "none");
+ },
+
+ onFocus: function(){
+ // summary:
+ // Called when the widget becomes "active" because
+ // it or a widget inside of it either has focus, or has recently
+ // been clicked.
+ // tags:
+ // callback
+ },
+
+ onBlur: function(){
+ // summary:
+ // Called when the widget stops being "active" because
+ // focus moved to something outside of it, or the user
+ // clicked somewhere outside of it, or the widget was
+ // hidden.
+ // tags:
+ // callback
+ },
+
+ _onFocus: function(e){
+ // summary:
+ // This is where widgets do processing for when they are active,
+ // such as changing CSS classes. See onFocus() for more details.
+ // tags:
+ // protected
+ this.onFocus();
+ },
+
+ _onBlur: function(){
+ // summary:
+ // This is where widgets do processing for when they stop being active,
+ // such as changing CSS classes. See onBlur() for more details.
+ // tags:
+ // protected
+ this.onBlur();
+ },
+
+ ////////////////// DEPRECATED METHODS ///////////////////
+
+ setAttribute: function(/*String*/ attr, /*anything*/ value){
+ // summary:
+ // Deprecated. Use set() instead.
+ // tags:
+ // deprecated
+ dojo.deprecated(this.declaredClass+"::setAttribute(attr, value) is deprecated. Use set() instead.", "", "2.0");
+ this.set(attr, value);
+ },
+
+ attr: function(/*String|Object*/name, /*Object?*/value){
+ // summary:
+ // Set or get properties on a widget instance.
+ // name:
+ // The property to get or set. If an object is passed here and not
+ // a string, its keys are used as names of attributes to be set
+ // and the value of the object as values to set in the widget.
+ // value:
+ // Optional. If provided, attr() operates as a setter. If omitted,
+ // the current value of the named property is returned.
+ // description:
+ // This method is deprecated, use get() or set() directly.
+
+ // Print deprecation warning but only once per calling function
+ if(dojo.config.isDebug){
+ var alreadyCalledHash = arguments.callee._ach || (arguments.callee._ach = {}),
+ caller = (arguments.callee.caller || "unknown caller").toString();
+ if(!alreadyCalledHash[caller]){
+ dojo.deprecated(this.declaredClass + "::attr() is deprecated. Use get() or set() instead, called from " +
+ caller, "", "2.0");
+ alreadyCalledHash[caller] = true;
+ }
+ }
+
+ var args = arguments.length;
+ if(args >= 2 || typeof name === "object"){ // setter
+ return this.set.apply(this, arguments);
+ }else{ // getter
+ return this.get(name);
+ }
+ },
+
+ ////////////////// ONDIJITCLICK SUPPORT ///////////////////
+
+ // nodesWithKeyClick: [private] String[]
+ // List of nodes that correctly handle click events via native browser support,
+ // and don't need dijit's help
+ nodesWithKeyClick: ["input", "button"],
+
+ connect: function(
+ /*Object|null*/ obj,
+ /*String|Function*/ event,
+ /*String|Function*/ method){
+ // summary:
+ // Connects specified obj/event to specified method of this object
+ // and registers for disconnect() on widget destroy.
+ // description:
+ // Provide widget-specific analog to dojo.connect, except with the
+ // implicit use of this widget as the target object.
+ // This version of connect also provides a special "ondijitclick"
+ // event which triggers on a click or space or enter keyup.
+ // Events connected with `this.connect` are disconnected upon
+ // destruction.
+ // returns:
+ // A handle that can be passed to `disconnect` in order to disconnect before
+ // the widget is destroyed.
+ // example:
+ // | var btn = new dijit.form.Button();
+ // | // when foo.bar() is called, call the listener we're going to
+ // | // provide in the scope of btn
+ // | btn.connect(foo, "bar", function(){
+ // | console.debug(this.toString());
+ // | });
+ // tags:
+ // protected
+
+ var d = dojo,
+ dc = d._connect,
+ handles = this.inherited(arguments, [obj, event == "ondijitclick" ? "onclick" : event, method]);
+
+ if(event == "ondijitclick"){
+ // add key based click activation for unsupported nodes.
+ // do all processing onkey up to prevent spurious clicks
+ // for details see comments at top of this file where _lastKeyDownNode is defined
+ if(d.indexOf(this.nodesWithKeyClick, obj.nodeName.toLowerCase()) == -1){ // is NOT input or button
+ var m = d.hitch(this, method);
+ handles.push(
+ dc(obj, "onkeydown", this, function(e){
+ //console.log(this.id + ": onkeydown, e.target = ", e.target, ", lastKeyDownNode was ", dijit._lastKeyDownNode, ", equality is ", (e.target === dijit._lastKeyDownNode));
+ if((e.keyCode == d.keys.ENTER || e.keyCode == d.keys.SPACE) &&
+ !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){
+ // needed on IE for when focus changes between keydown and keyup - otherwise dropdown menus do not work
+ dijit._lastKeyDownNode = e.target;
+
+ // Stop event to prevent scrolling on space key in IE.
+ // But don't do this for _HasDropDown because it surpresses the onkeypress
+ // event needed to open the drop down when the user presses the SPACE key.
+ if(!("openDropDown" in this && obj == this._buttonNode)){
+ e.preventDefault();
+ }
+ }
+ }),
+ dc(obj, "onkeyup", this, function(e){
+ //console.log(this.id + ": onkeyup, e.target = ", e.target, ", lastKeyDownNode was ", dijit._lastKeyDownNode, ", equality is ", (e.target === dijit._lastKeyDownNode));
+ if( (e.keyCode == d.keys.ENTER || e.keyCode == d.keys.SPACE) &&
+ e.target == dijit._lastKeyDownNode && // === breaks greasemonkey
+ !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){
+ //need reset here or have problems in FF when focus returns to trigger element after closing popup/alert
+ dijit._lastKeyDownNode = null;
+ return m(e);
+ }
+ })
+ );
+ }
+ }
+
+ return handles; // _Widget.Handle
+ },
+
+ ////////////////// MISCELLANEOUS METHODS ///////////////////
+
+ _onShow: function(){
+ // summary:
+ // Internal method called when this widget is made visible.
+ // See `onShow` for details.
+ this.onShow();
+ },
+
+ onShow: function(){
+ // summary:
+ // Called when this widget becomes the selected pane in a
+ // `dijit.layout.TabContainer`, `dijit.layout.StackContainer`,
+ // `dijit.layout.AccordionContainer`, etc.
+ //
+ // Also called to indicate display of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
+ // tags:
+ // callback
+ },
+
+ onHide: function(){
+ // summary:
+ // Called when another widget becomes the selected pane in a
+ // `dijit.layout.TabContainer`, `dijit.layout.StackContainer`,
+ // `dijit.layout.AccordionContainer`, etc.
+ //
+ // Also called to indicate hide of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
+ // tags:
+ // callback
+ },
+
+ onClose: function(){
+ // summary:
+ // Called when this widget is being displayed as a popup (ex: a Calendar popped
+ // up from a DateTextBox), and it is hidden.
+ // This is called from the dijit.popup code, and should not be called directly.
+ //
+ // Also used as a parameter for children of `dijit.layout.StackContainer` or subclasses.
+ // Callback if a user tries to close the child. Child will be closed if this function returns true.
+ // tags:
+ // extension
+
+ return true; // Boolean
+ }
+});
+
+})();
+
+}
+
+if(!dojo._hasResource["dojo.string"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.string"] = true;
+dojo.provide("dojo.string");
+
+
+dojo.getObject("string", true, dojo);
+
+/*=====
+dojo.string = {
+ // summary: String utilities for Dojo
+};
+=====*/
+
+dojo.string.rep = function(/*String*/str, /*Integer*/num){
+ // summary:
+ // Efficiently replicate a string `n` times.
+ // str:
+ // the string to replicate
+ // num:
+ // number of times to replicate the string
+
+ if(num <= 0 || !str){ return ""; }
+
+ var buf = [];
+ for(;;){
+ if(num & 1){
+ buf.push(str);
+ }
+ if(!(num >>= 1)){ break; }
+ str += str;
+ }
+ return buf.join(""); // String
+};
+
+dojo.string.pad = function(/*String*/text, /*Integer*/size, /*String?*/ch, /*Boolean?*/end){
+ // summary:
+ // Pad a string to guarantee that it is at least `size` length by
+ // filling with the character `ch` at either the start or end of the
+ // string. Pads at the start, by default.
+ // text:
+ // the string to pad
+ // size:
+ // length to provide padding
+ // ch:
+ // character to pad, defaults to '0'
+ // end:
+ // adds padding at the end if true, otherwise pads at start
+ // example:
+ // | // Fill the string to length 10 with "+" characters on the right. Yields "Dojo++++++".
+ // | dojo.string.pad("Dojo", 10, "+", true);
+
+ if(!ch){
+ ch = '0';
+ }
+ var out = String(text),
+ pad = dojo.string.rep(ch, Math.ceil((size - out.length) / ch.length));
+ return end ? out + pad : pad + out; // String
+};
+
+dojo.string.substitute = function( /*String*/ template,
+ /*Object|Array*/map,
+ /*Function?*/ transform,
+ /*Object?*/ thisObject){
+ // summary:
+ // Performs parameterized substitutions on a string. Throws an
+ // exception if any parameter is unmatched.
+ // template:
+ // a string with expressions in the form `${key}` to be replaced or
+ // `${key:format}` which specifies a format function. keys are case-sensitive.
+ // map:
+ // hash to search for substitutions
+ // transform:
+ // a function to process all parameters before substitution takes
+ // place, e.g. mylib.encodeXML
+ // thisObject:
+ // where to look for optional format function; default to the global
+ // namespace
+ // example:
+ // Substitutes two expressions in a string from an Array or Object
+ // | // returns "File 'foo.html' is not found in directory '/temp'."
+ // | // by providing substitution data in an Array
+ // | dojo.string.substitute(
+ // | "File '${0}' is not found in directory '${1}'.",
+ // | ["foo.html","/temp"]
+ // | );
+ // |
+ // | // also returns "File 'foo.html' is not found in directory '/temp'."
+ // | // but provides substitution data in an Object structure. Dotted
+ // | // notation may be used to traverse the structure.
+ // | dojo.string.substitute(
+ // | "File '${name}' is not found in directory '${info.dir}'.",
+ // | { name: "foo.html", info: { dir: "/temp" } }
+ // | );
+ // example:
+ // Use a transform function to modify the values:
+ // | // returns "file 'foo.html' is not found in directory '/temp'."
+ // | dojo.string.substitute(
+ // | "${0} is not found in ${1}.",
+ // | ["foo.html","/temp"],
+ // | function(str){
+ // | // try to figure out the type
+ // | var prefix = (str.charAt(0) == "/") ? "directory": "file";
+ // | return prefix + " '" + str + "'";
+ // | }
+ // | );
+ // example:
+ // Use a formatter
+ // | // returns "thinger -- howdy"
+ // | dojo.string.substitute(
+ // | "${0:postfix}", ["thinger"], null, {
+ // | postfix: function(value, key){
+ // | return value + " -- howdy";
+ // | }
+ // | }
+ // | );
+
+ thisObject = thisObject || dojo.global;
+ transform = transform ?
+ dojo.hitch(thisObject, transform) : function(v){ return v; };
+
+ return template.replace(/\$\{([^\s\:\}]+)(?:\:([^\s\:\}]+))?\}/g,
+ function(match, key, format){
+ var value = dojo.getObject(key, false, map);
+ if(format){
+ value = dojo.getObject(format, false, thisObject).call(thisObject, value, key);
+ }
+ return transform(value, key).toString();
+ }); // String
+};
+
+/*=====
+dojo.string.trim = function(str){
+ // summary:
+ // Trims whitespace from both sides of the string
+ // str: String
+ // String to be trimmed
+ // returns: String
+ // Returns the trimmed string
+ // description:
+ // This version of trim() was taken from [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript).
+ // The short yet performant version of this function is dojo.trim(),
+ // which is part of Dojo base. Uses String.prototype.trim instead, if available.
+ return ""; // String
+}
+=====*/
+
+dojo.string.trim = String.prototype.trim ?
+ dojo.trim : // aliasing to the native function
+ function(str){
+ str = str.replace(/^\s+/, '');
+ for(var i = str.length - 1; i >= 0; i--){
+ if(/\S/.test(str.charAt(i))){
+ str = str.substring(0, i + 1);
+ break;
+ }
+ }
+ return str;
+ };
+
+}
+
+if(!dojo._hasResource["dojo.cache"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.cache"] = true;
+dojo.provide("dojo.cache");
+
+
+
+/*=====
+dojo.cache = {
+ // summary:
+ // A way to cache string content that is fetchable via `dojo.moduleUrl`.
+};
+=====*/
+
+ var cache = {};
+ dojo.cache = function(/*String||Object*/module, /*String*/url, /*String||Object?*/value){
+ // summary:
+ // A getter and setter for storing the string content associated with the
+ // module and url arguments.
+ // description:
+ // module and url are used to call `dojo.moduleUrl()` to generate a module URL.
+ // If value is specified, the cache value for the moduleUrl will be set to
+ // that value. Otherwise, dojo.cache will fetch the moduleUrl and store it
+ // in its internal cache and return that cached value for the URL. To clear
+ // a cache value pass null for value. Since XMLHttpRequest (XHR) is used to fetch the
+ // the URL contents, only modules on the same domain of the page can use this capability.
+ // The build system can inline the cache values though, to allow for xdomain hosting.
+ // module: String||Object
+ // If a String, the module name to use for the base part of the URL, similar to module argument
+ // to `dojo.moduleUrl`. If an Object, something that has a .toString() method that
+ // generates a valid path for the cache item. For example, a dojo._Url object.
+ // url: String
+ // The rest of the path to append to the path derived from the module argument. If
+ // module is an object, then this second argument should be the "value" argument instead.
+ // value: String||Object?
+ // If a String, the value to use in the cache for the module/url combination.
+ // If an Object, it can have two properties: value and sanitize. The value property
+ // should be the value to use in the cache, and sanitize can be set to true or false,
+ // to indicate if XML declarations should be removed from the value and if the HTML
+ // inside a body tag in the value should be extracted as the real value. The value argument
+ // or the value property on the value argument are usually only used by the build system
+ // as it inlines cache content.
+ // example:
+ // To ask dojo.cache to fetch content and store it in the cache (the dojo["cache"] style
+ // of call is used to avoid an issue with the build system erroneously trying to intern
+ // this example. To get the build system to intern your dojo.cache calls, use the
+ // "dojo.cache" style of call):
+ // | //If template.html contains "<h1>Hello</h1>" that will be
+ // | //the value for the text variable.
+ // | var text = dojo["cache"]("my.module", "template.html");
+ // example:
+ // To ask dojo.cache to fetch content and store it in the cache, and sanitize the input
+ // (the dojo["cache"] style of call is used to avoid an issue with the build system
+ // erroneously trying to intern this example. To get the build system to intern your
+ // dojo.cache calls, use the "dojo.cache" style of call):
+ // | //If template.html contains "<html><body><h1>Hello</h1></body></html>", the
+ // | //text variable will contain just "<h1>Hello</h1>".
+ // | var text = dojo["cache"]("my.module", "template.html", {sanitize: true});
+ // example:
+ // Same example as previous, but demostrates how an object can be passed in as
+ // the first argument, then the value argument can then be the second argument.
+ // | //If template.html contains "<html><body><h1>Hello</h1></body></html>", the
+ // | //text variable will contain just "<h1>Hello</h1>".
+ // | var text = dojo["cache"](new dojo._Url("my/module/template.html"), {sanitize: true});
+
+ //Module could be a string, or an object that has a toString() method
+ //that will return a useful path. If it is an object, then the "url" argument
+ //will actually be the value argument.
+ if(typeof module == "string"){
+ var pathObj = dojo.moduleUrl(module, url);
+ }else{
+ pathObj = module;
+ value = url;
+ }
+ var key = pathObj.toString();
+
+ var val = value;
+ if(value != undefined && !dojo.isString(value)){
+ val = ("value" in value ? value.value : undefined);
+ }
+
+ var sanitize = value && value.sanitize ? true : false;
+
+ if(typeof val == "string"){
+ //We have a string, set cache value
+ val = cache[key] = sanitize ? dojo.cache._sanitize(val) : val;
+ }else if(val === null){
+ //Remove cached value
+ delete cache[key];
+ }else{
+ //Allow cache values to be empty strings. If key property does
+ //not exist, fetch it.
+ if(!(key in cache)){
+ val = dojo._getText(key);
+ cache[key] = sanitize ? dojo.cache._sanitize(val) : val;
+ }
+ val = cache[key];
+ }
+ return val; //String
+ };
+
+ dojo.cache._sanitize = function(/*String*/val){
+ // summary:
+ // Strips <?xml ...?> declarations so that external SVG and XML
+ // documents can be added to a document without worry. Also, if the string
+ // is an HTML document, only the part inside the body tag is returned.
+ // description:
+ // Copied from dijit._Templated._sanitizeTemplateString.
+ if(val){
+ val = val.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, "");
+ var matches = val.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
+ if(matches){
+ val = matches[1];
+ }
+ }else{
+ val = "";
+ }
+ return val; //String
+ };
+
+}
+
+if(!dojo._hasResource["dijit._Templated"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Templated"] = true;
+dojo.provide("dijit._Templated");
+
+
+
+
+
+
+
+dojo.declare("dijit._Templated",
+ null,
+ {
+ // summary:
+ // Mixin for widgets that are instantiated from a template
+
+ // templateString: [protected] String
+ // A string that represents the widget template. Pre-empts the
+ // templatePath. In builds that have their strings "interned", the
+ // templatePath is converted to an inline templateString, thereby
+ // preventing a synchronous network call.
+ //
+ // Use in conjunction with dojo.cache() to load from a file.
+ templateString: null,
+
+ // templatePath: [protected deprecated] String
+ // Path to template (HTML file) for this widget relative to dojo.baseUrl.
+ // Deprecated: use templateString with dojo.cache() instead.
+ templatePath: null,
+
+ // widgetsInTemplate: [protected] Boolean
+ // Should we parse the template to find widgets that might be
+ // declared in markup inside it? False by default.
+ widgetsInTemplate: false,
+
+ // skipNodeCache: [protected] Boolean
+ // If using a cached widget template node poses issues for a
+ // particular widget class, it can set this property to ensure
+ // that its template is always re-built from a string
+ _skipNodeCache: false,
+
+ // _earlyTemplatedStartup: Boolean
+ // A fallback to preserve the 1.0 - 1.3 behavior of children in
+ // templates having their startup called before the parent widget
+ // fires postCreate. Defaults to 'false', causing child widgets to
+ // have their .startup() called immediately before a parent widget
+ // .startup(), but always after the parent .postCreate(). Set to
+ // 'true' to re-enable to previous, arguably broken, behavior.
+ _earlyTemplatedStartup: false,
+
+/*=====
+ // _attachPoints: [private] String[]
+ // List of widget attribute names associated with dojoAttachPoint=... in the
+ // template, ex: ["containerNode", "labelNode"]
+ _attachPoints: [],
+ =====*/
+
+/*=====
+ // _attachEvents: [private] Handle[]
+ // List of connections associated with dojoAttachEvent=... in the
+ // template
+ _attachEvents: [],
+ =====*/
+
+ constructor: function(){
+ this._attachPoints = [];
+ this._attachEvents = [];
+ },
+
+ _stringRepl: function(tmpl){
+ // summary:
+ // Does substitution of ${foo} type properties in template string
+ // tags:
+ // private
+ var className = this.declaredClass, _this = this;
+ // Cache contains a string because we need to do property replacement
+ // do the property replacement
+ return dojo.string.substitute(tmpl, this, function(value, key){
+ if(key.charAt(0) == '!'){ value = dojo.getObject(key.substr(1), false, _this); }
+ if(typeof value == "undefined"){ throw new Error(className+" template:"+key); } // a debugging aide
+ if(value == null){ return ""; }
+
+ // Substitution keys beginning with ! will skip the transform step,
+ // in case a user wishes to insert unescaped markup, e.g. ${!foo}
+ return key.charAt(0) == "!" ? value :
+ // Safer substitution, see heading "Attribute values" in
+ // http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
+ value.toString().replace(/"/g,"&quot;"); //TODO: add &amp? use encodeXML method?
+ }, this);
+ },
+
+ buildRendering: function(){
+ // summary:
+ // Construct the UI for this widget from a template, setting this.domNode.
+ // tags:
+ // protected
+
+ // Lookup cached version of template, and download to cache if it
+ // isn't there already. Returns either a DomNode or a string, depending on
+ // whether or not the template contains ${foo} replacement parameters.
+ var cached = dijit._Templated.getCachedTemplate(this.templatePath, this.templateString, this._skipNodeCache);
+
+ var node;
+ if(dojo.isString(cached)){
+ node = dojo._toDom(this._stringRepl(cached));
+ if(node.nodeType != 1){
+ // Flag common problems such as templates with multiple top level nodes (nodeType == 11)
+ throw new Error("Invalid template: " + cached);
+ }
+ }else{
+ // if it's a node, all we have to do is clone it
+ node = cached.cloneNode(true);
+ }
+
+ this.domNode = node;
+
+ // Call down to _Widget.buildRendering() to get base classes assigned
+ // TODO: change the baseClass assignment to attributeMap
+ this.inherited(arguments);
+
+ // recurse through the node, looking for, and attaching to, our
+ // attachment points and events, which should be defined on the template node.
+ this._attachTemplateNodes(node);
+
+ if(this.widgetsInTemplate){
+ // Store widgets that we need to start at a later point in time
+ var cw = (this._startupWidgets = dojo.parser.parse(node, {
+ noStart: !this._earlyTemplatedStartup,
+ template: true,
+ inherited: {dir: this.dir, lang: this.lang},
+ propsThis: this, // so data-dojo-props of widgets in the template can reference "this" to refer to me
+ scope: "dojo" // even in multi-version mode templates use dojoType/data-dojo-type
+ }));
+
+ this._supportingWidgets = dijit.findWidgets(node);
+
+ this._attachTemplateNodes(cw, function(n,p){
+ return n[p];
+ });
+ }
+
+ this._fillContent(this.srcNodeRef);
+ },
+
+ _fillContent: function(/*DomNode*/ source){
+ // summary:
+ // Relocate source contents to templated container node.
+ // this.containerNode must be able to receive children, or exceptions will be thrown.
+ // tags:
+ // protected
+ var dest = this.containerNode;
+ if(source && dest){
+ while(source.hasChildNodes()){
+ dest.appendChild(source.firstChild);
+ }
+ }
+ },
+
+ _attachTemplateNodes: function(rootNode, getAttrFunc){
+ // summary:
+ // Iterate through the template and attach functions and nodes accordingly.
+ // Alternately, if rootNode is an array of widgets, then will process dojoAttachPoint
+ // etc. for those widgets.
+ // description:
+ // Map widget properties and functions to the handlers specified in
+ // the dom node and it's descendants. This function iterates over all
+ // nodes and looks for these properties:
+ // * dojoAttachPoint
+ // * dojoAttachEvent
+ // * waiRole
+ // * waiState
+ // rootNode: DomNode|Array[Widgets]
+ // the node to search for properties. All children will be searched.
+ // getAttrFunc: Function?
+ // a function which will be used to obtain property for a given
+ // DomNode/Widget
+ // tags:
+ // private
+
+ getAttrFunc = getAttrFunc || function(n,p){ return n.getAttribute(p); };
+
+ var nodes = dojo.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*"));
+ var x = dojo.isArray(rootNode) ? 0 : -1;
+ for(; x<nodes.length; x++){
+ var baseNode = (x == -1) ? rootNode : nodes[x];
+ if(this.widgetsInTemplate && (getAttrFunc(baseNode, "dojoType") || getAttrFunc(baseNode, "data-dojo-type"))){
+ continue;
+ }
+ // Process dojoAttachPoint
+ var attachPoint = getAttrFunc(baseNode, "dojoAttachPoint") || getAttrFunc(baseNode, "data-dojo-attach-point");
+ if(attachPoint){
+ var point, points = attachPoint.split(/\s*,\s*/);
+ while((point = points.shift())){
+ if(dojo.isArray(this[point])){
+ this[point].push(baseNode);
+ }else{
+ this[point]=baseNode;
+ }
+ this._attachPoints.push(point);
+ }
+ }
+
+ // Process dojoAttachEvent
+ var attachEvent = getAttrFunc(baseNode, "dojoAttachEvent") || getAttrFunc(baseNode, "data-dojo-attach-event");;
+ if(attachEvent){
+ // NOTE: we want to support attributes that have the form
+ // "domEvent: nativeEvent; ..."
+ var event, events = attachEvent.split(/\s*,\s*/);
+ var trim = dojo.trim;
+ while((event = events.shift())){
+ if(event){
+ var thisFunc = null;
+ if(event.indexOf(":") != -1){
+ // oh, if only JS had tuple assignment
+ var funcNameArr = event.split(":");
+ event = trim(funcNameArr[0]);
+ thisFunc = trim(funcNameArr[1]);
+ }else{
+ event = trim(event);
+ }
+ if(!thisFunc){
+ thisFunc = event;
+ }
+ this._attachEvents.push(this.connect(baseNode, event, thisFunc));
+ }
+ }
+ }
+
+ // waiRole, waiState
+ // TODO: remove this in 2.0, templates are now using role=... and aria-XXX=... attributes directicly
+ var role = getAttrFunc(baseNode, "waiRole");
+ if(role){
+ dijit.setWaiRole(baseNode, role);
+ }
+ var values = getAttrFunc(baseNode, "waiState");
+ if(values){
+ dojo.forEach(values.split(/\s*,\s*/), function(stateValue){
+ if(stateValue.indexOf('-') != -1){
+ var pair = stateValue.split('-');
+ dijit.setWaiState(baseNode, pair[0], pair[1]);
+ }
+ });
+ }
+ }
+ },
+
+ startup: function(){
+ dojo.forEach(this._startupWidgets, function(w){
+ if(w && !w._started && w.startup){
+ w.startup();
+ }
+ });
+ this.inherited(arguments);
+ },
+
+ destroyRendering: function(){
+ // Delete all attach points to prevent IE6 memory leaks.
+ dojo.forEach(this._attachPoints, function(point){
+ delete this[point];
+ }, this);
+ this._attachPoints = [];
+
+ // And same for event handlers
+ dojo.forEach(this._attachEvents, this.disconnect, this);
+ this._attachEvents = [];
+
+ this.inherited(arguments);
+ }
+ }
+);
+
+// key is either templatePath or templateString; object is either string or DOM tree
+dijit._Templated._templateCache = {};
+
+dijit._Templated.getCachedTemplate = function(templatePath, templateString, alwaysUseString){
+ // summary:
+ // Static method to get a template based on the templatePath or
+ // templateString key
+ // templatePath: String||dojo.uri.Uri
+ // The URL to get the template from.
+ // templateString: String?
+ // a string to use in lieu of fetching the template from a URL. Takes precedence
+ // over templatePath
+ // returns: Mixed
+ // Either string (if there are ${} variables that need to be replaced) or just
+ // a DOM tree (if the node can be cloned directly)
+
+ // is it already cached?
+ var tmplts = dijit._Templated._templateCache;
+ var key = templateString || templatePath;
+ var cached = tmplts[key];
+ if(cached){
+ try{
+ // if the cached value is an innerHTML string (no ownerDocument) or a DOM tree created within the current document, then use the current cached value
+ if(!cached.ownerDocument || cached.ownerDocument == dojo.doc){
+ // string or node of the same document
+ return cached;
+ }
+ }catch(e){ /* squelch */ } // IE can throw an exception if cached.ownerDocument was reloaded
+ dojo.destroy(cached);
+ }
+
+ // If necessary, load template string from template path
+ if(!templateString){
+ templateString = dojo.cache(templatePath, {sanitize: true});
+ }
+ templateString = dojo.string.trim(templateString);
+
+ if(alwaysUseString || templateString.match(/\$\{([^\}]+)\}/g)){
+ // there are variables in the template so all we can do is cache the string
+ return (tmplts[key] = templateString); //String
+ }else{
+ // there are no variables in the template so we can cache the DOM tree
+ var node = dojo._toDom(templateString);
+ if(node.nodeType != 1){
+ throw new Error("Invalid template: " + templateString);
+ }
+ return (tmplts[key] = node); //Node
+ }
+};
+
+if(dojo.isIE){
+ dojo.addOnWindowUnload(function(){
+ var cache = dijit._Templated._templateCache;
+ for(var key in cache){
+ var value = cache[key];
+ if(typeof value == "object"){ // value is either a string or a DOM node template
+ dojo.destroy(value);
+ }
+ delete cache[key];
+ }
+ });
+}
+
+// These arguments can be specified for widgets which are used in templates.
+// Since any widget can be specified as sub widgets in template, mix it
+// into the base widget class. (This is a hack, but it's effective.)
+dojo.extend(dijit._Widget,{
+ dojoAttachEvent: "",
+ dojoAttachPoint: "",
+ waiRole: "",
+ waiState:""
+});
+
+}
+
+if(!dojo._hasResource["dijit._Container"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Container"] = true;
+dojo.provide("dijit._Container");
+
+
+
+dojo.declare("dijit._Container",
+ null,
+ {
+ // summary:
+ // Mixin for widgets that contain a set of widget children.
+ // description:
+ // Use this mixin for widgets that needs to know about and
+ // keep track of their widget children. Suitable for widgets like BorderContainer
+ // and TabContainer which contain (only) a set of child widgets.
+ //
+ // It's not suitable for widgets like ContentPane
+ // which contains mixed HTML (plain DOM nodes in addition to widgets),
+ // and where contained widgets are not necessarily directly below
+ // this.containerNode. In that case calls like addChild(node, position)
+ // wouldn't make sense.
+
+ // isContainer: [protected] Boolean
+ // Indicates that this widget acts as a "parent" to the descendant widgets.
+ // When the parent is started it will call startup() on the child widgets.
+ // See also `isLayoutContainer`.
+ isContainer: true,
+
+ buildRendering: function(){
+ this.inherited(arguments);
+ if(!this.containerNode){
+ // all widgets with descendants must set containerNode
+ this.containerNode = this.domNode;
+ }
+ },
+
+ addChild: function(/*dijit._Widget*/ widget, /*int?*/ insertIndex){
+ // summary:
+ // Makes the given widget a child of this widget.
+ // description:
+ // Inserts specified child widget's dom node as a child of this widget's
+ // container node, and possibly does other processing (such as layout).
+
+ var refNode = this.containerNode;
+ if(insertIndex && typeof insertIndex == "number"){
+ var children = this.getChildren();
+ if(children && children.length >= insertIndex){
+ refNode = children[insertIndex-1].domNode;
+ insertIndex = "after";
+ }
+ }
+ dojo.place(widget.domNode, refNode, insertIndex);
+
+ // If I've been started but the child widget hasn't been started,
+ // start it now. Make sure to do this after widget has been
+ // inserted into the DOM tree, so it can see that it's being controlled by me,
+ // so it doesn't try to size itself.
+ if(this._started && !widget._started){
+ widget.startup();
+ }
+ },
+
+ removeChild: function(/*Widget or int*/ widget){
+ // summary:
+ // Removes the passed widget instance from this widget but does
+ // not destroy it. You can also pass in an integer indicating
+ // the index within the container to remove
+
+ if(typeof widget == "number"){
+ widget = this.getChildren()[widget];
+ }
+
+ if(widget){
+ var node = widget.domNode;
+ if(node && node.parentNode){
+ node.parentNode.removeChild(node); // detach but don't destroy
+ }
+ }
+ },
+
+ hasChildren: function(){
+ // summary:
+ // Returns true if widget has children, i.e. if this.containerNode contains something.
+ return this.getChildren().length > 0; // Boolean
+ },
+
+ destroyDescendants: function(/*Boolean*/ preserveDom){
+ // summary:
+ // Destroys all the widgets inside this.containerNode,
+ // but not this widget itself
+ dojo.forEach(this.getChildren(), function(child){ child.destroyRecursive(preserveDom); });
+ },
+
+ _getSiblingOfChild: function(/*dijit._Widget*/ child, /*int*/ dir){
+ // summary:
+ // Get the next or previous widget sibling of child
+ // dir:
+ // if 1, get the next sibling
+ // if -1, get the previous sibling
+ // tags:
+ // private
+ var node = child.domNode,
+ which = (dir>0 ? "nextSibling" : "previousSibling");
+ do{
+ node = node[which];
+ }while(node && (node.nodeType != 1 || !dijit.byNode(node)));
+ return node && dijit.byNode(node); // dijit._Widget
+ },
+
+ getIndexOfChild: function(/*dijit._Widget*/ child){
+ // summary:
+ // Gets the index of the child in this container or -1 if not found
+ return dojo.indexOf(this.getChildren(), child); // int
+ },
+
+ startup: function(){
+ // summary:
+ // Called after all the widgets have been instantiated and their
+ // dom nodes have been inserted somewhere under dojo.doc.body.
+ //
+ // Widgets should override this method to do any initialization
+ // dependent on other widgets existing, and then call
+ // this superclass method to finish things off.
+ //
+ // startup() in subclasses shouldn't do anything
+ // size related because the size of the widget hasn't been set yet.
+
+ if(this._started){ return; }
+
+ // Startup all children of this widget
+ dojo.forEach(this.getChildren(), function(child){ child.startup(); });
+
+ this.inherited(arguments);
+ }
+ }
+);
+
+}
+
+if(!dojo._hasResource["dijit._Contained"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Contained"] = true;
+dojo.provide("dijit._Contained");
+
+
+
+dojo.declare("dijit._Contained",
+ null,
+ {
+ // summary:
+ // Mixin for widgets that are children of a container widget
+ //
+ // example:
+ // | // make a basic custom widget that knows about it's parents
+ // | dojo.declare("my.customClass",[dijit._Widget,dijit._Contained],{});
+
+ getParent: function(){
+ // summary:
+ // Returns the parent widget of this widget, assuming the parent
+ // specifies isContainer
+ var parent = dijit.getEnclosingWidget(this.domNode.parentNode);
+ return parent && parent.isContainer ? parent : null;
+ },
+
+ _getSibling: function(/*String*/ which){
+ // summary:
+ // Returns next or previous sibling
+ // which:
+ // Either "next" or "previous"
+ // tags:
+ // private
+ var node = this.domNode;
+ do{
+ node = node[which+"Sibling"];
+ }while(node && node.nodeType != 1);
+ return node && dijit.byNode(node); // dijit._Widget
+ },
+
+ getPreviousSibling: function(){
+ // summary:
+ // Returns null if this is the first child of the parent,
+ // otherwise returns the next element sibling to the "left".
+
+ return this._getSibling("previous"); // dijit._Widget
+ },
+
+ getNextSibling: function(){
+ // summary:
+ // Returns null if this is the last child of the parent,
+ // otherwise returns the next element sibling to the "right".
+
+ return this._getSibling("next"); // dijit._Widget
+ },
+
+ getIndexInParent: function(){
+ // summary:
+ // Returns the index of this widget within its container parent.
+ // It returns -1 if the parent does not exist, or if the parent
+ // is not a dijit._Container
+
+ var p = this.getParent();
+ if(!p || !p.getIndexOfChild){
+ return -1; // int
+ }
+ return p.getIndexOfChild(this); // int
+ }
+ }
+ );
+
+}
+
+if(!dojo._hasResource["dijit.layout._LayoutWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.layout._LayoutWidget"] = true;
+dojo.provide("dijit.layout._LayoutWidget");
+
+
+
+
+
+
+dojo.declare("dijit.layout._LayoutWidget",
+ [dijit._Widget, dijit._Container, dijit._Contained],
+ {
+ // summary:
+ // Base class for a _Container widget which is responsible for laying out its children.
+ // Widgets which mixin this code must define layout() to manage placement and sizing of the children.
+
+ // baseClass: [protected extension] String
+ // This class name is applied to the widget's domNode
+ // and also may be used to generate names for sub nodes,
+ // for example dijitTabContainer-content.
+ baseClass: "dijitLayoutContainer",
+
+ // isLayoutContainer: [protected] Boolean
+ // Indicates that this widget is going to call resize() on its
+ // children widgets, setting their size, when they become visible.
+ isLayoutContainer: true,
+
+ buildRendering: function(){
+ this.inherited(arguments);
+ dojo.addClass(this.domNode, "dijitContainer");
+ },
+
+ startup: function(){
+ // summary:
+ // Called after all the widgets have been instantiated and their
+ // dom nodes have been inserted somewhere under dojo.doc.body.
+ //
+ // Widgets should override this method to do any initialization
+ // dependent on other widgets existing, and then call
+ // this superclass method to finish things off.
+ //
+ // startup() in subclasses shouldn't do anything
+ // size related because the size of the widget hasn't been set yet.
+
+ if(this._started){ return; }
+
+ // Need to call inherited first - so that child widgets get started
+ // up correctly
+ this.inherited(arguments);
+
+ // If I am a not being controlled by a parent layout widget...
+ var parent = this.getParent && this.getParent()
+ if(!(parent && parent.isLayoutContainer)){
+ // Do recursive sizing and layout of all my descendants
+ // (passing in no argument to resize means that it has to glean the size itself)
+ this.resize();
+
+ // Since my parent isn't a layout container, and my style *may be* width=height=100%
+ // or something similar (either set directly or via a CSS class),
+ // monitor when my size changes so that I can re-layout.
+ // For browsers where I can't directly monitor when my size changes,
+ // monitor when the viewport changes size, which *may* indicate a size change for me.
+ this.connect(dojo.isIE ? this.domNode : dojo.global, 'onresize', function(){
+ // Using function(){} closure to ensure no arguments to resize.
+ this.resize();
+ });
+ }
+ },
+
+ resize: function(changeSize, resultSize){
+ // summary:
+ // Call this to resize a widget, or after its size has changed.
+ // description:
+ // Change size mode:
+ // When changeSize is specified, changes the marginBox of this widget
+ // and forces it to relayout its contents accordingly.
+ // changeSize may specify height, width, or both.
+ //
+ // If resultSize is specified it indicates the size the widget will
+ // become after changeSize has been applied.
+ //
+ // Notification mode:
+ // When changeSize is null, indicates that the caller has already changed
+ // the size of the widget, or perhaps it changed because the browser
+ // window was resized. Tells widget to relayout its contents accordingly.
+ //
+ // If resultSize is also specified it indicates the size the widget has
+ // become.
+ //
+ // In either mode, this method also:
+ // 1. Sets this._borderBox and this._contentBox to the new size of
+ // the widget. Queries the current domNode size if necessary.
+ // 2. Calls layout() to resize contents (and maybe adjust child widgets).
+ //
+ // changeSize: Object?
+ // Sets the widget to this margin-box size and position.
+ // May include any/all of the following properties:
+ // | {w: int, h: int, l: int, t: int}
+ //
+ // resultSize: Object?
+ // The margin-box size of this widget after applying changeSize (if
+ // changeSize is specified). If caller knows this size and
+ // passes it in, we don't need to query the browser to get the size.
+ // | {w: int, h: int}
+
+ var node = this.domNode;
+
+ // set margin box size, unless it wasn't specified, in which case use current size
+ if(changeSize){
+ dojo.marginBox(node, changeSize);
+
+ // set offset of the node
+ if(changeSize.t){ node.style.top = changeSize.t + "px"; }
+ if(changeSize.l){ node.style.left = changeSize.l + "px"; }
+ }
+
+ // If either height or width wasn't specified by the user, then query node for it.
+ // But note that setting the margin box and then immediately querying dimensions may return
+ // inaccurate results, so try not to depend on it.
+ var mb = resultSize || {};
+ dojo.mixin(mb, changeSize || {}); // changeSize overrides resultSize
+ if( !("h" in mb) || !("w" in mb) ){
+ mb = dojo.mixin(dojo.marginBox(node), mb); // just use dojo.marginBox() to fill in missing values
+ }
+
+ // Compute and save the size of my border box and content box
+ // (w/out calling dojo.contentBox() since that may fail if size was recently set)
+ var cs = dojo.getComputedStyle(node);
+ var me = dojo._getMarginExtents(node, cs);
+ var be = dojo._getBorderExtents(node, cs);
+ var bb = (this._borderBox = {
+ w: mb.w - (me.w + be.w),
+ h: mb.h - (me.h + be.h)
+ });
+ var pe = dojo._getPadExtents(node, cs);
+ this._contentBox = {
+ l: dojo._toPixelValue(node, cs.paddingLeft),
+ t: dojo._toPixelValue(node, cs.paddingTop),
+ w: bb.w - pe.w,
+ h: bb.h - pe.h
+ };
+
+ // Callback for widget to adjust size of its children
+ this.layout();
+ },
+
+ layout: function(){
+ // summary:
+ // Widgets override this method to size and position their contents/children.
+ // When this is called this._contentBox is guaranteed to be set (see resize()).
+ //
+ // This is called after startup(), and also when the widget's size has been
+ // changed.
+ // tags:
+ // protected extension
+ },
+
+ _setupChild: function(/*dijit._Widget*/child){
+ // summary:
+ // Common setup for initial children and children which are added after startup
+ // tags:
+ // protected extension
+
+ var cls = this.baseClass + "-child "
+ + (child.baseClass ? this.baseClass + "-" + child.baseClass : "");
+ dojo.addClass(child.domNode, cls);
+ },
+
+ addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
+ // Overrides _Container.addChild() to call _setupChild()
+ this.inherited(arguments);
+ if(this._started){
+ this._setupChild(child);
+ }
+ },
+
+ removeChild: function(/*dijit._Widget*/ child){
+ // Overrides _Container.removeChild() to remove class added by _setupChild()
+ var cls = this.baseClass + "-child"
+ + (child.baseClass ?
+ " " + this.baseClass + "-" + child.baseClass : "");
+ dojo.removeClass(child.domNode, cls);
+
+ this.inherited(arguments);
+ }
+ }
+);
+
+dijit.layout.marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){
+ // summary:
+ // Given the margin-box size of a node, return its content box size.
+ // Functions like dojo.contentBox() but is more reliable since it doesn't have
+ // to wait for the browser to compute sizes.
+ var cs = dojo.getComputedStyle(node);
+ var me = dojo._getMarginExtents(node, cs);
+ var pb = dojo._getPadBorderExtents(node, cs);
+ return {
+ l: dojo._toPixelValue(node, cs.paddingLeft),
+ t: dojo._toPixelValue(node, cs.paddingTop),
+ w: mb.w - (me.w + pb.w),
+ h: mb.h - (me.h + pb.h)
+ };
+};
+
+(function(){
+ var capitalize = function(word){
+ return word.substring(0,1).toUpperCase() + word.substring(1);
+ };
+
+ var size = function(widget, dim){
+ // size the child
+ widget.resize ? widget.resize(dim) : dojo.marginBox(widget.domNode, dim);
+
+ // record child's size, but favor our own numbers when we have them.
+ // the browser lies sometimes
+ dojo.mixin(widget, dojo.marginBox(widget.domNode));
+ dojo.mixin(widget, dim);
+ };
+
+ dijit.layout.layoutChildren = function(/*DomNode*/ container, /*Object*/ dim, /*Widget[]*/ children,
+ /*String?*/ changedRegionId, /*Number?*/ changedRegionSize){
+ // summary
+ // Layout a bunch of child dom nodes within a parent dom node
+ // container:
+ // parent node
+ // dim:
+ // {l, t, w, h} object specifying dimensions of container into which to place children
+ // children:
+ // an array of Widgets or at least objects containing:
+ // * domNode: pointer to DOM node to position
+ // * region or layoutAlign: position to place DOM node
+ // * resize(): (optional) method to set size of node
+ // * id: (optional) Id of widgets, referenced from resize object, below.
+ // changedRegionId:
+ // If specified, the slider for the region with the specified id has been dragged, and thus
+ // the region's height or width should be adjusted according to changedRegionSize
+ // changedRegionSize:
+ // See changedRegionId.
+
+ // copy dim because we are going to modify it
+ dim = dojo.mixin({}, dim);
+
+ dojo.addClass(container, "dijitLayoutContainer");
+
+ // Move "client" elements to the end of the array for layout. a11y dictates that the author
+ // needs to be able to put them in the document in tab-order, but this algorithm requires that
+ // client be last. TODO: move these lines to LayoutContainer? Unneeded other places I think.
+ children = dojo.filter(children, function(item){ return item.region != "center" && item.layoutAlign != "client"; })
+ .concat(dojo.filter(children, function(item){ return item.region == "center" || item.layoutAlign == "client"; }));
+
+ // set positions/sizes
+ dojo.forEach(children, function(child){
+ var elm = child.domNode,
+ pos = (child.region || child.layoutAlign);
+
+ // set elem to upper left corner of unused space; may move it later
+ var elmStyle = elm.style;
+ elmStyle.left = dim.l+"px";
+ elmStyle.top = dim.t+"px";
+ elmStyle.bottom = elmStyle.right = "auto";
+
+ dojo.addClass(elm, "dijitAlign" + capitalize(pos));
+
+ // Size adjustments to make to this child widget
+ var sizeSetting = {};
+
+ // Check for optional size adjustment due to splitter drag (height adjustment for top/bottom align
+ // panes and width adjustment for left/right align panes.
+ if(changedRegionId && changedRegionId == child.id){
+ sizeSetting[child.region == "top" || child.region == "bottom" ? "h" : "w"] = changedRegionSize;
+ }
+
+ // set size && adjust record of remaining space.
+ // note that setting the width of a <div> may affect its height.
+ if(pos == "top" || pos == "bottom"){
+ sizeSetting.w = dim.w;
+ size(child, sizeSetting);
+ dim.h -= child.h;
+ if(pos == "top"){
+ dim.t += child.h;
+ }else{
+ elmStyle.top = dim.t + dim.h + "px";
+ }
+ }else if(pos == "left" || pos == "right"){
+ sizeSetting.h = dim.h;
+ size(child, sizeSetting);
+ dim.w -= child.w;
+ if(pos == "left"){
+ dim.l += child.w;
+ }else{
+ elmStyle.left = dim.l + dim.w + "px";
+ }
+ }else if(pos == "client" || pos == "center"){
+ size(child, dim);
+ }
+ });
+ };
+
+})();
+
+}
+
+if(!dojo._hasResource["dijit._CssStateMixin"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._CssStateMixin"] = true;
+dojo.provide("dijit._CssStateMixin");
+
+
+
+dojo.declare("dijit._CssStateMixin", [], {
+ // summary:
+ // Mixin for widgets to set CSS classes on the widget DOM nodes depending on hover/mouse press/focus
+ // state changes, and also higher-level state changes such becoming disabled or selected.
+ //
+ // description:
+ // By mixing this class into your widget, and setting the this.baseClass attribute, it will automatically
+ // maintain CSS classes on the widget root node (this.domNode) depending on hover,
+ // active, focus, etc. state. Ex: with a baseClass of dijitButton, it will apply the classes
+ // dijitButtonHovered and dijitButtonActive, as the user moves the mouse over the widget and clicks it.
+ //
+ // It also sets CSS like dijitButtonDisabled based on widget semantic state.
+ //
+ // By setting the cssStateNodes attribute, a widget can also track events on subnodes (like buttons
+ // within the widget).
+
+ // cssStateNodes: [protected] Object
+ // List of sub-nodes within the widget that need CSS classes applied on mouse hover/press and focus
+ //.
+ // Each entry in the hash is a an attachpoint names (like "upArrowButton") mapped to a CSS class names
+ // (like "dijitUpArrowButton"). Example:
+ // | {
+ // | "upArrowButton": "dijitUpArrowButton",
+ // | "downArrowButton": "dijitDownArrowButton"
+ // | }
+ // The above will set the CSS class dijitUpArrowButton to the this.upArrowButton DOMNode when it
+ // is hovered, etc.
+ cssStateNodes: {},
+
+ // hovering: [readonly] Boolean
+ // True if cursor is over this widget
+ hovering: false,
+
+ // active: [readonly] Boolean
+ // True if mouse was pressed while over this widget, and hasn't been released yet
+ active: false,
+
+ _applyAttributes: function(){
+ // This code would typically be in postCreate(), but putting in _applyAttributes() for
+ // performance: so the class changes happen before DOM is inserted into the document.
+ // Change back to postCreate() in 2.0. See #11635.
+
+ this.inherited(arguments);
+
+ // Automatically monitor mouse events (essentially :hover and :active) on this.domNode
+ dojo.forEach(["onmouseenter", "onmouseleave", "onmousedown"], function(e){
+ this.connect(this.domNode, e, "_cssMouseEvent");
+ }, this);
+
+ // Monitoring changes to disabled, readonly, etc. state, and update CSS class of root node
+ dojo.forEach(["disabled", "readOnly", "checked", "selected", "focused", "state", "hovering", "active"], function(attr){
+ this.watch(attr, dojo.hitch(this, "_setStateClass"));
+ }, this);
+
+ // Events on sub nodes within the widget
+ for(var ap in this.cssStateNodes){
+ this._trackMouseState(this[ap], this.cssStateNodes[ap]);
+ }
+ // Set state initially; there's probably no hover/active/focus state but widget might be
+ // disabled/readonly/checked/selected so we want to set CSS classes for those conditions.
+ this._setStateClass();
+ },
+
+ _cssMouseEvent: function(/*Event*/ event){
+ // summary:
+ // Sets hovering and active properties depending on mouse state,
+ // which triggers _setStateClass() to set appropriate CSS classes for this.domNode.
+
+ if(!this.disabled){
+ switch(event.type){
+ case "mouseenter":
+ case "mouseover": // generated on non-IE browsers even though we connected to mouseenter
+ this._set("hovering", true);
+ this._set("active", this._mouseDown);
+ break;
+
+ case "mouseleave":
+ case "mouseout": // generated on non-IE browsers even though we connected to mouseleave
+ this._set("hovering", false);
+ this._set("active", false);
+ break;
+
+ case "mousedown" :
+ this._set("active", true);
+ this._mouseDown = true;
+ // Set a global event to handle mouseup, so it fires properly
+ // even if the cursor leaves this.domNode before the mouse up event.
+ // Alternately could set active=false on mouseout.
+ var mouseUpConnector = this.connect(dojo.body(), "onmouseup", function(){
+ this._mouseDown = false;
+ this._set("active", false);
+ this.disconnect(mouseUpConnector);
+ });
+ break;
+ }
+ }
+ },
+
+ _setStateClass: function(){
+ // summary:
+ // Update the visual state of the widget by setting the css classes on this.domNode
+ // (or this.stateNode if defined) by combining this.baseClass with
+ // various suffixes that represent the current widget state(s).
+ //
+ // description:
+ // In the case where a widget has multiple
+ // states, it sets the class based on all possible
+ // combinations. For example, an invalid form widget that is being hovered
+ // will be "dijitInput dijitInputInvalid dijitInputHover dijitInputInvalidHover".
+ //
+ // The widget may have one or more of the following states, determined
+ // by this.state, this.checked, this.valid, and this.selected:
+ // - Error - ValidationTextBox sets this.state to "Error" if the current input value is invalid
+ // - Incomplete - ValidationTextBox sets this.state to "Incomplete" if the current input value is not finished yet
+ // - Checked - ex: a checkmark or a ToggleButton in a checked state, will have this.checked==true
+ // - Selected - ex: currently selected tab will have this.selected==true
+ //
+ // In addition, it may have one or more of the following states,
+ // based on this.disabled and flags set in _onMouse (this.active, this.hovering) and from focus manager (this.focused):
+ // - Disabled - if the widget is disabled
+ // - Active - if the mouse (or space/enter key?) is being pressed down
+ // - Focused - if the widget has focus
+ // - Hover - if the mouse is over the widget
+
+ // Compute new set of classes
+ var newStateClasses = this.baseClass.split(" ");
+
+ function multiply(modifier){
+ newStateClasses = newStateClasses.concat(dojo.map(newStateClasses, function(c){ return c+modifier; }), "dijit"+modifier);
+ }
+
+ if(!this.isLeftToRight()){
+ // For RTL mode we need to set an addition class like dijitTextBoxRtl.
+ multiply("Rtl");
+ }
+
+ if(this.checked){
+ multiply("Checked");
+ }
+ if(this.state){
+ multiply(this.state);
+ }
+ if(this.selected){
+ multiply("Selected");
+ }
+
+ if(this.disabled){
+ multiply("Disabled");
+ }else if(this.readOnly){
+ multiply("ReadOnly");
+ }else{
+ if(this.active){
+ multiply("Active");
+ }else if(this.hovering){
+ multiply("Hover");
+ }
+ }
+
+ if(this._focused){
+ multiply("Focused");
+ }
+
+ // Remove old state classes and add new ones.
+ // For performance concerns we only write into domNode.className once.
+ var tn = this.stateNode || this.domNode,
+ classHash = {}; // set of all classes (state and otherwise) for node
+
+ dojo.forEach(tn.className.split(" "), function(c){ classHash[c] = true; });
+
+ if("_stateClasses" in this){
+ dojo.forEach(this._stateClasses, function(c){ delete classHash[c]; });
+ }
+
+ dojo.forEach(newStateClasses, function(c){ classHash[c] = true; });
+
+ var newClasses = [];
+ for(var c in classHash){
+ newClasses.push(c);
+ }
+ tn.className = newClasses.join(" ");
+
+ this._stateClasses = newStateClasses;
+ },
+
+ _trackMouseState: function(/*DomNode*/ node, /*String*/ clazz){
+ // summary:
+ // Track mouse/focus events on specified node and set CSS class on that node to indicate
+ // current state. Usually not called directly, but via cssStateNodes attribute.
+ // description:
+ // Given class=foo, will set the following CSS class on the node
+ // - fooActive: if the user is currently pressing down the mouse button while over the node
+ // - fooHover: if the user is hovering the mouse over the node, but not pressing down a button
+ // - fooFocus: if the node is focused
+ //
+ // Note that it won't set any classes if the widget is disabled.
+ // node: DomNode
+ // Should be a sub-node of the widget, not the top node (this.domNode), since the top node
+ // is handled specially and automatically just by mixing in this class.
+ // clazz: String
+ // CSS class name (ex: dijitSliderUpArrow).
+
+ // Current state of node (initially false)
+ // NB: setting specifically to false because dojo.toggleClass() needs true boolean as third arg
+ var hovering=false, active=false, focused=false;
+
+ var self = this,
+ cn = dojo.hitch(this, "connect", node);
+
+ function setClass(){
+ var disabled = ("disabled" in self && self.disabled) || ("readonly" in self && self.readonly);
+ dojo.toggleClass(node, clazz+"Hover", hovering && !active && !disabled);
+ dojo.toggleClass(node, clazz+"Active", active && !disabled);
+ dojo.toggleClass(node, clazz+"Focused", focused && !disabled);
+ }
+
+ // Mouse
+ cn("onmouseenter", function(){
+ hovering = true;
+ setClass();
+ });
+ cn("onmouseleave", function(){
+ hovering = false;
+ active = false;
+ setClass();
+ });
+ cn("onmousedown", function(){
+ active = true;
+ setClass();
+ });
+ cn("onmouseup", function(){
+ active = false;
+ setClass();
+ });
+
+ // Focus
+ cn("onfocus", function(){
+ focused = true;
+ setClass();
+ });
+ cn("onblur", function(){
+ focused = false;
+ setClass();
+ });
+
+ // Just in case widget is enabled/disabled while it has focus/hover/active state.
+ // Maybe this is overkill.
+ this.watch("disabled", setClass);
+ this.watch("readOnly", setClass);
+ }
+});
+
+}
+
+if(!dojo._hasResource["dijit.form._FormWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form._FormWidget"] = true;
+dojo.provide("dijit.form._FormWidget");
+
+
+
+
+
+
+
+dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated, dijit._CssStateMixin],
+ {
+ // summary:
+ // Base class for widgets corresponding to native HTML elements such as <checkbox> or <button>,
+ // which can be children of a <form> node or a `dijit.form.Form` widget.
+ //
+ // description:
+ // Represents a single HTML element.
+ // All these widgets should have these attributes just like native HTML input elements.
+ // You can set them during widget construction or afterwards, via `dijit._Widget.attr`.
+ //
+ // They also share some common methods.
+
+ // name: [const] String
+ // Name used when submitting form; same as "name" attribute or plain HTML elements
+ name: "",
+
+ // alt: String
+ // Corresponds to the native HTML <input> element's attribute.
+ alt: "",
+
+ // value: String
+ // Corresponds to the native HTML <input> element's attribute.
+ value: "",
+
+ // type: String
+ // Corresponds to the native HTML <input> element's attribute.
+ type: "text",
+
+ // tabIndex: Integer
+ // Order fields are traversed when user hits the tab key
+ tabIndex: "0",
+
+ // disabled: Boolean
+ // Should this widget respond to user input?
+ // In markup, this is specified as "disabled='disabled'", or just "disabled".
+ disabled: false,
+
+ // intermediateChanges: Boolean
+ // Fires onChange for each value change or only on demand
+ intermediateChanges: false,
+
+ // scrollOnFocus: Boolean
+ // On focus, should this widget scroll into view?
+ scrollOnFocus: true,
+
+ // These mixins assume that the focus node is an INPUT, as many but not all _FormWidgets are.
+ attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
+ value: "focusNode",
+ id: "focusNode",
+ tabIndex: "focusNode",
+ alt: "focusNode",
+ title: "focusNode"
+ }),
+
+ postMixInProperties: function(){
+ // Setup name=foo string to be referenced from the template (but only if a name has been specified)
+ // Unfortunately we can't use attributeMap to set the name due to IE limitations, see #8660
+ // Regarding escaping, see heading "Attribute values" in
+ // http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
+ this.nameAttrSetting = this.name ? ('name="' + this.name.replace(/'/g, "&quot;") + '"') : '';
+ this.inherited(arguments);
+ },
+
+ postCreate: function(){
+ this.inherited(arguments);
+ this.connect(this.domNode, "onmousedown", "_onMouseDown");
+ },
+
+ _setDisabledAttr: function(/*Boolean*/ value){
+ this._set("disabled", value);
+ dojo.attr(this.focusNode, 'disabled', value);
+ if(this.valueNode){
+ dojo.attr(this.valueNode, 'disabled', value);
+ }
+ dijit.setWaiState(this.focusNode, "disabled", value);
+
+ if(value){
+ // reset these, because after the domNode is disabled, we can no longer receive
+ // mouse related events, see #4200
+ this._set("hovering", false);
+ this._set("active", false);
+
+ // clear tab stop(s) on this widget's focusable node(s) (ComboBox has two focusable nodes)
+ var attachPointNames = "tabIndex" in this.attributeMap ? this.attributeMap.tabIndex : "focusNode";
+ dojo.forEach(dojo.isArray(attachPointNames) ? attachPointNames : [attachPointNames], function(attachPointName){
+ var node = this[attachPointName];
+ // complex code because tabIndex=-1 on a <div> doesn't work on FF
+ if(dojo.isWebKit || dijit.hasDefaultTabStop(node)){ // see #11064 about webkit bug
+ node.setAttribute('tabIndex', "-1");
+ }else{
+ node.removeAttribute('tabIndex');
+ }
+ }, this);
+ }else{
+ if(this.tabIndex != ""){
+ this.focusNode.setAttribute('tabIndex', this.tabIndex);
+ }
+ }
+ },
+
+ setDisabled: function(/*Boolean*/ disabled){
+ // summary:
+ // Deprecated. Use set('disabled', ...) instead.
+ dojo.deprecated("setDisabled("+disabled+") is deprecated. Use set('disabled',"+disabled+") instead.", "", "2.0");
+ this.set('disabled', disabled);
+ },
+
+ _onFocus: function(e){
+ if(this.scrollOnFocus){
+ dojo.window.scrollIntoView(this.domNode);
+ }
+ this.inherited(arguments);
+ },
+
+ isFocusable: function(){
+ // summary:
+ // Tells if this widget is focusable or not. Used internally by dijit.
+ // tags:
+ // protected
+ return !this.disabled && this.focusNode && (dojo.style(this.domNode, "display") != "none");
+ },
+
+ focus: function(){
+ // summary:
+ // Put focus on this widget
+ if(!this.disabled){
+ dijit.focus(this.focusNode);
+ }
+ },
+
+ compare: function(/*anything*/ val1, /*anything*/ val2){
+ // summary:
+ // Compare 2 values (as returned by get('value') for this widget).
+ // tags:
+ // protected
+ if(typeof val1 == "number" && typeof val2 == "number"){
+ return (isNaN(val1) && isNaN(val2)) ? 0 : val1 - val2;
+ }else if(val1 > val2){
+ return 1;
+ }else if(val1 < val2){
+ return -1;
+ }else{
+ return 0;
+ }
+ },
+
+ onChange: function(newValue){
+ // summary:
+ // Callback when this widget's value is changed.
+ // tags:
+ // callback
+ },
+
+ // _onChangeActive: [private] Boolean
+ // Indicates that changes to the value should call onChange() callback.
+ // This is false during widget initialization, to avoid calling onChange()
+ // when the initial value is set.
+ _onChangeActive: false,
+
+ _handleOnChange: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
+ // summary:
+ // Called when the value of the widget is set. Calls onChange() if appropriate
+ // newValue:
+ // the new value
+ // priorityChange:
+ // For a slider, for example, dragging the slider is priorityChange==false,
+ // but on mouse up, it's priorityChange==true. If intermediateChanges==false,
+ // onChange is only called form priorityChange=true events.
+ // tags:
+ // private
+ if(this._lastValueReported == undefined && (priorityChange === null || !this._onChangeActive)){
+ // this block executes not for a change, but during initialization,
+ // and is used to store away the original value (or for ToggleButton, the original checked state)
+ this._resetValue = this._lastValueReported = newValue;
+ }
+ this._pendingOnChange = this._pendingOnChange
+ || (typeof newValue != typeof this._lastValueReported)
+ || (this.compare(newValue, this._lastValueReported) != 0);
+ if((this.intermediateChanges || priorityChange || priorityChange === undefined) && this._pendingOnChange){
+ this._lastValueReported = newValue;
+ this._pendingOnChange = false;
+ if(this._onChangeActive){
+ if(this._onChangeHandle){
+ clearTimeout(this._onChangeHandle);
+ }
+ // setTimout allows hidden value processing to run and
+ // also the onChange handler can safely adjust focus, etc
+ this._onChangeHandle = setTimeout(dojo.hitch(this,
+ function(){
+ this._onChangeHandle = null;
+ this.onChange(newValue);
+ }), 0); // try to collapse multiple onChange's fired faster than can be processed
+ }
+ }
+ },
+
+ create: function(){
+ // Overrides _Widget.create()
+ this.inherited(arguments);
+ this._onChangeActive = true;
+ },
+
+ destroy: function(){
+ if(this._onChangeHandle){ // destroy called before last onChange has fired
+ clearTimeout(this._onChangeHandle);
+ this.onChange(this._lastValueReported);
+ }
+ this.inherited(arguments);
+ },
+
+ setValue: function(/*String*/ value){
+ // summary:
+ // Deprecated. Use set('value', ...) instead.
+ dojo.deprecated("dijit.form._FormWidget:setValue("+value+") is deprecated. Use set('value',"+value+") instead.", "", "2.0");
+ this.set('value', value);
+ },
+
+ getValue: function(){
+ // summary:
+ // Deprecated. Use get('value') instead.
+ dojo.deprecated(this.declaredClass+"::getValue() is deprecated. Use get('value') instead.", "", "2.0");
+ return this.get('value');
+ },
+
+ _onMouseDown: function(e){
+ // If user clicks on the button, even if the mouse is released outside of it,
+ // this button should get focus (to mimics native browser buttons).
+ // This is also needed on chrome because otherwise buttons won't get focus at all,
+ // which leads to bizarre focus restore on Dialog close etc.
+ if(!e.ctrlKey && dojo.mouseButtons.isLeft(e) && this.isFocusable()){ // !e.ctrlKey to ignore right-click on mac
+ // Set a global event to handle mouseup, so it fires properly
+ // even if the cursor leaves this.domNode before the mouse up event.
+ var mouseUpConnector = this.connect(dojo.body(), "onmouseup", function(){
+ if (this.isFocusable()) {
+ this.focus();
+ }
+ this.disconnect(mouseUpConnector);
+ });
+ }
+ }
+});
+
+dojo.declare("dijit.form._FormValueWidget", dijit.form._FormWidget,
+{
+ // summary:
+ // Base class for widgets corresponding to native HTML elements such as <input> or <select> that have user changeable values.
+ // description:
+ // Each _FormValueWidget represents a single input value, and has a (possibly hidden) <input> element,
+ // to which it serializes it's input value, so that form submission (either normal submission or via FormBind?)
+ // works as expected.
+
+ // Don't attempt to mixin the 'type', 'name' attributes here programatically -- they must be declared
+ // directly in the template as read by the parser in order to function. IE is known to specifically
+ // require the 'name' attribute at element creation time. See #8484, #8660.
+ // TODO: unclear what that {value: ""} is for; FormWidget.attributeMap copies value to focusNode,
+ // so maybe {value: ""} is so the value *doesn't* get copied to focusNode?
+ // Seems like we really want value removed from attributeMap altogether
+ // (although there's no easy way to do that now)
+
+ // readOnly: Boolean
+ // Should this widget respond to user input?
+ // In markup, this is specified as "readOnly".
+ // Similar to disabled except readOnly form values are submitted.
+ readOnly: false,
+
+ attributeMap: dojo.delegate(dijit.form._FormWidget.prototype.attributeMap, {
+ value: "",
+ readOnly: "focusNode"
+ }),
+
+ _setReadOnlyAttr: function(/*Boolean*/ value){
+ dojo.attr(this.focusNode, 'readOnly', value);
+ dijit.setWaiState(this.focusNode, "readonly", value);
+ this._set("readOnly", value);
+ },
+
+ postCreate: function(){
+ this.inherited(arguments);
+
+ if(dojo.isIE){ // IE won't stop the event with keypress
+ this.connect(this.focusNode || this.domNode, "onkeydown", this._onKeyDown);
+ }
+ // Update our reset value if it hasn't yet been set (because this.set()
+ // is only called when there *is* a value)
+ if(this._resetValue === undefined){
+ this._lastValueReported = this._resetValue = this.value;
+ }
+ },
+
+ _setValueAttr: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
+ // summary:
+ // Hook so set('value', value) works.
+ // description:
+ // Sets the value of the widget.
+ // If the value has changed, then fire onChange event, unless priorityChange
+ // is specified as null (or false?)
+ this._handleOnChange(newValue, priorityChange);
+ },
+
+ _handleOnChange: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
+ // summary:
+ // Called when the value of the widget has changed. Saves the new value in this.value,
+ // and calls onChange() if appropriate. See _FormWidget._handleOnChange() for details.
+ this._set("value", newValue);
+ this.inherited(arguments);
+ },
+
+ undo: function(){
+ // summary:
+ // Restore the value to the last value passed to onChange
+ this._setValueAttr(this._lastValueReported, false);
+ },
+
+ reset: function(){
+ // summary:
+ // Reset the widget's value to what it was at initialization time
+ this._hasBeenBlurred = false;
+ this._setValueAttr(this._resetValue, true);
+ },
+
+ _onKeyDown: function(e){
+ if(e.keyCode == dojo.keys.ESCAPE && !(e.ctrlKey || e.altKey || e.metaKey)){
+ var te;
+ if(dojo.isIE){
+ e.preventDefault(); // default behavior needs to be stopped here since keypress is too late
+ te = document.createEventObject();
+ te.keyCode = dojo.keys.ESCAPE;
+ te.shiftKey = e.shiftKey;
+ e.srcElement.fireEvent('onkeypress', te);
+ }
+ }
+ },
+
+ _layoutHackIE7: function(){
+ // summary:
+ // Work around table sizing bugs on IE7 by forcing redraw
+
+ if(dojo.isIE == 7){ // fix IE7 layout bug when the widget is scrolled out of sight
+ var domNode = this.domNode;
+ var parent = domNode.parentNode;
+ var pingNode = domNode.firstChild || domNode; // target node most unlikely to have a custom filter
+ var origFilter = pingNode.style.filter; // save custom filter, most likely nothing
+ var _this = this;
+ while(parent && parent.clientHeight == 0){ // search for parents that haven't rendered yet
+ (function ping(){
+ var disconnectHandle = _this.connect(parent, "onscroll",
+ function(e){
+ _this.disconnect(disconnectHandle); // only call once
+ pingNode.style.filter = (new Date()).getMilliseconds(); // set to anything that's unique
+ setTimeout(function(){ pingNode.style.filter = origFilter }, 0); // restore custom filter, if any
+ }
+ );
+ })();
+ parent = parent.parentNode;
+ }
+ }
+ }
+});
+
+}
+
+if(!dojo._hasResource["dijit.dijit"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.dijit"] = true;
+dojo.provide("dijit.dijit");
+
+
+
+
+
+
+
+
+
+
+/*=====
+dijit.dijit = {
+ // summary:
+ // A roll-up for common dijit methods
+ // description:
+ // A rollup file for the build system including the core and common
+ // dijit files.
+ //
+ // example:
+ // | <script type="text/javascript" src="js/dojo/dijit/dijit.js"></script>
+ //
+};
+=====*/
+
+// All the stuff in _base (these are the function that are guaranteed available without an explicit dojo.require)
+
+// And some other stuff that we tend to pull in all the time anyway
+
+}
+
+if(!dojo._hasResource["dijit._KeyNavContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._KeyNavContainer"] = true;
+dojo.provide("dijit._KeyNavContainer");
+
+
+
+
+dojo.declare("dijit._KeyNavContainer",
+ dijit._Container,
+ {
+
+ // summary:
+ // A _Container with keyboard navigation of its children.
+ // description:
+ // To use this mixin, call connectKeyNavHandlers() in
+ // postCreate() and call startupKeyNavChildren() in startup().
+ // It provides normalized keyboard and focusing code for Container
+ // widgets.
+/*=====
+ // focusedChild: [protected] Widget
+ // The currently focused child widget, or null if there isn't one
+ focusedChild: null,
+=====*/
+
+ // tabIndex: Integer
+ // Tab index of the container; same as HTML tabIndex attribute.
+ // Note then when user tabs into the container, focus is immediately
+ // moved to the first item in the container.
+ tabIndex: "0",
+
+ _keyNavCodes: {},
+
+ connectKeyNavHandlers: function(/*dojo.keys[]*/ prevKeyCodes, /*dojo.keys[]*/ nextKeyCodes){
+ // summary:
+ // Call in postCreate() to attach the keyboard handlers
+ // to the container.
+ // preKeyCodes: dojo.keys[]
+ // Key codes for navigating to the previous child.
+ // nextKeyCodes: dojo.keys[]
+ // Key codes for navigating to the next child.
+ // tags:
+ // protected
+
+ var keyCodes = (this._keyNavCodes = {});
+ var prev = dojo.hitch(this, this.focusPrev);
+ var next = dojo.hitch(this, this.focusNext);
+ dojo.forEach(prevKeyCodes, function(code){ keyCodes[code] = prev; });
+ dojo.forEach(nextKeyCodes, function(code){ keyCodes[code] = next; });
+ keyCodes[dojo.keys.HOME] = dojo.hitch(this, "focusFirstChild");
+ keyCodes[dojo.keys.END] = dojo.hitch(this, "focusLastChild");
+ this.connect(this.domNode, "onkeypress", "_onContainerKeypress");
+ this.connect(this.domNode, "onfocus", "_onContainerFocus");
+ },
+
+ startupKeyNavChildren: function(){
+ // summary:
+ // Call in startup() to set child tabindexes to -1
+ // tags:
+ // protected
+ dojo.forEach(this.getChildren(), dojo.hitch(this, "_startupChild"));
+ },
+
+ addChild: function(/*dijit._Widget*/ widget, /*int?*/ insertIndex){
+ // summary:
+ // Add a child to our _Container
+ dijit._KeyNavContainer.superclass.addChild.apply(this, arguments);
+ this._startupChild(widget);
+ },
+
+ focus: function(){
+ // summary:
+ // Default focus() implementation: focus the first child.
+ this.focusFirstChild();
+ },
+
+ focusFirstChild: function(){
+ // summary:
+ // Focus the first focusable child in the container.
+ // tags:
+ // protected
+ var child = this._getFirstFocusableChild();
+ if(child){ // edge case: Menu could be empty or hidden
+ this.focusChild(child);
+ }
+ },
+
+ focusLastChild: function(){
+ // summary:
+ // Focus the last focusable child in the container.
+ // tags:
+ // protected
+ var child = this._getLastFocusableChild();
+ if(child){ // edge case: Menu could be empty or hidden
+ this.focusChild(child);
+ }
+ },
+
+ focusNext: function(){
+ // summary:
+ // Focus the next widget
+ // tags:
+ // protected
+ var child = this._getNextFocusableChild(this.focusedChild, 1);
+ this.focusChild(child);
+ },
+
+ focusPrev: function(){
+ // summary:
+ // Focus the last focusable node in the previous widget
+ // (ex: go to the ComboButton icon section rather than button section)
+ // tags:
+ // protected
+ var child = this._getNextFocusableChild(this.focusedChild, -1);
+ this.focusChild(child, true);
+ },
+
+ focusChild: function(/*dijit._Widget*/ widget, /*Boolean*/ last){
+ // summary:
+ // Focus widget.
+ // widget:
+ // Reference to container's child widget
+ // last:
+ // If true and if widget has multiple focusable nodes, focus the
+ // last one instead of the first one
+ // tags:
+ // protected
+
+ if(this.focusedChild && widget !== this.focusedChild){
+ this._onChildBlur(this.focusedChild);
+ }
+ widget.focus(last ? "end" : "start");
+ this._set("focusedChild", widget);
+ },
+
+ _startupChild: function(/*dijit._Widget*/ widget){
+ // summary:
+ // Setup for each child widget
+ // description:
+ // Sets tabIndex=-1 on each child, so that the tab key will
+ // leave the container rather than visiting each child.
+ // tags:
+ // private
+
+ widget.set("tabIndex", "-1");
+
+ this.connect(widget, "_onFocus", function(){
+ // Set valid tabIndex so tabbing away from widget goes to right place, see #10272
+ widget.set("tabIndex", this.tabIndex);
+ });
+ this.connect(widget, "_onBlur", function(){
+ widget.set("tabIndex", "-1");
+ });
+ },
+
+ _onContainerFocus: function(evt){
+ // summary:
+ // Handler for when the container gets focus
+ // description:
+ // Initially the container itself has a tabIndex, but when it gets
+ // focus, switch focus to first child...
+ // tags:
+ // private
+
+ // Note that we can't use _onFocus() because switching focus from the
+ // _onFocus() handler confuses the focus.js code
+ // (because it causes _onFocusNode() to be called recursively)
+
+ // focus bubbles on Firefox,
+ // so just make sure that focus has really gone to the container
+ if(evt.target !== this.domNode){ return; }
+
+ this.focusFirstChild();
+
+ // and then set the container's tabIndex to -1,
+ // (don't remove as that breaks Safari 4)
+ // so that tab or shift-tab will go to the fields after/before
+ // the container, rather than the container itself
+ dojo.attr(this.domNode, "tabIndex", "-1");
+ },
+
+ _onBlur: function(evt){
+ // When focus is moved away the container, and its descendant (popup) widgets,
+ // then restore the container's tabIndex so that user can tab to it again.
+ // Note that using _onBlur() so that this doesn't happen when focus is shifted
+ // to one of my child widgets (typically a popup)
+ if(this.tabIndex){
+ dojo.attr(this.domNode, "tabIndex", this.tabIndex);
+ }
+ this.inherited(arguments);
+ },
+
+ _onContainerKeypress: function(evt){
+ // summary:
+ // When a key is pressed, if it's an arrow key etc. then
+ // it's handled here.
+ // tags:
+ // private
+ if(evt.ctrlKey || evt.altKey){ return; }
+ var func = this._keyNavCodes[evt.charOrCode];
+ if(func){
+ func();
+ dojo.stopEvent(evt);
+ }
+ },
+
+ _onChildBlur: function(/*dijit._Widget*/ widget){
+ // summary:
+ // Called when focus leaves a child widget to go
+ // to a sibling widget.
+ // tags:
+ // protected
+ },
+
+ _getFirstFocusableChild: function(){
+ // summary:
+ // Returns first child that can be focused
+ return this._getNextFocusableChild(null, 1); // dijit._Widget
+ },
+
+ _getLastFocusableChild: function(){
+ // summary:
+ // Returns last child that can be focused
+ return this._getNextFocusableChild(null, -1); // dijit._Widget
+ },
+
+ _getNextFocusableChild: function(child, dir){
+ // summary:
+ // Returns the next or previous focusable child, compared
+ // to "child"
+ // child: Widget
+ // The current widget
+ // dir: Integer
+ // * 1 = after
+ // * -1 = before
+ if(child){
+ child = this._getSiblingOfChild(child, dir);
+ }
+ var children = this.getChildren();
+ for(var i=0; i < children.length; i++){
+ if(!child){
+ child = children[(dir>0) ? 0 : (children.length-1)];
+ }
+ if(child.isFocusable()){
+ return child; // dijit._Widget
+ }
+ child = this._getSiblingOfChild(child, dir);
+ }
+ // no focusable child found
+ return null; // dijit._Widget
+ }
+ }
+);
+
+}
+
+if(!dojo._hasResource["dijit.MenuItem"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.MenuItem"] = true;
+dojo.provide("dijit.MenuItem");
+
+
+
+
+
+
+
+dojo.declare("dijit.MenuItem",
+ [dijit._Widget, dijit._Templated, dijit._Contained, dijit._CssStateMixin],
+ {
+ // summary:
+ // A line item in a Menu Widget
+
+ // Make 3 columns
+ // icon, label, and expand arrow (BiDi-dependent) indicating sub-menu
+ templateString: dojo.cache("dijit", "templates/MenuItem.html", "<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" role=\"menuitem\" tabIndex=\"-1\"\r\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\r\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\r\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitIcon dijitMenuItemIcon\" dojoAttachPoint=\"iconNode\"/>\r\n\t</td>\r\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" dojoAttachPoint=\"containerNode\"></td>\r\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" dojoAttachPoint=\"accelKeyNode\"></td>\r\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">\r\n\t\t<div dojoAttachPoint=\"arrowWrapper\" style=\"visibility: hidden\">\r\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuExpand\"/>\r\n\t\t\t<span class=\"dijitMenuExpandA11y\">+</span>\r\n\t\t</div>\r\n\t</td>\r\n</tr>\r\n"),
+
+ attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
+ label: { node: "containerNode", type: "innerHTML" },
+ iconClass: { node: "iconNode", type: "class" }
+ }),
+
+ baseClass: "dijitMenuItem",
+
+ // label: String
+ // Menu text
+ label: '',
+
+ // iconClass: String
+ // Class to apply to DOMNode to make it display an icon.
+ iconClass: "",
+
+ // accelKey: String
+ // Text for the accelerator (shortcut) key combination.
+ // Note that although Menu can display accelerator keys there
+ // is no infrastructure to actually catch and execute these
+ // accelerators.
+ accelKey: "",
+
+ // disabled: Boolean
+ // If true, the menu item is disabled.
+ // If false, the menu item is enabled.
+ disabled: false,
+
+ _fillContent: function(/*DomNode*/ source){
+ // If button label is specified as srcNodeRef.innerHTML rather than
+ // this.params.label, handle it here.
+ if(source && !("label" in this.params)){
+ this.set('label', source.innerHTML);
+ }
+ },
+
+ buildRendering: function(){
+ this.inherited(arguments);
+ var label = this.id+"_text";
+ dojo.attr(this.containerNode, "id", label);
+ if(this.accelKeyNode){
+ dojo.attr(this.accelKeyNode, "id", this.id + "_accel");
+ label += " " + this.id + "_accel";
+ }
+ dijit.setWaiState(this.domNode, "labelledby", label);
+ dojo.setSelectable(this.domNode, false);
+ },
+
+ _onHover: function(){
+ // summary:
+ // Handler when mouse is moved onto menu item
+ // tags:
+ // protected
+ this.getParent().onItemHover(this);
+ },
+
+ _onUnhover: function(){
+ // summary:
+ // Handler when mouse is moved off of menu item,
+ // possibly to a child menu, or maybe to a sibling
+ // menuitem or somewhere else entirely.
+ // tags:
+ // protected
+
+ // if we are unhovering the currently selected item
+ // then unselect it
+ this.getParent().onItemUnhover(this);
+
+ // When menu is hidden (collapsed) due to clicking a MenuItem and having it execute,
+ // FF and IE don't generate an onmouseout event for the MenuItem.
+ // So, help out _CssStateMixin in this case.
+ this._set("hovering", false);
+ },
+
+ _onClick: function(evt){
+ // summary:
+ // Internal handler for click events on MenuItem.
+ // tags:
+ // private
+ this.getParent().onItemClick(this, evt);
+ dojo.stopEvent(evt);
+ },
+
+ onClick: function(/*Event*/ evt){
+ // summary:
+ // User defined function to handle clicks
+ // tags:
+ // callback
+ },
+
+ focus: function(){
+ // summary:
+ // Focus on this MenuItem
+ try{
+ if(dojo.isIE == 8){
+ // needed for IE8 which won't scroll TR tags into view on focus yet calling scrollIntoView creates flicker (#10275)
+ this.containerNode.focus();
+ }
+ dijit.focus(this.focusNode);
+ }catch(e){
+ // this throws on IE (at least) in some scenarios
+ }
+ },
+
+ _onFocus: function(){
+ // summary:
+ // This is called by the focus manager when focus
+ // goes to this MenuItem or a child menu.
+ // tags:
+ // protected
+ this._setSelected(true);
+ this.getParent()._onItemFocus(this);
+
+ this.inherited(arguments);
+ },
+
+ _setSelected: function(selected){
+ // summary:
+ // Indicate that this node is the currently selected one
+ // tags:
+ // private
+
+ /***
+ * TODO: remove this method and calls to it, when _onBlur() is working for MenuItem.
+ * Currently _onBlur() gets called when focus is moved from the MenuItem to a child menu.
+ * That's not supposed to happen, but the problem is:
+ * In order to allow dijit.popup's getTopPopup() to work,a sub menu's popupParent
+ * points to the parent Menu, bypassing the parent MenuItem... thus the
+ * MenuItem is not in the chain of active widgets and gets a premature call to
+ * _onBlur()
+ */
+
+ dojo.toggleClass(this.domNode, "dijitMenuItemSelected", selected);
+ },
+
+ setLabel: function(/*String*/ content){
+ // summary:
+ // Deprecated. Use set('label', ...) instead.
+ // tags:
+ // deprecated
+ dojo.deprecated("dijit.MenuItem.setLabel() is deprecated. Use set('label', ...) instead.", "", "2.0");
+ this.set("label", content);
+ },
+
+ setDisabled: function(/*Boolean*/ disabled){
+ // summary:
+ // Deprecated. Use set('disabled', bool) instead.
+ // tags:
+ // deprecated
+ dojo.deprecated("dijit.Menu.setDisabled() is deprecated. Use set('disabled', bool) instead.", "", "2.0");
+ this.set('disabled', disabled);
+ },
+ _setDisabledAttr: function(/*Boolean*/ value){
+ // summary:
+ // Hook for attr('disabled', ...) to work.
+ // Enable or disable this menu item.
+
+ dijit.setWaiState(this.focusNode, 'disabled', value ? 'true' : 'false');
+ this._set("disabled", value);
+ },
+ _setAccelKeyAttr: function(/*String*/ value){
+ // summary:
+ // Hook for attr('accelKey', ...) to work.
+ // Set accelKey on this menu item.
+
+ this.accelKeyNode.style.display=value?"":"none";
+ this.accelKeyNode.innerHTML=value;
+ //have to use colSpan to make it work in IE
+ dojo.attr(this.containerNode,'colSpan',value?"1":"2");
+
+ this._set("accelKey", value);
+ }
+ });
+
+}
+
+if(!dojo._hasResource["dijit.PopupMenuItem"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.PopupMenuItem"] = true;
+dojo.provide("dijit.PopupMenuItem");
+
+
+
+
+dojo.declare("dijit.PopupMenuItem",
+ dijit.MenuItem,
+ {
+ _fillContent: function(){
+ // summary:
+ // When Menu is declared in markup, this code gets the menu label and
+ // the popup widget from the srcNodeRef.
+ // description:
+ // srcNodeRefinnerHTML contains both the menu item text and a popup widget
+ // The first part holds the menu item text and the second part is the popup
+ // example:
+ // | <div dojoType="dijit.PopupMenuItem">
+ // | <span>pick me</span>
+ // | <popup> ... </popup>
+ // | </div>
+ // tags:
+ // protected
+
+ if(this.srcNodeRef){
+ var nodes = dojo.query("*", this.srcNodeRef);
+ dijit.PopupMenuItem.superclass._fillContent.call(this, nodes[0]);
+
+ // save pointer to srcNode so we can grab the drop down widget after it's instantiated
+ this.dropDownContainer = this.srcNodeRef;
+ }
+ },
+
+ startup: function(){
+ if(this._started){ return; }
+ this.inherited(arguments);
+
+ // we didn't copy the dropdown widget from the this.srcNodeRef, so it's in no-man's
+ // land now. move it to dojo.doc.body.
+ if(!this.popup){
+ var node = dojo.query("[widgetId]", this.dropDownContainer)[0];
+ this.popup = dijit.byNode(node);
+ }
+ dojo.body().appendChild(this.popup.domNode);
+ this.popup.startup();
+
+ this.popup.domNode.style.display="none";
+ if(this.arrowWrapper){
+ dojo.style(this.arrowWrapper, "visibility", "");
+ }
+ dijit.setWaiState(this.focusNode, "haspopup", "true");
+ },
+
+ destroyDescendants: function(){
+ if(this.popup){
+ // Destroy the popup, unless it's already been destroyed. This can happen because
+ // the popup is a direct child of <body> even though it's logically my child.
+ if(!this.popup._destroyed){
+ this.popup.destroyRecursive();
+ }
+ delete this.popup;
+ }
+ this.inherited(arguments);
+ }
+ });
+
+}
+
+if(!dojo._hasResource["dijit.CheckedMenuItem"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.CheckedMenuItem"] = true;
+dojo.provide("dijit.CheckedMenuItem");
+
+
+
+
+dojo.declare("dijit.CheckedMenuItem",
+ dijit.MenuItem,
+ {
+ // summary:
+ // A checkbox-like menu item for toggling on and off
+
+ templateString: dojo.cache("dijit", "templates/CheckedMenuItem.html", "<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" role=\"menuitemcheckbox\" tabIndex=\"-1\"\r\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\r\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\r\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" dojoAttachPoint=\"iconNode\"/>\r\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">&#10003;</span>\r\n\t</td>\r\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" dojoAttachPoint=\"containerNode,labelNode\"></td>\r\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" dojoAttachPoint=\"accelKeyNode\"></td>\r\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">&nbsp;</td>\r\n</tr>\r\n"),
+
+ // checked: Boolean
+ // Our checked state
+ checked: false,
+ _setCheckedAttr: function(/*Boolean*/ checked){
+ // summary:
+ // Hook so attr('checked', bool) works.
+ // Sets the class and state for the check box.
+ dojo.toggleClass(this.domNode, "dijitCheckedMenuItemChecked", checked);
+ dijit.setWaiState(this.domNode, "checked", checked);
+ this._set("checked", checked);
+ },
+
+ onChange: function(/*Boolean*/ checked){
+ // summary:
+ // User defined function to handle check/uncheck events
+ // tags:
+ // callback
+ },
+
+ _onClick: function(/*Event*/ e){
+ // summary:
+ // Clicking this item just toggles its state
+ // tags:
+ // private
+ if(!this.disabled){
+ this.set("checked", !this.checked);
+ this.onChange(this.checked);
+ }
+ this.inherited(arguments);
+ }
+ });
+
+}
+
+if(!dojo._hasResource["dijit.MenuSeparator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.MenuSeparator"] = true;
+dojo.provide("dijit.MenuSeparator");
+
+
+
+
+
+
+dojo.declare("dijit.MenuSeparator",
+ [dijit._Widget, dijit._Templated, dijit._Contained],
+ {
+ // summary:
+ // A line between two menu items
+
+ templateString: dojo.cache("dijit", "templates/MenuSeparator.html", "<tr class=\"dijitMenuSeparator\">\r\n\t<td class=\"dijitMenuSeparatorIconCell\">\r\n\t\t<div class=\"dijitMenuSeparatorTop\"></div>\r\n\t\t<div class=\"dijitMenuSeparatorBottom\"></div>\r\n\t</td>\r\n\t<td colspan=\"3\" class=\"dijitMenuSeparatorLabelCell\">\r\n\t\t<div class=\"dijitMenuSeparatorTop dijitMenuSeparatorLabel\"></div>\r\n\t\t<div class=\"dijitMenuSeparatorBottom\"></div>\r\n\t</td>\r\n</tr>\r\n"),
+
+ buildRendering: function(){
+ this.inherited(arguments);
+ dojo.setSelectable(this.domNode, false);
+ },
+
+ isFocusable: function(){
+ // summary:
+ // Override to always return false
+ // tags:
+ // protected
+
+ return false; // Boolean
+ }
+ });
+
+}
+
+if(!dojo._hasResource["dijit.Menu"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.Menu"] = true;
+dojo.provide("dijit.Menu");
+
+
+
+
+
+
+
+
+
+
+
+// "dijit/MenuItem", "dijit/PopupMenuItem", "dijit/CheckedMenuItem", "dijit/MenuSeparator" for Back-compat (TODO: remove in 2.0)
+
+dojo.declare("dijit._MenuBase",
+ [dijit._Widget, dijit._Templated, dijit._KeyNavContainer],
+{
+ // summary:
+ // Base class for Menu and MenuBar
+
+ // parentMenu: [readonly] Widget
+ // pointer to menu that displayed me
+ parentMenu: null,
+
+ // popupDelay: Integer
+ // number of milliseconds before hovering (without clicking) causes the popup to automatically open.
+ popupDelay: 500,
+
+ startup: function(){
+ if(this._started){ return; }
+
+ dojo.forEach(this.getChildren(), function(child){ child.startup(); });
+ this.startupKeyNavChildren();
+
+ this.inherited(arguments);
+ },
+
+ onExecute: function(){
+ // summary:
+ // Attach point for notification about when a menu item has been executed.
+ // This is an internal mechanism used for Menus to signal to their parent to
+ // close them, because they are about to execute the onClick handler. In
+ // general developers should not attach to or override this method.
+ // tags:
+ // protected
+ },
+
+ onCancel: function(/*Boolean*/ closeAll){
+ // summary:
+ // Attach point for notification about when the user cancels the current menu
+ // This is an internal mechanism used for Menus to signal to their parent to
+ // close them. In general developers should not attach to or override this method.
+ // tags:
+ // protected
+ },
+
+ _moveToPopup: function(/*Event*/ evt){
+ // summary:
+ // This handles the right arrow key (left arrow key on RTL systems),
+ // which will either open a submenu, or move to the next item in the
+ // ancestor MenuBar
+ // tags:
+ // private
+
+ if(this.focusedChild && this.focusedChild.popup && !this.focusedChild.disabled){
+ this.focusedChild._onClick(evt);
+ }else{
+ var topMenu = this._getTopMenu();
+ if(topMenu && topMenu._isMenuBar){
+ topMenu.focusNext();
+ }
+ }
+ },
+
+ _onPopupHover: function(/*Event*/ evt){
+ // summary:
+ // This handler is called when the mouse moves over the popup.
+ // tags:
+ // private
+
+ // if the mouse hovers over a menu popup that is in pending-close state,
+ // then stop the close operation.
+ // This can't be done in onItemHover since some popup targets don't have MenuItems (e.g. ColorPicker)
+ if(this.currentPopup && this.currentPopup._pendingClose_timer){
+ var parentMenu = this.currentPopup.parentMenu;
+ // highlight the parent menu item pointing to this popup
+ if(parentMenu.focusedChild){
+ parentMenu.focusedChild._setSelected(false);
+ }
+ parentMenu.focusedChild = this.currentPopup.from_item;
+ parentMenu.focusedChild._setSelected(true);
+ // cancel the pending close
+ this._stopPendingCloseTimer(this.currentPopup);
+ }
+ },
+
+ onItemHover: function(/*MenuItem*/ item){
+ // summary:
+ // Called when cursor is over a MenuItem.
+ // tags:
+ // protected
+
+ // Don't do anything unless user has "activated" the menu by:
+ // 1) clicking it
+ // 2) opening it from a parent menu (which automatically focuses it)
+ if(this.isActive){
+ this.focusChild(item);
+ if(this.focusedChild.popup && !this.focusedChild.disabled && !this.hover_timer){
+ this.hover_timer = setTimeout(dojo.hitch(this, "_openPopup"), this.popupDelay);
+ }
+ }
+ // if the user is mixing mouse and keyboard navigation,
+ // then the menu may not be active but a menu item has focus,
+ // but it's not the item that the mouse just hovered over.
+ // To avoid both keyboard and mouse selections, use the latest.
+ if(this.focusedChild){
+ this.focusChild(item);
+ }
+ this._hoveredChild = item;
+ },
+
+ _onChildBlur: function(item){
+ // summary:
+ // Called when a child MenuItem becomes inactive because focus
+ // has been removed from the MenuItem *and* it's descendant menus.
+ // tags:
+ // private
+ this._stopPopupTimer();
+ item._setSelected(false);
+ // Close all popups that are open and descendants of this menu
+ var itemPopup = item.popup;
+ if(itemPopup){
+ this._stopPendingCloseTimer(itemPopup);
+ itemPopup._pendingClose_timer = setTimeout(function(){
+ itemPopup._pendingClose_timer = null;
+ if(itemPopup.parentMenu){
+ itemPopup.parentMenu.currentPopup = null;
+ }
+ dijit.popup.close(itemPopup); // this calls onClose
+ }, this.popupDelay);
+ }
+ },
+
+ onItemUnhover: function(/*MenuItem*/ item){
+ // summary:
+ // Callback fires when mouse exits a MenuItem
+ // tags:
+ // protected
+
+ if(this.isActive){
+ this._stopPopupTimer();
+ }
+ if(this._hoveredChild == item){ this._hoveredChild = null; }
+ },
+
+ _stopPopupTimer: function(){
+ // summary:
+ // Cancels the popup timer because the user has stop hovering
+ // on the MenuItem, etc.
+ // tags:
+ // private
+ if(this.hover_timer){
+ clearTimeout(this.hover_timer);
+ this.hover_timer = null;
+ }
+ },
+
+ _stopPendingCloseTimer: function(/*dijit._Widget*/ popup){
+ // summary:
+ // Cancels the pending-close timer because the close has been preempted
+ // tags:
+ // private
+ if(popup._pendingClose_timer){
+ clearTimeout(popup._pendingClose_timer);
+ popup._pendingClose_timer = null;
+ }
+ },
+
+ _stopFocusTimer: function(){
+ // summary:
+ // Cancels the pending-focus timer because the menu was closed before focus occured
+ // tags:
+ // private
+ if(this._focus_timer){
+ clearTimeout(this._focus_timer);
+ this._focus_timer = null;
+ }
+ },
+
+ _getTopMenu: function(){
+ // summary:
+ // Returns the top menu in this chain of Menus
+ // tags:
+ // private
+ for(var top=this; top.parentMenu; top=top.parentMenu);
+ return top;
+ },
+
+ onItemClick: function(/*dijit._Widget*/ item, /*Event*/ evt){
+ // summary:
+ // Handle clicks on an item.
+ // tags:
+ // private
+
+ // this can't be done in _onFocus since the _onFocus events occurs asynchronously
+ if(typeof this.isShowingNow == 'undefined'){ // non-popup menu
+ this._markActive();
+ }
+
+ this.focusChild(item);
+
+ if(item.disabled){ return false; }
+
+ if(item.popup){
+ this._openPopup();
+ }else{
+ // before calling user defined handler, close hierarchy of menus
+ // and restore focus to place it was when menu was opened
+ this.onExecute();
+
+ // user defined handler for click
+ item.onClick(evt);
+ }
+ },
+
+ _openPopup: function(){
+ // summary:
+ // Open the popup to the side of/underneath the current menu item
+ // tags:
+ // protected
+
+ this._stopPopupTimer();
+ var from_item = this.focusedChild;
+ if(!from_item){ return; } // the focused child lost focus since the timer was started
+ var popup = from_item.popup;
+ if(popup.isShowingNow){ return; }
+ if(this.currentPopup){
+ this._stopPendingCloseTimer(this.currentPopup);
+ dijit.popup.close(this.currentPopup);
+ }
+ popup.parentMenu = this;
+ popup.from_item = from_item; // helps finding the parent item that should be focused for this popup
+ var self = this;
+ dijit.popup.open({
+ parent: this,
+ popup: popup,
+ around: from_item.domNode,
+ orient: this._orient || (this.isLeftToRight() ?
+ {'TR': 'TL', 'TL': 'TR', 'BR': 'BL', 'BL': 'BR'} :
+ {'TL': 'TR', 'TR': 'TL', 'BL': 'BR', 'BR': 'BL'}),
+ onCancel: function(){ // called when the child menu is canceled
+ // set isActive=false (_closeChild vs _cleanUp) so that subsequent hovering will NOT open child menus
+ // which seems aligned with the UX of most applications (e.g. notepad, wordpad, paint shop pro)
+ self.focusChild(from_item); // put focus back on my node
+ self._cleanUp(); // close the submenu (be sure this is done _after_ focus is moved)
+ from_item._setSelected(true); // oops, _cleanUp() deselected the item
+ self.focusedChild = from_item; // and unset focusedChild
+ },
+ onExecute: dojo.hitch(this, "_cleanUp")
+ });
+
+ this.currentPopup = popup;
+ // detect mouseovers to handle lazy mouse movements that temporarily focus other menu items
+ popup.connect(popup.domNode, "onmouseenter", dojo.hitch(self, "_onPopupHover")); // cleaned up when the popped-up widget is destroyed on close
+
+ if(popup.focus){
+ // If user is opening the popup via keyboard (right arrow, or down arrow for MenuBar),
+ // if the cursor happens to collide with the popup, it will generate an onmouseover event
+ // even though the mouse wasn't moved. Use a setTimeout() to call popup.focus so that
+ // our focus() call overrides the onmouseover event, rather than vice-versa. (#8742)
+ popup._focus_timer = setTimeout(dojo.hitch(popup, function(){
+ this._focus_timer = null;
+ this.focus();
+ }), 0);
+ }
+ },
+
+ _markActive: function(){
+ // summary:
+ // Mark this menu's state as active.
+ // Called when this Menu gets focus from:
+ // 1) clicking it (mouse or via space/arrow key)
+ // 2) being opened by a parent menu.
+ // This is not called just from mouse hover.
+ // Focusing a menu via TAB does NOT automatically set isActive
+ // since TAB is a navigation operation and not a selection one.
+ // For Windows apps, pressing the ALT key focuses the menubar
+ // menus (similar to TAB navigation) but the menu is not active
+ // (ie no dropdown) until an item is clicked.
+ this.isActive = true;
+ dojo.replaceClass(this.domNode, "dijitMenuActive", "dijitMenuPassive");
+ },
+
+ onOpen: function(/*Event*/ e){
+ // summary:
+ // Callback when this menu is opened.
+ // This is called by the popup manager as notification that the menu
+ // was opened.
+ // tags:
+ // private
+
+ this.isShowingNow = true;
+ this._markActive();
+ },
+
+ _markInactive: function(){
+ // summary:
+ // Mark this menu's state as inactive.
+ this.isActive = false; // don't do this in _onBlur since the state is pending-close until we get here
+ dojo.replaceClass(this.domNode, "dijitMenuPassive", "dijitMenuActive");
+ },
+
+ onClose: function(){
+ // summary:
+ // Callback when this menu is closed.
+ // This is called by the popup manager as notification that the menu
+ // was closed.
+ // tags:
+ // private
+
+ this._stopFocusTimer();
+ this._markInactive();
+ this.isShowingNow = false;
+ this.parentMenu = null;
+ },
+
+ _closeChild: function(){
+ // summary:
+ // Called when submenu is clicked or focus is lost. Close hierarchy of menus.
+ // tags:
+ // private
+ this._stopPopupTimer();
+
+ var fromItem = this.focusedChild && this.focusedChild.from_item;
+
+ if(this.currentPopup){
+ // If focus is on my child menu then move focus to me,
+ // because IE doesn't like it when you display:none a node with focus
+ if(dijit._curFocus && dojo.isDescendant(dijit._curFocus, this.currentPopup.domNode)){
+ this.focusedChild.focusNode.focus();
+ }
+ // Close all popups that are open and descendants of this menu
+ dijit.popup.close(this.currentPopup);
+ this.currentPopup = null;
+ }
+
+ if(this.focusedChild){ // unhighlight the focused item
+ this.focusedChild._setSelected(false);
+ this.focusedChild._onUnhover();
+ this.focusedChild = null;
+ }
+ },
+
+ _onItemFocus: function(/*MenuItem*/ item){
+ // summary:
+ // Called when child of this Menu gets focus from:
+ // 1) clicking it
+ // 2) tabbing into it
+ // 3) being opened by a parent menu.
+ // This is not called just from mouse hover.
+ if(this._hoveredChild && this._hoveredChild != item){
+ this._hoveredChild._onUnhover(); // any previous mouse movement is trumped by focus selection
+ }
+ },
+
+ _onBlur: function(){
+ // summary:
+ // Called when focus is moved away from this Menu and it's submenus.
+ // tags:
+ // protected
+ this._cleanUp();
+ this.inherited(arguments);
+ },
+
+ _cleanUp: function(){
+ // summary:
+ // Called when the user is done with this menu. Closes hierarchy of menus.
+ // tags:
+ // private
+
+ this._closeChild(); // don't call this.onClose since that's incorrect for MenuBar's that never close
+ if(typeof this.isShowingNow == 'undefined'){ // non-popup menu doesn't call onClose
+ this._markInactive();
+ }
+ }
+});
+
+dojo.declare("dijit.Menu",
+ dijit._MenuBase,
+ {
+ // summary
+ // A context menu you can assign to multiple elements
+
+ // TODO: most of the code in here is just for context menu (right-click menu)
+ // support. In retrospect that should have been a separate class (dijit.ContextMenu).
+ // Split them for 2.0
+
+ constructor: function(){
+ this._bindings = [];
+ },
+
+ templateString: dojo.cache("dijit", "templates/Menu.html", "<table class=\"dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable\" role=\"menu\" tabIndex=\"${tabIndex}\" dojoAttachEvent=\"onkeypress:_onKeyPress\" cellspacing=\"0\">\r\n\t<tbody class=\"dijitReset\" dojoAttachPoint=\"containerNode\"></tbody>\r\n</table>\r\n"),
+
+ baseClass: "dijitMenu",
+
+ // targetNodeIds: [const] String[]
+ // Array of dom node ids of nodes to attach to.
+ // Fill this with nodeIds upon widget creation and it becomes context menu for those nodes.
+ targetNodeIds: [],
+
+ // contextMenuForWindow: [const] Boolean
+ // If true, right clicking anywhere on the window will cause this context menu to open.
+ // If false, must specify targetNodeIds.
+ contextMenuForWindow: false,
+
+ // leftClickToOpen: [const] Boolean
+ // If true, menu will open on left click instead of right click, similiar to a file menu.
+ leftClickToOpen: false,
+
+ // refocus: Boolean
+ // When this menu closes, re-focus the element which had focus before it was opened.
+ refocus: true,
+
+ postCreate: function(){
+ if(this.contextMenuForWindow){
+ this.bindDomNode(dojo.body());
+ }else{
+ // TODO: should have _setTargetNodeIds() method to handle initialization and a possible
+ // later set('targetNodeIds', ...) call. There's also a problem that targetNodeIds[]
+ // gets stale after calls to bindDomNode()/unBindDomNode() as it still is just the original list (see #9610)
+ dojo.forEach(this.targetNodeIds, this.bindDomNode, this);
+ }
+ var k = dojo.keys, l = this.isLeftToRight();
+ this._openSubMenuKey = l ? k.RIGHT_ARROW : k.LEFT_ARROW;
+ this._closeSubMenuKey = l ? k.LEFT_ARROW : k.RIGHT_ARROW;
+ this.connectKeyNavHandlers([k.UP_ARROW], [k.DOWN_ARROW]);
+ },
+
+ _onKeyPress: function(/*Event*/ evt){
+ // summary:
+ // Handle keyboard based menu navigation.
+ // tags:
+ // protected
+
+ if(evt.ctrlKey || evt.altKey){ return; }
+
+ switch(evt.charOrCode){
+ case this._openSubMenuKey:
+ this._moveToPopup(evt);
+ dojo.stopEvent(evt);
+ break;
+ case this._closeSubMenuKey:
+ if(this.parentMenu){
+ if(this.parentMenu._isMenuBar){
+ this.parentMenu.focusPrev();
+ }else{
+ this.onCancel(false);
+ }
+ }else{
+ dojo.stopEvent(evt);
+ }
+ break;
+ }
+ },
+
+ // thanks burstlib!
+ _iframeContentWindow: function(/* HTMLIFrameElement */iframe_el){
+ // summary:
+ // Returns the window reference of the passed iframe
+ // tags:
+ // private
+ var win = dojo.window.get(this._iframeContentDocument(iframe_el)) ||
+ // Moz. TODO: is this available when defaultView isn't?
+ this._iframeContentDocument(iframe_el)['__parent__'] ||
+ (iframe_el.name && dojo.doc.frames[iframe_el.name]) || null;
+ return win; // Window
+ },
+
+ _iframeContentDocument: function(/* HTMLIFrameElement */iframe_el){
+ // summary:
+ // Returns a reference to the document object inside iframe_el
+ // tags:
+ // protected
+ var doc = iframe_el.contentDocument // W3
+ || (iframe_el.contentWindow && iframe_el.contentWindow.document) // IE
+ || (iframe_el.name && dojo.doc.frames[iframe_el.name] && dojo.doc.frames[iframe_el.name].document)
+ || null;
+ return doc; // HTMLDocument
+ },
+
+ bindDomNode: function(/*String|DomNode*/ node){
+ // summary:
+ // Attach menu to given node
+ node = dojo.byId(node);
+
+ var cn; // Connect node
+
+ // Support context menus on iframes. Rather than binding to the iframe itself we need
+ // to bind to the <body> node inside the iframe.
+ if(node.tagName.toLowerCase() == "iframe"){
+ var iframe = node,
+ win = this._iframeContentWindow(iframe);
+ cn = dojo.withGlobal(win, dojo.body);
+ }else{
+
+ // To capture these events at the top level, attach to <html>, not <body>.
+ // Otherwise right-click context menu just doesn't work.
+ cn = (node == dojo.body() ? dojo.doc.documentElement : node);
+ }
+
+
+ // "binding" is the object to track our connection to the node (ie, the parameter to bindDomNode())
+ var binding = {
+ node: node,
+ iframe: iframe
+ };
+
+ // Save info about binding in _bindings[], and make node itself record index(+1) into
+ // _bindings[] array. Prefix w/_dijitMenu to avoid setting an attribute that may
+ // start with a number, which fails on FF/safari.
+ dojo.attr(node, "_dijitMenu" + this.id, this._bindings.push(binding));
+
+ // Setup the connections to monitor click etc., unless we are connecting to an iframe which hasn't finished
+ // loading yet, in which case we need to wait for the onload event first, and then connect
+ // On linux Shift-F10 produces the oncontextmenu event, but on Windows it doesn't, so
+ // we need to monitor keyboard events in addition to the oncontextmenu event.
+ var doConnects = dojo.hitch(this, function(cn){
+ return [
+ // TODO: when leftClickToOpen is true then shouldn't space/enter key trigger the menu,
+ // rather than shift-F10?
+ dojo.connect(cn, this.leftClickToOpen ? "onclick" : "oncontextmenu", this, function(evt){
+ // Schedule context menu to be opened unless it's already been scheduled from onkeydown handler
+ dojo.stopEvent(evt);
+ this._scheduleOpen(evt.target, iframe, {x: evt.pageX, y: evt.pageY});
+ }),
+ dojo.connect(cn, "onkeydown", this, function(evt){
+ if(evt.shiftKey && evt.keyCode == dojo.keys.F10){
+ dojo.stopEvent(evt);
+ this._scheduleOpen(evt.target, iframe); // no coords - open near target node
+ }
+ })
+ ];
+ });
+ binding.connects = cn ? doConnects(cn) : [];
+
+ if(iframe){
+ // Setup handler to [re]bind to the iframe when the contents are initially loaded,
+ // and every time the contents change.
+ // Need to do this b/c we are actually binding to the iframe's <body> node.
+ // Note: can't use dojo.connect(), see #9609.
+
+ binding.onloadHandler = dojo.hitch(this, function(){
+ // want to remove old connections, but IE throws exceptions when trying to
+ // access the <body> node because it's already gone, or at least in a state of limbo
+
+ var win = this._iframeContentWindow(iframe);
+ cn = dojo.withGlobal(win, dojo.body);
+ binding.connects = doConnects(cn);
+ });
+ if(iframe.addEventListener){
+ iframe.addEventListener("load", binding.onloadHandler, false);
+ }else{
+ iframe.attachEvent("onload", binding.onloadHandler);
+ }
+ }
+ },
+
+ unBindDomNode: function(/*String|DomNode*/ nodeName){
+ // summary:
+ // Detach menu from given node
+
+ var node;
+ try{
+ node = dojo.byId(nodeName);
+ }catch(e){
+ // On IE the dojo.byId() call will get an exception if the attach point was
+ // the <body> node of an <iframe> that has since been reloaded (and thus the
+ // <body> node is in a limbo state of destruction.
+ return;
+ }
+
+ // node["_dijitMenu" + this.id] contains index(+1) into my _bindings[] array
+ var attrName = "_dijitMenu" + this.id;
+ if(node && dojo.hasAttr(node, attrName)){
+ var bid = dojo.attr(node, attrName)-1, b = this._bindings[bid];
+ dojo.forEach(b.connects, dojo.disconnect);
+
+ // Remove listener for iframe onload events
+ var iframe = b.iframe;
+ if(iframe){
+ if(iframe.removeEventListener){
+ iframe.removeEventListener("load", b.onloadHandler, false);
+ }else{
+ iframe.detachEvent("onload", b.onloadHandler);
+ }
+ }
+
+ dojo.removeAttr(node, attrName);
+ delete this._bindings[bid];
+ }
+ },
+
+ _scheduleOpen: function(/*DomNode?*/ target, /*DomNode?*/ iframe, /*Object?*/ coords){
+ // summary:
+ // Set timer to display myself. Using a timer rather than displaying immediately solves
+ // two problems:
+ //
+ // 1. IE: without the delay, focus work in "open" causes the system
+ // context menu to appear in spite of stopEvent.
+ //
+ // 2. Avoid double-shows on linux, where shift-F10 generates an oncontextmenu event
+ // even after a dojo.stopEvent(e). (Shift-F10 on windows doesn't generate the
+ // oncontextmenu event.)
+
+ if(!this._openTimer){
+ this._openTimer = setTimeout(dojo.hitch(this, function(){
+ delete this._openTimer;
+ this._openMyself({
+ target: target,
+ iframe: iframe,
+ coords: coords
+ });
+ }), 1);
+ }
+ },
+
+ _openMyself: function(args){
+ // summary:
+ // Internal function for opening myself when the user does a right-click or something similar.
+ // args:
+ // This is an Object containing:
+ // * target:
+ // The node that is being clicked
+ // * iframe:
+ // If an <iframe> is being clicked, iframe points to that iframe
+ // * coords:
+ // Put menu at specified x/y position in viewport, or if iframe is
+ // specified, then relative to iframe.
+ //
+ // _openMyself() formerly took the event object, and since various code references
+ // evt.target (after connecting to _openMyself()), using an Object for parameters
+ // (so that old code still works).
+
+ var target = args.target,
+ iframe = args.iframe,
+ coords = args.coords;
+
+ // Get coordinates to open menu, either at specified (mouse) position or (if triggered via keyboard)
+ // then near the node the menu is assigned to.
+ if(coords){
+ if(iframe){
+ // Specified coordinates are on <body> node of an <iframe>, convert to match main document
+ var od = target.ownerDocument,
+ ifc = dojo.position(iframe, true),
+ win = this._iframeContentWindow(iframe),
+ scroll = dojo.withGlobal(win, "_docScroll", dojo);
+
+ var cs = dojo.getComputedStyle(iframe),
+ tp = dojo._toPixelValue,
+ left = (dojo.isIE && dojo.isQuirks ? 0 : tp(iframe, cs.paddingLeft)) + (dojo.isIE && dojo.isQuirks ? tp(iframe, cs.borderLeftWidth) : 0),
+ top = (dojo.isIE && dojo.isQuirks ? 0 : tp(iframe, cs.paddingTop)) + (dojo.isIE && dojo.isQuirks ? tp(iframe, cs.borderTopWidth) : 0);
+
+ coords.x += ifc.x + left - scroll.x;
+ coords.y += ifc.y + top - scroll.y;
+ }
+ }else{
+ coords = dojo.position(target, true);
+ coords.x += 10;
+ coords.y += 10;
+ }
+
+ var self=this;
+ var savedFocus = dijit.getFocus(this);
+ function closeAndRestoreFocus(){
+ // user has clicked on a menu or popup
+ if(self.refocus){
+ dijit.focus(savedFocus);
+ }
+ dijit.popup.close(self);
+ }
+ dijit.popup.open({
+ popup: this,
+ x: coords.x,
+ y: coords.y,
+ onExecute: closeAndRestoreFocus,
+ onCancel: closeAndRestoreFocus,
+ orient: this.isLeftToRight() ? 'L' : 'R'
+ });
+ this.focus();
+
+ this._onBlur = function(){
+ this.inherited('_onBlur', arguments);
+ // Usually the parent closes the child widget but if this is a context
+ // menu then there is no parent
+ dijit.popup.close(this);
+ // don't try to restore focus; user has clicked another part of the screen
+ // and set focus there
+ };
+ },
+
+ uninitialize: function(){
+ dojo.forEach(this._bindings, function(b){ if(b){ this.unBindDomNode(b.node); } }, this);
+ this.inherited(arguments);
+ }
+}
+);
+
+}
+
+if(!dojo._hasResource["dojox.html.metrics"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.html.metrics"] = true;
+dojo.provide("dojox.html.metrics");
+
+(function(){
+ var dhm = dojox.html.metrics;
+
+ // derived from Morris John's emResized measurer
+ dhm.getFontMeasurements = function(){
+ // summary
+ // Returns an object that has pixel equivilents of standard font size values.
+ var heights = {
+ '1em':0, '1ex':0, '100%':0, '12pt':0, '16px':0, 'xx-small':0, 'x-small':0,
+ 'small':0, 'medium':0, 'large':0, 'x-large':0, 'xx-large':0
+ };
+
+ if(dojo.isIE){
+ // we do a font-size fix if and only if one isn't applied already.
+ // NOTE: If someone set the fontSize on the HTML Element, this will kill it.
+ dojo.doc.documentElement.style.fontSize="100%";
+ }
+
+ // set up the measuring node.
+ var div=dojo.doc.createElement("div");
+ var ds = div.style;
+ ds.position="absolute";
+ ds.left="-100px";
+ ds.top="0";
+ ds.width="30px";
+ ds.height="1000em";
+ ds.borderWidth="0";
+ ds.margin="0";
+ ds.padding="0";
+ ds.outline="0";
+ ds.lineHeight="1";
+ ds.overflow="hidden";
+ dojo.body().appendChild(div);
+
+ // do the measurements.
+ for(var p in heights){
+ ds.fontSize = p;
+ heights[p] = Math.round(div.offsetHeight * 12/16) * 16/12 / 1000;
+ }
+
+ dojo.body().removeChild(div);
+ div = null;
+ return heights; // object
+ };
+
+ var fontMeasurements = null;
+
+ dhm.getCachedFontMeasurements = function(recalculate){
+ if(recalculate || !fontMeasurements){
+ fontMeasurements = dhm.getFontMeasurements();
+ }
+ return fontMeasurements;
+ };
+
+ var measuringNode = null, empty = {};
+ dhm.getTextBox = function(/* String */ text, /* Object */ style, /* String? */ className){
+ var m, s;
+ if(!measuringNode){
+ m = measuringNode = dojo.doc.createElement("div");
+ // Container that we can set contraints on so that it doesn't
+ // trigger a scrollbar.
+ var c = dojo.doc.createElement("div");
+ c.appendChild(m);
+ s = c.style;
+ s.overflow='scroll';
+ s.position = "absolute";
+ s.left = "0px";
+ s.top = "-10000px";
+ s.width = "1px";
+ s.height = "1px";
+ s.visibility = "hidden";
+ s.borderWidth = "0";
+ s.margin = "0";
+ s.padding = "0";
+ s.outline = "0";
+ dojo.body().appendChild(c);
+ }else{
+ m = measuringNode;
+ }
+ // reset styles
+ m.className = "";
+ s = m.style;
+ s.borderWidth = "0";
+ s.margin = "0";
+ s.padding = "0";
+ s.outline = "0";
+ // set new style
+ if(arguments.length > 1 && style){
+ for(var i in style){
+ if(i in empty){ continue; }
+ s[i] = style[i];
+ }
+ }
+ // set classes
+ if(arguments.length > 2 && className){
+ m.className = className;
+ }
+ // take a measure
+ m.innerHTML = text;
+ var box = dojo.position(m);
+ // position doesn't report right (reports 1, since parent is 1)
+ // So we have to look at the scrollWidth to get the real width
+ // Height is right.
+ box.w = m.parentNode.scrollWidth;
+ return box;
+ };
+
+ // determine the scrollbar sizes on load.
+ var scroll={ w:16, h:16 };
+ dhm.getScrollbar=function(){ return { w:scroll.w, h:scroll.h }; };
+
+ dhm._fontResizeNode = null;
+
+ dhm.initOnFontResize = function(interval){
+ var f = dhm._fontResizeNode = dojo.doc.createElement("iframe");
+ var fs = f.style;
+ fs.position = "absolute";
+ fs.width = "5em";
+ fs.height = "10em";
+ fs.top = "-10000px";
+ if(dojo.isIE){
+ f.onreadystatechange = function(){
+ if(f.contentWindow.document.readyState == "complete"){
+ f.onresize = f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize;
+ }
+ };
+ }else{
+ f.onload = function(){
+ f.contentWindow.onresize = f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize;
+ };
+ }
+ //The script tag is to work around a known firebug race condition. See comments in bug #9046
+ f.setAttribute("src", "javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'");
+ dojo.body().appendChild(f);
+ dhm.initOnFontResize = function(){};
+ };
+
+ dhm.onFontResize = function(){};
+ dhm._fontresize = function(){
+ dhm.onFontResize();
+ }
+
+ dojo.addOnUnload(function(){
+ // destroy our font resize iframe if we have one
+ var f = dhm._fontResizeNode;
+ if(f){
+ if(dojo.isIE && f.onresize){
+ f.onresize = null;
+ }else if(f.contentWindow && f.contentWindow.onresize){
+ f.contentWindow.onresize = null;
+ }
+ dhm._fontResizeNode = null;
+ }
+ });
+
+ dojo.addOnLoad(function(){
+ // getScrollbar metrics node
+ try{
+ var n=dojo.doc.createElement("div");
+ n.style.cssText = "top:0;left:0;width:100px;height:100px;overflow:scroll;position:absolute;visibility:hidden;";
+ dojo.body().appendChild(n);
+ scroll.w = n.offsetWidth - n.clientWidth;
+ scroll.h = n.offsetHeight - n.clientHeight;
+ dojo.body().removeChild(n);
+ //console.log("Scroll bar dimensions: ", scroll);
+ delete n;
+ }catch(e){}
+
+ // text size poll setup
+ if("fontSizeWatch" in dojo.config && !!dojo.config.fontSizeWatch){
+ dhm.initOnFontResize();
+ }
+ });
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid.util"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.util"] = true;
+dojo.provide("dojox.grid.util");
+
+// summary: grid utility library
+(function(){
+ var dgu = dojox.grid.util;
+
+ dgu.na = '...';
+ dgu.rowIndexTag = "gridRowIndex";
+ dgu.gridViewTag = "gridView";
+
+
+ dgu.fire = function(ob, ev, args){
+ var fn = ob && ev && ob[ev];
+ return fn && (args ? fn.apply(ob, args) : ob[ev]());
+ };
+
+ dgu.setStyleHeightPx = function(inElement, inHeight){
+ if(inHeight >= 0){
+ var s = inElement.style;
+ var v = inHeight + 'px';
+ if(inElement && s['height'] != v){
+ s['height'] = v;
+ }
+ }
+ };
+
+ dgu.mouseEvents = [ 'mouseover', 'mouseout', /*'mousemove',*/ 'mousedown', 'mouseup', 'click', 'dblclick', 'contextmenu' ];
+
+ dgu.keyEvents = [ 'keyup', 'keydown', 'keypress' ];
+
+ dgu.funnelEvents = function(inNode, inObject, inMethod, inEvents){
+ var evts = (inEvents ? inEvents : dgu.mouseEvents.concat(dgu.keyEvents));
+ for (var i=0, l=evts.length; i<l; i++){
+ inObject.connect(inNode, 'on' + evts[i], inMethod);
+ }
+ };
+
+ dgu.removeNode = function(inNode){
+ inNode = dojo.byId(inNode);
+ inNode && inNode.parentNode && inNode.parentNode.removeChild(inNode);
+ return inNode;
+ };
+
+ dgu.arrayCompare = function(inA, inB){
+ for(var i=0,l=inA.length; i<l; i++){
+ if(inA[i] != inB[i]){return false;}
+ }
+ return (inA.length == inB.length);
+ };
+
+ dgu.arrayInsert = function(inArray, inIndex, inValue){
+ if(inArray.length <= inIndex){
+ inArray[inIndex] = inValue;
+ }else{
+ inArray.splice(inIndex, 0, inValue);
+ }
+ };
+
+ dgu.arrayRemove = function(inArray, inIndex){
+ inArray.splice(inIndex, 1);
+ };
+
+ dgu.arraySwap = function(inArray, inI, inJ){
+ var cache = inArray[inI];
+ inArray[inI] = inArray[inJ];
+ inArray[inJ] = cache;
+ };
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid._Scroller"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Scroller"] = true;
+dojo.provide("dojox.grid._Scroller");
+
+(function(){
+ var indexInParent = function(inNode){
+ var i=0, n, p=inNode.parentNode;
+ while((n = p.childNodes[i++])){
+ if(n == inNode){
+ return i - 1;
+ }
+ }
+ return -1;
+ };
+
+ var cleanNode = function(inNode){
+ if(!inNode){
+ return;
+ }
+ var filter = function(inW){
+ return inW.domNode && dojo.isDescendant(inW.domNode, inNode, true);
+ };
+ var ws = dijit.registry.filter(filter);
+ for(var i=0, w; (w=ws[i]); i++){
+ w.destroy();
+ }
+ delete ws;
+ };
+
+ var getTagName = function(inNodeOrId){
+ var node = dojo.byId(inNodeOrId);
+ return (node && node.tagName ? node.tagName.toLowerCase() : '');
+ };
+
+ var nodeKids = function(inNode, inTag){
+ var result = [];
+ var i=0, n;
+ while((n = inNode.childNodes[i])){
+ i++;
+ if(getTagName(n) == inTag){
+ result.push(n);
+ }
+ }
+ return result;
+ };
+
+ var divkids = function(inNode){
+ return nodeKids(inNode, 'div');
+ };
+
+ dojo.declare("dojox.grid._Scroller", null, {
+ constructor: function(inContentNodes){
+ this.setContentNodes(inContentNodes);
+ this.pageHeights = [];
+ this.pageNodes = [];
+ this.stack = [];
+ },
+ // specified
+ rowCount: 0, // total number of rows to manage
+ defaultRowHeight: 32, // default height of a row
+ keepRows: 100, // maximum number of rows that should exist at one time
+ contentNode: null, // node to contain pages
+ scrollboxNode: null, // node that controls scrolling
+ // calculated
+ defaultPageHeight: 0, // default height of a page
+ keepPages: 10, // maximum number of pages that should exists at one time
+ pageCount: 0,
+ windowHeight: 0,
+ firstVisibleRow: 0,
+ lastVisibleRow: 0,
+ averageRowHeight: 0, // the average height of a row
+ // private
+ page: 0,
+ pageTop: 0,
+ // init
+ init: function(inRowCount, inKeepRows, inRowsPerPage){
+ switch(arguments.length){
+ case 3: this.rowsPerPage = inRowsPerPage;
+ case 2: this.keepRows = inKeepRows;
+ case 1: this.rowCount = inRowCount;
+ default: break;
+ }
+ this.defaultPageHeight = this.defaultRowHeight * this.rowsPerPage;
+ this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage);
+ this.setKeepInfo(this.keepRows);
+ this.invalidate();
+ if(this.scrollboxNode){
+ this.scrollboxNode.scrollTop = 0;
+ this.scroll(0);
+ this.scrollboxNode.onscroll = dojo.hitch(this, 'onscroll');
+ }
+ },
+ _getPageCount: function(rowCount, rowsPerPage){
+ return rowCount ? (Math.ceil(rowCount / rowsPerPage) || 1) : 0;
+ },
+ destroy: function(){
+ this.invalidateNodes();
+ delete this.contentNodes;
+ delete this.contentNode;
+ delete this.scrollboxNode;
+ },
+ setKeepInfo: function(inKeepRows){
+ this.keepRows = inKeepRows;
+ this.keepPages = !this.keepRows ? this.keepPages : Math.max(Math.ceil(this.keepRows / this.rowsPerPage), 2);
+ },
+ // nodes
+ setContentNodes: function(inNodes){
+ this.contentNodes = inNodes;
+ this.colCount = (this.contentNodes ? this.contentNodes.length : 0);
+ this.pageNodes = [];
+ for(var i=0; i<this.colCount; i++){
+ this.pageNodes[i] = [];
+ }
+ },
+ getDefaultNodes: function(){
+ return this.pageNodes[0] || [];
+ },
+ // updating
+ invalidate: function(){
+ this._invalidating = true;
+ this.invalidateNodes();
+ this.pageHeights = [];
+ this.height = (this.pageCount ? (this.pageCount - 1)* this.defaultPageHeight + this.calcLastPageHeight() : 0);
+ this.resize();
+ this._invalidating = false;
+ },
+ updateRowCount: function(inRowCount){
+ this.invalidateNodes();
+ this.rowCount = inRowCount;
+ // update page count, adjust document height
+ var oldPageCount = this.pageCount;
+ if(oldPageCount === 0){
+ //We want to have at least 1px in height to keep scroller. Otherwise with an
+ //empty grid you can't scroll to see the header.
+ this.height = 1;
+ }
+ this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage);
+ if(this.pageCount < oldPageCount){
+ for(var i=oldPageCount-1; i>=this.pageCount; i--){
+ this.height -= this.getPageHeight(i);
+ delete this.pageHeights[i];
+ }
+ }else if(this.pageCount > oldPageCount){
+ this.height += this.defaultPageHeight * (this.pageCount - oldPageCount - 1) + this.calcLastPageHeight();
+ }
+ this.resize();
+ },
+ // implementation for page manager
+ pageExists: function(inPageIndex){
+ return Boolean(this.getDefaultPageNode(inPageIndex));
+ },
+ measurePage: function(inPageIndex){
+ if(this.grid.rowHeight){
+ var height = this.grid.rowHeight + 1;
+ return ((inPageIndex + 1) * this.rowsPerPage > this.rowCount ?
+ this.rowCount - inPageIndex * this.rowsPerPage :
+ this.rowsPerPage) * height;
+
+ }
+ var n = this.getDefaultPageNode(inPageIndex);
+ return (n && n.innerHTML) ? n.offsetHeight : undefined;
+ },
+ positionPage: function(inPageIndex, inPos){
+ for(var i=0; i<this.colCount; i++){
+ this.pageNodes[i][inPageIndex].style.top = inPos + 'px';
+ }
+ },
+ repositionPages: function(inPageIndex){
+ var nodes = this.getDefaultNodes();
+ var last = 0;
+
+ for(var i=0; i<this.stack.length; i++){
+ last = Math.max(this.stack[i], last);
+ }
+ //
+ var n = nodes[inPageIndex];
+ var y = (n ? this.getPageNodePosition(n) + this.getPageHeight(inPageIndex) : 0);
+ for(var p=inPageIndex+1; p<=last; p++){
+ n = nodes[p];
+ if(n){
+ if(this.getPageNodePosition(n) == y){
+ return;
+ }
+ this.positionPage(p, y);
+ }
+ y += this.getPageHeight(p);
+ }
+ },
+ installPage: function(inPageIndex){
+ for(var i=0; i<this.colCount; i++){
+ this.contentNodes[i].appendChild(this.pageNodes[i][inPageIndex]);
+ }
+ },
+ preparePage: function(inPageIndex, inReuseNode){
+ var p = (inReuseNode ? this.popPage() : null);
+ for(var i=0; i<this.colCount; i++){
+ var nodes = this.pageNodes[i];
+ var new_p = (p === null ? this.createPageNode() : this.invalidatePageNode(p, nodes));
+ new_p.pageIndex = inPageIndex;
+ nodes[inPageIndex] = new_p;
+ }
+ },
+ // rendering implementation
+ renderPage: function(inPageIndex){
+ var nodes = [];
+ var i, j;
+ for(i=0; i<this.colCount; i++){
+ nodes[i] = this.pageNodes[i][inPageIndex];
+ }
+ for(i=0, j=inPageIndex*this.rowsPerPage; (i<this.rowsPerPage)&&(j<this.rowCount); i++, j++){
+ this.renderRow(j, nodes);
+ }
+ },
+ removePage: function(inPageIndex){
+ for(var i=0, j=inPageIndex*this.rowsPerPage; i<this.rowsPerPage; i++, j++){
+ this.removeRow(j);
+ }
+ },
+ destroyPage: function(inPageIndex){
+ for(var i=0; i<this.colCount; i++){
+ var n = this.invalidatePageNode(inPageIndex, this.pageNodes[i]);
+ if(n){
+ dojo.destroy(n);
+ }
+ }
+ },
+ pacify: function(inShouldPacify){
+ },
+ // pacification
+ pacifying: false,
+ pacifyTicks: 200,
+ setPacifying: function(inPacifying){
+ if(this.pacifying != inPacifying){
+ this.pacifying = inPacifying;
+ this.pacify(this.pacifying);
+ }
+ },
+ startPacify: function(){
+ this.startPacifyTicks = new Date().getTime();
+ },
+ doPacify: function(){
+ var result = (new Date().getTime() - this.startPacifyTicks) > this.pacifyTicks;
+ this.setPacifying(true);
+ this.startPacify();
+ return result;
+ },
+ endPacify: function(){
+ this.setPacifying(false);
+ },
+ // default sizing implementation
+ resize: function(){
+ if(this.scrollboxNode){
+ this.windowHeight = this.scrollboxNode.clientHeight;
+ }
+ for(var i=0; i<this.colCount; i++){
+ //We want to have 1px in height min to keep scroller. Otherwise can't scroll
+ //and see header in empty grid.
+ dojox.grid.util.setStyleHeightPx(this.contentNodes[i], Math.max(1,this.height));
+ }
+
+ // Calculate the average row height and update the defaults (row and page).
+ var needPage = (!this._invalidating);
+ if(!needPage){
+ var ah = this.grid.get("autoHeight");
+ if(typeof ah == "number" && ah <= Math.min(this.rowsPerPage, this.rowCount)){
+ needPage = true;
+ }
+ }
+ if(needPage){
+ this.needPage(this.page, this.pageTop);
+ }
+ var rowsOnPage = (this.page < this.pageCount - 1) ? this.rowsPerPage : ((this.rowCount % this.rowsPerPage) || this.rowsPerPage);
+ var pageHeight = this.getPageHeight(this.page);
+ this.averageRowHeight = (pageHeight > 0 && rowsOnPage > 0) ? (pageHeight / rowsOnPage) : 0;
+ },
+ calcLastPageHeight: function(){
+ if(!this.pageCount){
+ return 0;
+ }
+ var lastPage = this.pageCount - 1;
+ var lastPageHeight = ((this.rowCount % this.rowsPerPage)||(this.rowsPerPage)) * this.defaultRowHeight;
+ this.pageHeights[lastPage] = lastPageHeight;
+ return lastPageHeight;
+ },
+ updateContentHeight: function(inDh){
+ this.height += inDh;
+ this.resize();
+ },
+ updatePageHeight: function(inPageIndex, fromBuild, fromAsynRendering){
+ if(this.pageExists(inPageIndex)){
+ var oh = this.getPageHeight(inPageIndex);
+ var h = (this.measurePage(inPageIndex));
+ if(h === undefined){
+ h = oh;
+ }
+ this.pageHeights[inPageIndex] = h;
+ if(oh != h){
+ this.updateContentHeight(h - oh);
+ var ah = this.grid.get("autoHeight");
+ if((typeof ah == "number" && ah > this.rowCount)||(ah === true && !fromBuild)){
+ if(!fromAsynRendering){
+ this.grid.sizeChange();
+ }else{//fix #11101 by using fromAsynRendering to avoid deadlock
+ var ns = this.grid.viewsNode.style;
+ ns.height = parseInt(ns.height) + h - oh + 'px';
+ this.repositionPages(inPageIndex);
+ }
+ }else{
+ this.repositionPages(inPageIndex);
+ }
+ }
+ return h;
+ }
+ return 0;
+ },
+ rowHeightChanged: function(inRowIndex, fromAsynRendering){
+ this.updatePageHeight(Math.floor(inRowIndex / this.rowsPerPage), false, fromAsynRendering);
+ },
+ // scroller core
+ invalidateNodes: function(){
+ while(this.stack.length){
+ this.destroyPage(this.popPage());
+ }
+ },
+ createPageNode: function(){
+ var p = document.createElement('div');
+ dojo.attr(p,"role","presentation");
+ p.style.position = 'absolute';
+ //p.style.width = '100%';
+ p.style[dojo._isBodyLtr() ? "left" : "right"] = '0';
+ return p;
+ },
+ getPageHeight: function(inPageIndex){
+ var ph = this.pageHeights[inPageIndex];
+ return (ph !== undefined ? ph : this.defaultPageHeight);
+ },
+ // FIXME: this is not a stack, it's a FIFO list
+ pushPage: function(inPageIndex){
+ return this.stack.push(inPageIndex);
+ },
+ popPage: function(){
+ return this.stack.shift();
+ },
+ findPage: function(inTop){
+ var i = 0, h = 0;
+ for(var ph = 0; i<this.pageCount; i++, h += ph){
+ ph = this.getPageHeight(i);
+ if(h + ph >= inTop){
+ break;
+ }
+ }
+ this.page = i;
+ this.pageTop = h;
+ },
+ buildPage: function(inPageIndex, inReuseNode, inPos){
+ this.preparePage(inPageIndex, inReuseNode);
+ this.positionPage(inPageIndex, inPos);
+ // order of operations is key below
+ this.installPage(inPageIndex);
+ this.renderPage(inPageIndex);
+ // order of operations is key above
+ this.pushPage(inPageIndex);
+ },
+ needPage: function(inPageIndex, inPos){
+ var h = this.getPageHeight(inPageIndex), oh = h;
+ if(!this.pageExists(inPageIndex)){
+ this.buildPage(inPageIndex, (!this.grid._autoHeight/*fix #10543*/ && this.keepPages&&(this.stack.length >= this.keepPages)), inPos);
+ h = this.updatePageHeight(inPageIndex, true);
+ }else{
+ this.positionPage(inPageIndex, inPos);
+ }
+ return h;
+ },
+ onscroll: function(){
+ this.scroll(this.scrollboxNode.scrollTop);
+ },
+ scroll: function(inTop){
+ this.grid.scrollTop = inTop;
+ if(this.colCount){
+ this.startPacify();
+ this.findPage(inTop);
+ var h = this.height;
+ var b = this.getScrollBottom(inTop);
+ for(var p=this.page, y=this.pageTop; (p<this.pageCount)&&((b<0)||(y<b)); p++){
+ y += this.needPage(p, y);
+ }
+ this.firstVisibleRow = this.getFirstVisibleRow(this.page, this.pageTop, inTop);
+ this.lastVisibleRow = this.getLastVisibleRow(p - 1, y, b);
+ // indicates some page size has been updated
+ if(h != this.height){
+ this.repositionPages(p-1);
+ }
+ this.endPacify();
+ }
+ },
+ getScrollBottom: function(inTop){
+ return (this.windowHeight >= 0 ? inTop + this.windowHeight : -1);
+ },
+ // events
+ processNodeEvent: function(e, inNode){
+ var t = e.target;
+ while(t && (t != inNode) && t.parentNode && (t.parentNode.parentNode != inNode)){
+ t = t.parentNode;
+ }
+ if(!t || !t.parentNode || (t.parentNode.parentNode != inNode)){
+ return false;
+ }
+ var page = t.parentNode;
+ e.topRowIndex = page.pageIndex * this.rowsPerPage;
+ e.rowIndex = e.topRowIndex + indexInParent(t);
+ e.rowTarget = t;
+ return true;
+ },
+ processEvent: function(e){
+ return this.processNodeEvent(e, this.contentNode);
+ },
+ // virtual rendering interface
+ renderRow: function(inRowIndex, inPageNode){
+ },
+ removeRow: function(inRowIndex){
+ },
+ // page node operations
+ getDefaultPageNode: function(inPageIndex){
+ return this.getDefaultNodes()[inPageIndex];
+ },
+ positionPageNode: function(inNode, inPos){
+ },
+ getPageNodePosition: function(inNode){
+ return inNode.offsetTop;
+ },
+ invalidatePageNode: function(inPageIndex, inNodes){
+ var p = inNodes[inPageIndex];
+ if(p){
+ delete inNodes[inPageIndex];
+ this.removePage(inPageIndex, p);
+ cleanNode(p);
+ p.innerHTML = '';
+ }
+ return p;
+ },
+ // scroll control
+ getPageRow: function(inPage){
+ return inPage * this.rowsPerPage;
+ },
+ getLastPageRow: function(inPage){
+ return Math.min(this.rowCount, this.getPageRow(inPage + 1)) - 1;
+ },
+ getFirstVisibleRow: function(inPage, inPageTop, inScrollTop){
+ if(!this.pageExists(inPage)){
+ return 0;
+ }
+ var row = this.getPageRow(inPage);
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[inPage]);
+ for(var i=0,l=rows.length; i<l && inPageTop<inScrollTop; i++, row++){
+ inPageTop += rows[i].offsetHeight;
+ }
+ return (row ? row - 1 : row);
+ },
+ getLastVisibleRow: function(inPage, inBottom, inScrollBottom){
+ if(!this.pageExists(inPage)){
+ return 0;
+ }
+ var nodes = this.getDefaultNodes();
+ var row = this.getLastPageRow(inPage);
+ var rows = divkids(nodes[inPage]);
+ for(var i=rows.length-1; i>=0 && inBottom>inScrollBottom; i--, row--){
+ inBottom -= rows[i].offsetHeight;
+ }
+ return row + 1;
+ },
+ findTopRow: function(inScrollTop){
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[this.page]);
+ for(var i=0,l=rows.length,t=this.pageTop,h; i<l; i++){
+ h = rows[i].offsetHeight;
+ t += h;
+ if(t >= inScrollTop){
+ this.offset = h - (t - inScrollTop);
+ return i + this.page * this.rowsPerPage;
+ }
+ }
+ return -1;
+ },
+ findScrollTop: function(inRow){
+ var rowPage = Math.floor(inRow / this.rowsPerPage);
+ var t = 0;
+ var i, l;
+ for(i=0; i<rowPage; i++){
+ t += this.getPageHeight(i);
+ }
+ this.pageTop = t;
+ this.page = rowPage;//fix #10543
+ this.needPage(rowPage, this.pageTop);
+
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[rowPage]);
+ var r = inRow - this.rowsPerPage * rowPage;
+ for(i=0,l=rows.length; i<l && i<r; i++){
+ t += rows[i].offsetHeight;
+ }
+ return t;
+ },
+ dummy: 0
+ });
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid.cells._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.cells._base"] = true;
+dojo.provide("dojox.grid.cells._base");
+
+
+
+
+dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
+ deferred: null,
+ _destroyOnRemove: true,
+ postCreate: function(){
+ if(this.deferred){
+ this.deferred.addBoth(dojo.hitch(this, function(text){
+ if(this.domNode){
+ this.domNode.innerHTML = text;
+ }
+ }));
+ }
+ }
+});
+
+(function(){
+ var focusSelectNode = function(inNode){
+ try{
+ dojox.grid.util.fire(inNode, "focus");
+ dojox.grid.util.fire(inNode, "select");
+ }catch(e){// IE sux bad
+ }
+ };
+
+ var whenIdle = function(/*inContext, inMethod, args ...*/){
+ setTimeout(dojo.hitch.apply(dojo, arguments), 0);
+ };
+
+ var dgc = dojox.grid.cells;
+
+ dojo.declare("dojox.grid.cells._Base", null, {
+ // summary:
+ // Respresents a grid cell and contains information about column options and methods
+ // for retrieving cell related information.
+ // Each column in a grid layout has a cell object and most events and many methods
+ // provide access to these objects.
+ styles: '',
+ classes: '',
+ editable: false,
+ alwaysEditing: false,
+ formatter: null,
+ defaultValue: '...',
+ value: null,
+ hidden: false,
+ noresize: false,
+ draggable: true,
+ //private
+ _valueProp: "value",
+ _formatPending: false,
+
+ constructor: function(inProps){
+ this._props = inProps || {};
+ dojo.mixin(this, inProps);
+ if(this.draggable === undefined){
+ this.draggable = true;
+ }
+ },
+
+ _defaultFormat: function(inValue, callArgs){
+ var s = this.grid.formatterScope || this;
+ var f = this.formatter;
+ if(f && s && typeof f == "string"){
+ f = this.formatter = s[f];
+ }
+ var v = (inValue != this.defaultValue && f) ? f.apply(s, callArgs) : inValue;
+ if(typeof v == "undefined"){
+ return this.defaultValue;
+ }
+ if(v && v.addBoth){
+ // Check if it's a deferred
+ v = new dojox.grid._DeferredTextWidget({deferred: v},
+ dojo.create("span", {innerHTML: this.defaultValue}));
+ }
+ if(v && v.declaredClass && v.startup){
+ return "<div class='dojoxGridStubNode' linkWidget='" +
+ v.id +
+ "' cellIdx='" +
+ this.index +
+ "'>" +
+ this.defaultValue +
+ "</div>";
+ }
+ return v;
+ },
+
+ // data source
+ format: function(inRowIndex, inItem){
+ // summary:
+ // provides the html for a given grid cell.
+ // inRowIndex: int
+ // grid row index
+ // returns: html for a given grid cell
+ var f, i=this.grid.edit.info, d=this.get ? this.get(inRowIndex, inItem) : (this.value || this.defaultValue);
+ d = (d && d.replace && this.grid.escapeHTMLInData) ? d.replace(/&/g, '&amp;').replace(/</g, '&lt;') : d;
+ if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndex && i.cell==this))){
+ return this.formatEditing(d, inRowIndex);
+ }else{
+ return this._defaultFormat(d, [d, inRowIndex, this]);
+ }
+ },
+ formatEditing: function(inDatum, inRowIndex){
+ // summary:
+ // formats the cell for editing
+ // inDatum: anything
+ // cell data to edit
+ // inRowIndex: int
+ // grid row index
+ // returns: string of html to place in grid cell
+ },
+ // utility
+ getNode: function(inRowIndex){
+ // summary:
+ // gets the dom node for a given grid cell.
+ // inRowIndex: int
+ // grid row index
+ // returns: dom node for a given grid cell
+ return this.view.getCellNode(inRowIndex, this.index);
+ },
+ getHeaderNode: function(){
+ return this.view.getHeaderCellNode(this.index);
+ },
+ getEditNode: function(inRowIndex){
+ return (this.getNode(inRowIndex) || 0).firstChild || 0;
+ },
+ canResize: function(){
+ var uw = this.unitWidth;
+ return uw && (uw!=='auto');
+ },
+ isFlex: function(){
+ var uw = this.unitWidth;
+ return uw && dojo.isString(uw) && (uw=='auto' || uw.slice(-1)=='%');
+ },
+ // edit support
+ applyEdit: function(inValue, inRowIndex){
+ this.grid.edit.applyCellEdit(inValue, this, inRowIndex);
+ },
+ cancelEdit: function(inRowIndex){
+ this.grid.doCancelEdit(inRowIndex);
+ },
+ _onEditBlur: function(inRowIndex){
+ if(this.grid.edit.isEditCell(inRowIndex, this.index)){
+ //console.log('editor onblur', e);
+ this.grid.edit.apply();
+ }
+ },
+ registerOnBlur: function(inNode, inRowIndex){
+ if(this.commitOnBlur){
+ dojo.connect(inNode, "onblur", function(e){
+ // hack: if editor still thinks this editor is current some ms after it blurs, assume we've focused away from grid
+ setTimeout(dojo.hitch(this, "_onEditBlur", inRowIndex), 250);
+ });
+ }
+ },
+ //protected
+ needFormatNode: function(inDatum, inRowIndex){
+ this._formatPending = true;
+ whenIdle(this, "_formatNode", inDatum, inRowIndex);
+ },
+ cancelFormatNode: function(){
+ this._formatPending = false;
+ },
+ //private
+ _formatNode: function(inDatum, inRowIndex){
+ if(this._formatPending){
+ this._formatPending = false;
+ // make cell selectable
+ dojo.setSelectable(this.grid.domNode, true);
+ this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex);
+ }
+ },
+ //protected
+ formatNode: function(inNode, inDatum, inRowIndex){
+ // summary:
+ // format the editing dom node. Use when editor is a widget.
+ // inNode: dom node
+ // dom node for the editor
+ // inDatum: anything
+ // cell data to edit
+ // inRowIndex: int
+ // grid row index
+ if(dojo.isIE){
+ // IE sux bad
+ whenIdle(this, "focus", inRowIndex, inNode);
+ }else{
+ this.focus(inRowIndex, inNode);
+ }
+ },
+ dispatchEvent: function(m, e){
+ if(m in this){
+ return this[m](e);
+ }
+ },
+ //public
+ getValue: function(inRowIndex){
+ // summary:
+ // returns value entered into editor
+ // inRowIndex: int
+ // grid row index
+ // returns:
+ // value of editor
+ return this.getEditNode(inRowIndex)[this._valueProp];
+ },
+ setValue: function(inRowIndex, inValue){
+ // summary:
+ // set the value of the grid editor
+ // inRowIndex: int
+ // grid row index
+ // inValue: anything
+ // value of editor
+ var n = this.getEditNode(inRowIndex);
+ if(n){
+ n[this._valueProp] = inValue;
+ }
+ },
+ focus: function(inRowIndex, inNode){
+ // summary:
+ // focus the grid editor
+ // inRowIndex: int
+ // grid row index
+ // inNode: dom node
+ // editor node
+ focusSelectNode(inNode || this.getEditNode(inRowIndex));
+ },
+ save: function(inRowIndex){
+ // summary:
+ // save editor state
+ // inRowIndex: int
+ // grid row index
+ this.value = this.value || this.getValue(inRowIndex);
+ //console.log("save", this.value, inCell.index, inRowIndex);
+ },
+ restore: function(inRowIndex){
+ // summary:
+ // restore editor state
+ // inRowIndex: int
+ // grid row index
+ this.setValue(inRowIndex, this.value);
+ //console.log("restore", this.value, inCell.index, inRowIndex);
+ },
+ //protected
+ _finish: function(inRowIndex){
+ // summary:
+ // called when editing is completed to clean up editor
+ // inRowIndex: int
+ // grid row index
+ dojo.setSelectable(this.grid.domNode, false);
+ this.cancelFormatNode();
+ },
+ //public
+ apply: function(inRowIndex){
+ // summary:
+ // apply edit from cell editor
+ // inRowIndex: int
+ // grid row index
+ this.applyEdit(this.getValue(inRowIndex), inRowIndex);
+ this._finish(inRowIndex);
+ },
+ cancel: function(inRowIndex){
+ // summary:
+ // cancel cell edit
+ // inRowIndex: int
+ // grid row index
+ this.cancelEdit(inRowIndex);
+ this._finish(inRowIndex);
+ }
+ });
+ dgc._Base.markupFactory = function(node, cellDef){
+ var d = dojo;
+ var formatter = d.trim(d.attr(node, "formatter")||"");
+ if(formatter){
+ cellDef.formatter = dojo.getObject(formatter)||formatter;
+ }
+ var get = d.trim(d.attr(node, "get")||"");
+ if(get){
+ cellDef.get = dojo.getObject(get);
+ }
+ var getBoolAttr = function(attr, cell, cellAttr){
+ var value = d.trim(d.attr(node, attr)||"");
+ if(value){ cell[cellAttr||attr] = !(value.toLowerCase()=="false"); }
+ };
+ getBoolAttr("sortDesc", cellDef);
+ getBoolAttr("editable", cellDef);
+ getBoolAttr("alwaysEditing", cellDef);
+ getBoolAttr("noresize", cellDef);
+ getBoolAttr("draggable", cellDef);
+
+ var value = d.trim(d.attr(node, "loadingText")||d.attr(node, "defaultValue")||"");
+ if(value){
+ cellDef.defaultValue = value;
+ }
+
+ var getStrAttr = function(attr, cell, cellAttr){
+ var value = d.trim(d.attr(node, attr)||"")||undefined;
+ if(value){ cell[cellAttr||attr] = value; }
+ };
+ getStrAttr("styles", cellDef);
+ getStrAttr("headerStyles", cellDef);
+ getStrAttr("cellStyles", cellDef);
+ getStrAttr("classes", cellDef);
+ getStrAttr("headerClasses", cellDef);
+ getStrAttr("cellClasses", cellDef);
+ };
+
+ dojo.declare("dojox.grid.cells.Cell", dgc._Base, {
+ // summary
+ // grid cell that provides a standard text input box upon editing
+ constructor: function(){
+ this.keyFilter = this.keyFilter;
+ },
+ // keyFilter: RegExp
+ // optional regex for disallowing keypresses
+ keyFilter: null,
+ formatEditing: function(inDatum, inRowIndex){
+ this.needFormatNode(inDatum, inRowIndex);
+ return '<input class="dojoxGridInput" type="text" value="' + inDatum + '">';
+ },
+ formatNode: function(inNode, inDatum, inRowIndex){
+ this.inherited(arguments);
+ // FIXME: feels too specific for this interface
+ this.registerOnBlur(inNode, inRowIndex);
+ },
+ doKey: function(e){
+ if(this.keyFilter){
+ var key = String.fromCharCode(e.charCode);
+ if(key.search(this.keyFilter) == -1){
+ dojo.stopEvent(e);
+ }
+ }
+ },
+ _finish: function(inRowIndex){
+ this.inherited(arguments);
+ var n = this.getEditNode(inRowIndex);
+ try{
+ dojox.grid.util.fire(n, "blur");
+ }catch(e){}
+ }
+ });
+ dgc.Cell.markupFactory = function(node, cellDef){
+ dgc._Base.markupFactory(node, cellDef);
+ var d = dojo;
+ var keyFilter = d.trim(d.attr(node, "keyFilter")||"");
+ if(keyFilter){
+ cellDef.keyFilter = new RegExp(keyFilter);
+ }
+ };
+
+ dojo.declare("dojox.grid.cells.RowIndex", dgc.Cell, {
+ name: 'Row',
+
+ postscript: function(){
+ this.editable = false;
+ },
+ get: function(inRowIndex){
+ return inRowIndex + 1;
+ }
+ });
+ dgc.RowIndex.markupFactory = function(node, cellDef){
+ dgc.Cell.markupFactory(node, cellDef);
+ };
+
+ dojo.declare("dojox.grid.cells.Select", dgc.Cell, {
+ // summary:
+ // grid cell that provides a standard select for editing
+
+ // options: Array
+ // text of each item
+ options: null,
+
+ // values: Array
+ // value for each item
+ values: null,
+
+ // returnIndex: Integer
+ // editor returns only the index of the selected option and not the value
+ returnIndex: -1,
+
+ constructor: function(inCell){
+ this.values = this.values || this.options;
+ },
+ formatEditing: function(inDatum, inRowIndex){
+ this.needFormatNode(inDatum, inRowIndex);
+ var h = [ '<select class="dojoxGridSelect">' ];
+ for (var i=0, o, v; ((o=this.options[i]) !== undefined)&&((v=this.values[i]) !== undefined); i++){
+ h.push("<option", (inDatum==v ? ' selected' : ''), ' value="' + v + '"', ">", o, "</option>");
+ }
+ h.push('</select>');
+ return h.join('');
+ },
+ getValue: function(inRowIndex){
+ var n = this.getEditNode(inRowIndex);
+ if(n){
+ var i = n.selectedIndex, o = n.options[i];
+ return this.returnIndex > -1 ? i : o.value || o.innerHTML;
+ }
+ }
+ });
+ dgc.Select.markupFactory = function(node, cell){
+ dgc.Cell.markupFactory(node, cell);
+ var d=dojo;
+ var options = d.trim(d.attr(node, "options")||"");
+ if(options){
+ var o = options.split(',');
+ if(o[0] != options){
+ cell.options = o;
+ }
+ }
+ var values = d.trim(d.attr(node, "values")||"");
+ if(values){
+ var v = values.split(',');
+ if(v[0] != values){
+ cell.values = v;
+ }
+ }
+ };
+
+ dojo.declare("dojox.grid.cells.AlwaysEdit", dgc.Cell, {
+ // summary:
+ // grid cell that is always in an editable state, regardless of grid editing state
+ alwaysEditing: true,
+ _formatNode: function(inDatum, inRowIndex){
+ this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex);
+ },
+ applyStaticValue: function(inRowIndex){
+ var e = this.grid.edit;
+ e.applyCellEdit(this.getValue(inRowIndex), this, inRowIndex);
+ e.start(this, inRowIndex, true);
+ }
+ });
+ dgc.AlwaysEdit.markupFactory = function(node, cell){
+ dgc.Cell.markupFactory(node, cell);
+ };
+
+ dojo.declare("dojox.grid.cells.Bool", dgc.AlwaysEdit, {
+ // summary:
+ // grid cell that provides a standard checkbox that is always on for editing
+ _valueProp: "checked",
+ formatEditing: function(inDatum, inRowIndex){
+ return '<input class="dojoxGridInput" type="checkbox"' + (inDatum ? ' checked="checked"' : '') + ' style="width: auto" />';
+ },
+ doclick: function(e){
+ if(e.target.tagName == 'INPUT'){
+ this.applyStaticValue(e.rowIndex);
+ }
+ }
+ });
+ dgc.Bool.markupFactory = function(node, cell){
+ dgc.AlwaysEdit.markupFactory(node, cell);
+ };
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid.cells"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.cells"] = true;
+dojo.provide("dojox.grid.cells");
+
+
+}
+
+if(!dojo._hasResource["dojo.dnd.common"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.common"] = true;
+dojo.provide("dojo.dnd.common");
+
+
+dojo.getObject("dnd", true, dojo);
+
+dojo.dnd.getCopyKeyState = dojo.isCopyKey;
+
+dojo.dnd._uniqueId = 0;
+dojo.dnd.getUniqueId = function(){
+ // summary:
+ // returns a unique string for use with any DOM element
+ var id;
+ do{
+ id = dojo._scopeName + "Unique" + (++dojo.dnd._uniqueId);
+ }while(dojo.byId(id));
+ return id;
+};
+
+dojo.dnd._empty = {};
+
+dojo.dnd.isFormElement = function(/*Event*/ e){
+ // summary:
+ // returns true if user clicked on a form element
+ var t = e.target;
+ if(t.nodeType == 3 /*TEXT_NODE*/){
+ t = t.parentNode;
+ }
+ return " button textarea input select option ".indexOf(" " + t.tagName.toLowerCase() + " ") >= 0; // Boolean
+};
+
+}
+
+if(!dojo._hasResource["dojo.dnd.autoscroll"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.autoscroll"] = true;
+dojo.provide("dojo.dnd.autoscroll");
+
+
+
+dojo.getObject("dnd", true, dojo);
+
+dojo.dnd.getViewport = dojo.window.getBox;
+
+dojo.dnd.V_TRIGGER_AUTOSCROLL = 32;
+dojo.dnd.H_TRIGGER_AUTOSCROLL = 32;
+
+dojo.dnd.V_AUTOSCROLL_VALUE = 16;
+dojo.dnd.H_AUTOSCROLL_VALUE = 16;
+
+dojo.dnd.autoScroll = function(e){
+ // summary:
+ // a handler for onmousemove event, which scrolls the window, if
+ // necesary
+ // e: Event
+ // onmousemove event
+
+ // FIXME: needs more docs!
+ var v = dojo.window.getBox(), dx = 0, dy = 0;
+ if(e.clientX < dojo.dnd.H_TRIGGER_AUTOSCROLL){
+ dx = -dojo.dnd.H_AUTOSCROLL_VALUE;
+ }else if(e.clientX > v.w - dojo.dnd.H_TRIGGER_AUTOSCROLL){
+ dx = dojo.dnd.H_AUTOSCROLL_VALUE;
+ }
+ if(e.clientY < dojo.dnd.V_TRIGGER_AUTOSCROLL){
+ dy = -dojo.dnd.V_AUTOSCROLL_VALUE;
+ }else if(e.clientY > v.h - dojo.dnd.V_TRIGGER_AUTOSCROLL){
+ dy = dojo.dnd.V_AUTOSCROLL_VALUE;
+ }
+ window.scrollBy(dx, dy);
+};
+
+dojo.dnd._validNodes = {"div": 1, "p": 1, "td": 1};
+dojo.dnd._validOverflow = {"auto": 1, "scroll": 1};
+
+dojo.dnd.autoScrollNodes = function(e){
+ // summary:
+ // a handler for onmousemove event, which scrolls the first avaialble
+ // Dom element, it falls back to dojo.dnd.autoScroll()
+ // e: Event
+ // onmousemove event
+
+ // FIXME: needs more docs!
+ for(var n = e.target; n;){
+ if(n.nodeType == 1 && (n.tagName.toLowerCase() in dojo.dnd._validNodes)){
+ var s = dojo.getComputedStyle(n);
+ if(s.overflow.toLowerCase() in dojo.dnd._validOverflow){
+ var b = dojo._getContentBox(n, s), t = dojo.position(n, true);
+ //console.log(b.l, b.t, t.x, t.y, n.scrollLeft, n.scrollTop);
+ var w = Math.min(dojo.dnd.H_TRIGGER_AUTOSCROLL, b.w / 2),
+ h = Math.min(dojo.dnd.V_TRIGGER_AUTOSCROLL, b.h / 2),
+ rx = e.pageX - t.x, ry = e.pageY - t.y, dx = 0, dy = 0;
+ if(dojo.isWebKit || dojo.isOpera){
+ // FIXME: this code should not be here, it should be taken into account
+ // either by the event fixing code, or the dojo.position()
+ // FIXME: this code doesn't work on Opera 9.5 Beta
+ rx += dojo.body().scrollLeft;
+ ry += dojo.body().scrollTop;
+ }
+ if(rx > 0 && rx < b.w){
+ if(rx < w){
+ dx = -w;
+ }else if(rx > b.w - w){
+ dx = w;
+ }
+ }
+ //console.log("ry =", ry, "b.h =", b.h, "h =", h);
+ if(ry > 0 && ry < b.h){
+ if(ry < h){
+ dy = -h;
+ }else if(ry > b.h - h){
+ dy = h;
+ }
+ }
+ var oldLeft = n.scrollLeft, oldTop = n.scrollTop;
+ n.scrollLeft = n.scrollLeft + dx;
+ n.scrollTop = n.scrollTop + dy;
+ if(oldLeft != n.scrollLeft || oldTop != n.scrollTop){ return; }
+ }
+ }
+ try{
+ n = n.parentNode;
+ }catch(x){
+ n = null;
+ }
+ }
+ dojo.dnd.autoScroll(e);
+};
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Mover"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Mover"] = true;
+dojo.provide("dojo.dnd.Mover");
+
+
+
+
+
+dojo.declare("dojo.dnd.Mover", null, {
+ constructor: function(node, e, host){
+ // summary:
+ // an object which makes a node follow the mouse, or touch-drag on touch devices.
+ // Used as a default mover, and as a base class for custom movers.
+ // node: Node
+ // a node (or node's id) to be moved
+ // e: Event
+ // a mouse event, which started the move;
+ // only pageX and pageY properties are used
+ // host: Object?
+ // object which implements the functionality of the move,
+ // and defines proper events (onMoveStart and onMoveStop)
+ this.node = dojo.byId(node);
+ var pos = e.touches ? e.touches[0] : e;
+ this.marginBox = {l: pos.pageX, t: pos.pageY};
+ this.mouseButton = e.button;
+ var h = (this.host = host), d = node.ownerDocument;
+ this.events = [
+ // At the start of a drag, onFirstMove is called, and then the following two
+ // connects are disconnected
+ dojo.connect(d, "onmousemove", this, "onFirstMove"),
+ dojo.connect(d, "ontouchmove", this, "onFirstMove"),
+
+ // These are called continually during the drag
+ dojo.connect(d, "onmousemove", this, "onMouseMove"),
+ dojo.connect(d, "ontouchmove", this, "onMouseMove"),
+
+ // And these are called at the end of the drag
+ dojo.connect(d, "onmouseup", this, "onMouseUp"),
+ dojo.connect(d, "ontouchend", this, "onMouseUp"),
+
+ // cancel text selection and text dragging
+ dojo.connect(d, "ondragstart", dojo.stopEvent),
+ dojo.connect(d.body, "onselectstart", dojo.stopEvent)
+ ];
+ // notify that the move has started
+ if(h && h.onMoveStart){
+ h.onMoveStart(this);
+ }
+ },
+ // mouse event processors
+ onMouseMove: function(e){
+ // summary:
+ // event processor for onmousemove/ontouchmove
+ // e: Event
+ // mouse/touch event
+ dojo.dnd.autoScroll(e);
+ var m = this.marginBox,
+ pos = e.touches ? e.touches[0] : e;
+ this.host.onMove(this, {l: m.l + pos.pageX, t: m.t + pos.pageY}, e);
+ dojo.stopEvent(e);
+ },
+ onMouseUp: function(e){
+ if(dojo.isWebKit && dojo.isMac && this.mouseButton == 2 ?
+ e.button == 0 : this.mouseButton == e.button){ // TODO Should condition be met for touch devices, too?
+ this.destroy();
+ }
+ dojo.stopEvent(e);
+ },
+ // utilities
+ onFirstMove: function(e){
+ // summary:
+ // makes the node absolute; it is meant to be called only once.
+ // relative and absolutely positioned nodes are assumed to use pixel units
+ var s = this.node.style, l, t, h = this.host;
+ switch(s.position){
+ case "relative":
+ case "absolute":
+ // assume that left and top values are in pixels already
+ l = Math.round(parseFloat(s.left)) || 0;
+ t = Math.round(parseFloat(s.top)) || 0;
+ break;
+ default:
+ s.position = "absolute"; // enforcing the absolute mode
+ var m = dojo.marginBox(this.node);
+ // event.pageX/pageY (which we used to generate the initial
+ // margin box) includes padding and margin set on the body.
+ // However, setting the node's position to absolute and then
+ // doing dojo.marginBox on it *doesn't* take that additional
+ // space into account - so we need to subtract the combined
+ // padding and margin. We use getComputedStyle and
+ // _getMarginBox/_getContentBox to avoid the extra lookup of
+ // the computed style.
+ var b = dojo.doc.body;
+ var bs = dojo.getComputedStyle(b);
+ var bm = dojo._getMarginBox(b, bs);
+ var bc = dojo._getContentBox(b, bs);
+ l = m.l - (bc.l - bm.l);
+ t = m.t - (bc.t - bm.t);
+ break;
+ }
+ this.marginBox.l = l - this.marginBox.l;
+ this.marginBox.t = t - this.marginBox.t;
+ if(h && h.onFirstMove){
+ h.onFirstMove(this, e);
+ }
+
+ // Disconnect onmousemove and ontouchmove events that call this function
+ dojo.disconnect(this.events.shift());
+ dojo.disconnect(this.events.shift());
+ },
+ destroy: function(){
+ // summary:
+ // stops the move, deletes all references, so the object can be garbage-collected
+ dojo.forEach(this.events, dojo.disconnect);
+ // undo global settings
+ var h = this.host;
+ if(h && h.onMoveStop){
+ h.onMoveStop(this);
+ }
+ // destroy objects
+ this.events = this.node = this.host = null;
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Moveable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Moveable"] = true;
+dojo.provide("dojo.dnd.Moveable");
+
+
+
+
+/*=====
+dojo.declare("dojo.dnd.__MoveableArgs", [], {
+ // handle: Node||String
+ // A node (or node's id), which is used as a mouse handle.
+ // If omitted, the node itself is used as a handle.
+ handle: null,
+
+ // delay: Number
+ // delay move by this number of pixels
+ delay: 0,
+
+ // skip: Boolean
+ // skip move of form elements
+ skip: false,
+
+ // mover: Object
+ // a constructor of custom Mover
+ mover: dojo.dnd.Mover
+});
+=====*/
+
+dojo.declare("dojo.dnd.Moveable", null, {
+ // object attributes (for markup)
+ handle: "",
+ delay: 0,
+ skip: false,
+
+ constructor: function(node, params){
+ // summary:
+ // an object, which makes a node moveable
+ // node: Node
+ // a node (or node's id) to be moved
+ // params: dojo.dnd.__MoveableArgs?
+ // optional parameters
+ this.node = dojo.byId(node);
+ if(!params){ params = {}; }
+ this.handle = params.handle ? dojo.byId(params.handle) : null;
+ if(!this.handle){ this.handle = this.node; }
+ this.delay = params.delay > 0 ? params.delay : 0;
+ this.skip = params.skip;
+ this.mover = params.mover ? params.mover : dojo.dnd.Mover;
+ this.events = [
+ dojo.connect(this.handle, "onmousedown", this, "onMouseDown"),
+ dojo.connect(this.handle, "ontouchstart", this, "onMouseDown"),
+ // cancel text selection and text dragging
+ dojo.connect(this.handle, "ondragstart", this, "onSelectStart"),
+ dojo.connect(this.handle, "onselectstart", this, "onSelectStart")
+ ];
+ },
+
+ // markup methods
+ markupFactory: function(params, node){
+ return new dojo.dnd.Moveable(node, params);
+ },
+
+ // methods
+ destroy: function(){
+ // summary:
+ // stops watching for possible move, deletes all references, so the object can be garbage-collected
+ dojo.forEach(this.events, dojo.disconnect);
+ this.events = this.node = this.handle = null;
+ },
+
+ // mouse event processors
+ onMouseDown: function(e){
+ // summary:
+ // event processor for onmousedown/ontouchstart, creates a Mover for the node
+ // e: Event
+ // mouse/touch event
+ if(this.skip && dojo.dnd.isFormElement(e)){ return; }
+ if(this.delay){
+ this.events.push(
+ dojo.connect(this.handle, "onmousemove", this, "onMouseMove"),
+ dojo.connect(this.handle, "ontouchmove", this, "onMouseMove"),
+ dojo.connect(this.handle, "onmouseup", this, "onMouseUp"),
+ dojo.connect(this.handle, "ontouchend", this, "onMouseUp")
+ );
+ var pos = e.touches ? e.touches[0] : e;
+ this._lastX = pos.pageX;
+ this._lastY = pos.pageY;
+ }else{
+ this.onDragDetected(e);
+ }
+ dojo.stopEvent(e);
+ },
+ onMouseMove: function(e){
+ // summary:
+ // event processor for onmousemove/ontouchmove, used only for delayed drags
+ // e: Event
+ // mouse/touch event
+ var pos = e.touches ? e.touches[0] : e;
+ if(Math.abs(pos.pageX - this._lastX) > this.delay || Math.abs(pos.pageY - this._lastY) > this.delay){
+ this.onMouseUp(e);
+ this.onDragDetected(e);
+ }
+ dojo.stopEvent(e);
+ },
+ onMouseUp: function(e){
+ // summary:
+ // event processor for onmouseup, used only for delayed drags
+ // e: Event
+ // mouse event
+ for(var i = 0; i < 2; ++i){
+ dojo.disconnect(this.events.pop());
+ }
+ dojo.stopEvent(e);
+ },
+ onSelectStart: function(e){
+ // summary:
+ // event processor for onselectevent and ondragevent
+ // e: Event
+ // mouse event
+ if(!this.skip || !dojo.dnd.isFormElement(e)){
+ dojo.stopEvent(e);
+ }
+ },
+
+ // local events
+ onDragDetected: function(/* Event */ e){
+ // summary:
+ // called when the drag is detected;
+ // responsible for creation of the mover
+ new this.mover(this.node, e, this);
+ },
+ onMoveStart: function(/* dojo.dnd.Mover */ mover){
+ // summary:
+ // called before every move operation
+ dojo.publish("/dnd/move/start", [mover]);
+ dojo.addClass(dojo.body(), "dojoMove");
+ dojo.addClass(this.node, "dojoMoveItem");
+ },
+ onMoveStop: function(/* dojo.dnd.Mover */ mover){
+ // summary:
+ // called after every move operation
+ dojo.publish("/dnd/move/stop", [mover]);
+ dojo.removeClass(dojo.body(), "dojoMove");
+ dojo.removeClass(this.node, "dojoMoveItem");
+ },
+ onFirstMove: function(/* dojo.dnd.Mover */ mover, /* Event */ e){
+ // summary:
+ // called during the very first move notification;
+ // can be used to initialize coordinates, can be overwritten.
+
+ // default implementation does nothing
+ },
+ onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop, /* Event */ e){
+ // summary:
+ // called during every move notification;
+ // should actually move the node; can be overwritten.
+ this.onMoving(mover, leftTop);
+ var s = mover.node.style;
+ s.left = leftTop.l + "px";
+ s.top = leftTop.t + "px";
+ this.onMoved(mover, leftTop);
+ },
+ onMoving: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+ // summary:
+ // called before every incremental move; can be overwritten.
+
+ // default implementation does nothing
+ },
+ onMoved: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+ // summary:
+ // called after every incremental move; can be overwritten.
+
+ // default implementation does nothing
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._Builder"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Builder"] = true;
+dojo.provide("dojox.grid._Builder");
+
+
+
+
+(function(){
+ var dg = dojox.grid;
+
+ var getTdIndex = function(td){
+ return td.cellIndex >=0 ? td.cellIndex : dojo.indexOf(td.parentNode.cells, td);
+ };
+
+ var getTrIndex = function(tr){
+ return tr.rowIndex >=0 ? tr.rowIndex : dojo.indexOf(tr.parentNode.childNodes, tr);
+ };
+
+ var getTr = function(rowOwner, index){
+ return rowOwner && ((rowOwner.rows||0)[index] || rowOwner.childNodes[index]);
+ };
+
+ var findTable = function(node){
+ for(var n=node; n && n.tagName!='TABLE'; n=n.parentNode){}
+ return n;
+ };
+
+ var ascendDom = function(inNode, inWhile){
+ for(var n=inNode; n && inWhile(n); n=n.parentNode){}
+ return n;
+ };
+
+ var makeNotTagName = function(inTagName){
+ var name = inTagName.toUpperCase();
+ return function(node){ return node.tagName != name; };
+ };
+
+ var rowIndexTag = dojox.grid.util.rowIndexTag;
+ var gridViewTag = dojox.grid.util.gridViewTag;
+
+ // base class for generating markup for the views
+ dg._Builder = dojo.extend(function(view){
+ if(view){
+ this.view = view;
+ this.grid = view.grid;
+ }
+ },{
+ view: null,
+ // boilerplate HTML
+ _table: '<table class="dojoxGridRowTable" border="0" cellspacing="0" cellpadding="0" role="presentation"',
+
+ // Returns the table variable as an array - and with the view width, if specified
+ getTableArray: function(){
+ var html = [this._table];
+ if(this.view.viewWidth){
+ html.push([' style="width:', this.view.viewWidth, ';"'].join(''));
+ }
+ html.push('>');
+ return html;
+ },
+
+ // generate starting tags for a cell
+ generateCellMarkup: function(inCell, inMoreStyles, inMoreClasses, isHeader){
+ var result = [], html;
+ if(isHeader){
+ var sortInfo = inCell.index != inCell.grid.getSortIndex() ? "" : inCell.grid.sortInfo > 0 ? 'aria-sort="ascending"' : 'aria-sort="descending"';
+ if (!inCell.id){
+ inCell.id = this.grid.id + "Hdr" + inCell.index;
+ }
+ // column headers are not editable, mark as aria-readonly=true
+ html = ['<th tabIndex="-1" aria-readonly="true" role="columnheader"', sortInfo, 'id="', inCell.id, '"'];
+ }else{
+ // cells inherit grid aria-readonly property; default value for aria-readonly is false(grid is editable)
+ // if grid is editable (had any editable cells), mark non editable cells as aria-readonly=true
+ // if no editable cells, grid's aria-readonly value will have been set to true and cells will inherit
+ var editInfo = this.grid.editable && !inCell.editable ? 'aria-readonly="true"' : "";
+ html = ['<td tabIndex="-1" role="gridcell"', editInfo];
+ }
+ if(inCell.colSpan){
+ html.push(' colspan="', inCell.colSpan, '"');
+ }
+ if(inCell.rowSpan){
+ html.push(' rowspan="', inCell.rowSpan, '"');
+ }
+ html.push(' class="dojoxGridCell ');
+ if(inCell.classes){
+ html.push(inCell.classes, ' ');
+ }
+ if(inMoreClasses){
+ html.push(inMoreClasses, ' ');
+ }
+ // result[0] => td opener, style
+ result.push(html.join(''));
+ // SLOT: result[1] => td classes
+ result.push('');
+ html = ['" idx="', inCell.index, '" style="'];
+ if(inMoreStyles && inMoreStyles[inMoreStyles.length-1] != ';'){
+ inMoreStyles += ';';
+ }
+ html.push(inCell.styles, inMoreStyles||'', inCell.hidden?'display:none;':'');
+ if(inCell.unitWidth){
+ html.push('width:', inCell.unitWidth, ';');
+ }
+ // result[2] => markup
+ result.push(html.join(''));
+ // SLOT: result[3] => td style
+ result.push('');
+ html = [ '"' ];
+ if(inCell.attrs){
+ html.push(" ", inCell.attrs);
+ }
+ html.push('>');
+ // result[4] => td postfix
+ result.push(html.join(''));
+ // SLOT: result[5] => content
+ result.push('');
+ // result[6] => td closes
+ result.push(isHeader?'</th>':'</td>');
+ return result; // Array
+ },
+
+ // cell finding
+ isCellNode: function(inNode){
+ return Boolean(inNode && inNode!=dojo.doc && dojo.attr(inNode, "idx"));
+ },
+
+ getCellNodeIndex: function(inCellNode){
+ return inCellNode ? Number(dojo.attr(inCellNode, "idx")) : -1;
+ },
+
+ getCellNode: function(inRowNode, inCellIndex){
+ for(var i=0, row; (row=getTr(inRowNode.firstChild, i)); i++){
+ for(var j=0, cell; (cell=row.cells[j]); j++){
+ if(this.getCellNodeIndex(cell) == inCellIndex){
+ return cell;
+ }
+ }
+ }
+ return null;
+ },
+
+ findCellTarget: function(inSourceNode, inTopNode){
+ var n = inSourceNode;
+ while(n && (!this.isCellNode(n) || (n.offsetParent && gridViewTag in n.offsetParent.parentNode && n.offsetParent.parentNode[gridViewTag] != this.view.id)) && (n!=inTopNode)){
+ n = n.parentNode;
+ }
+ return n!=inTopNode ? n : null;
+ },
+
+ // event decoration
+ baseDecorateEvent: function(e){
+ e.dispatch = 'do' + e.type;
+ e.grid = this.grid;
+ e.sourceView = this.view;
+ e.cellNode = this.findCellTarget(e.target, e.rowNode);
+ e.cellIndex = this.getCellNodeIndex(e.cellNode);
+ e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null);
+ },
+
+ // event dispatch
+ findTarget: function(inSource, inTag){
+ var n = inSource;
+ while(n && (n!=this.domNode) && (!(inTag in n) || (gridViewTag in n && n[gridViewTag] != this.view.id))){
+ n = n.parentNode;
+ }
+ return (n != this.domNode) ? n : null;
+ },
+
+ findRowTarget: function(inSource){
+ return this.findTarget(inSource, rowIndexTag);
+ },
+
+ isIntraNodeEvent: function(e){
+ try{
+ return (e.cellNode && e.relatedTarget && dojo.isDescendant(e.relatedTarget, e.cellNode));
+ }catch(x){
+ // e.relatedTarget has permission problem in FF if it's an input: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+ return false;
+ }
+ },
+
+ isIntraRowEvent: function(e){
+ try{
+ var row = e.relatedTarget && this.findRowTarget(e.relatedTarget);
+ return !row && (e.rowIndex==-1) || row && (e.rowIndex==row.gridRowIndex);
+ }catch(x){
+ // e.relatedTarget on INPUT has permission problem in FF: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+ return false;
+ }
+ },
+
+ dispatchEvent: function(e){
+ if(e.dispatch in this){
+ return this[e.dispatch](e);
+ }
+ return false;
+ },
+
+ // dispatched event handlers
+ domouseover: function(e){
+ if(e.cellNode && (e.cellNode!=this.lastOverCellNode)){
+ this.lastOverCellNode = e.cellNode;
+ this.grid.onMouseOver(e);
+ }
+ this.grid.onMouseOverRow(e);
+ },
+
+ domouseout: function(e){
+ if(e.cellNode && (e.cellNode==this.lastOverCellNode) && !this.isIntraNodeEvent(e, this.lastOverCellNode)){
+ this.lastOverCellNode = null;
+ this.grid.onMouseOut(e);
+ if(!this.isIntraRowEvent(e)){
+ this.grid.onMouseOutRow(e);
+ }
+ }
+ },
+
+ domousedown: function(e){
+ if (e.cellNode)
+ this.grid.onMouseDown(e);
+ this.grid.onMouseDownRow(e);
+ }
+ });
+
+ // Produces html for grid data content. Owned by grid and used internally
+ // for rendering data. Override to implement custom rendering.
+ dg._ContentBuilder = dojo.extend(function(view){
+ dg._Builder.call(this, view);
+ },dg._Builder.prototype,{
+ update: function(){
+ this.prepareHtml();
+ },
+
+ // cache html for rendering data rows
+ prepareHtml: function(){
+ var defaultGet=this.grid.get, cells=this.view.structure.cells;
+ for(var j=0, row; (row=cells[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ cell.get = cell.get || (cell.value == undefined) && defaultGet;
+ cell.markup = this.generateCellMarkup(cell, cell.cellStyles, cell.cellClasses, false);
+ if (!this.grid.editable && cell.editable){
+ this.grid.editable = true;
+ }
+ }
+ }
+ },
+
+ // time critical: generate html using cache and data source
+ generateHtml: function(inDataIndex, inRowIndex){
+ var
+ html = this.getTableArray(),
+ v = this.view,
+ cells = v.structure.cells,
+ item = this.grid.getItem(inRowIndex);
+
+ dojox.grid.util.fire(this.view, "onBeforeRow", [inRowIndex, cells]);
+ for(var j=0, row; (row=cells[j]); j++){
+ if(row.hidden || row.header){
+ continue;
+ }
+ html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
+ for(var i=0, cell, m, cc, cs; (cell=row[i]); i++){
+ m = cell.markup; cc = cell.customClasses = []; cs = cell.customStyles = [];
+ // content (format can fill in cc and cs as side-effects)
+ m[5] = cell.format(inRowIndex, item);
+ // classes
+ m[1] = cc.join(' ');
+ // styles
+ m[3] = cs.join(';');
+ // in-place concat
+ html.push.apply(html, m);
+ }
+ html.push('</tr>');
+ }
+ html.push('</table>');
+ return html.join(''); // String
+ },
+
+ decorateEvent: function(e){
+ e.rowNode = this.findRowTarget(e.target);
+ if(!e.rowNode){return false;}
+ e.rowIndex = e.rowNode[rowIndexTag];
+ this.baseDecorateEvent(e);
+ e.cell = this.grid.getCell(e.cellIndex);
+ return true; // Boolean
+ }
+ });
+
+ // Produces html for grid header content. Owned by grid and used internally
+ // for rendering data. Override to implement custom rendering.
+ dg._HeaderBuilder = dojo.extend(function(view){
+ this.moveable = null;
+ dg._Builder.call(this, view);
+ },dg._Builder.prototype,{
+ _skipBogusClicks: false,
+ overResizeWidth: 4,
+ minColWidth: 1,
+
+ update: function(){
+ if(this.tableMap){
+ this.tableMap.mapRows(this.view.structure.cells);
+ }else{
+ this.tableMap = new dg._TableMap(this.view.structure.cells);
+ }
+ },
+
+ generateHtml: function(inGetValue, inValue){
+ var html = this.getTableArray(), cells = this.view.structure.cells;
+
+ dojox.grid.util.fire(this.view, "onBeforeRow", [-1, cells]);
+ for(var j=0, row; (row=cells[j]); j++){
+ if(row.hidden){
+ continue;
+ }
+ html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
+ for(var i=0, cell, markup; (cell=row[i]); i++){
+ cell.customClasses = [];
+ cell.customStyles = [];
+ if(this.view.simpleStructure){
+ if(cell.draggable){
+ if(cell.headerClasses){
+ if(cell.headerClasses.indexOf('dojoDndItem') == -1){
+ cell.headerClasses += ' dojoDndItem';
+ }
+ }else{
+ cell.headerClasses = 'dojoDndItem';
+ }
+ }
+ if(cell.attrs){
+ if(cell.attrs.indexOf("dndType='gridColumn_") == -1){
+ cell.attrs += " dndType='gridColumn_" + this.grid.id + "'";
+ }
+ }else{
+ cell.attrs = "dndType='gridColumn_" + this.grid.id + "'";
+ }
+ }
+ markup = this.generateCellMarkup(cell, cell.headerStyles, cell.headerClasses, true);
+ // content
+ markup[5] = (inValue != undefined ? inValue : inGetValue(cell));
+ // styles
+ markup[3] = cell.customStyles.join(';');
+ // classes
+ markup[1] = cell.customClasses.join(' '); //(cell.customClasses ? ' ' + cell.customClasses : '');
+ html.push(markup.join(''));
+ }
+ html.push('</tr>');
+ }
+ html.push('</table>');
+ return html.join('');
+ },
+
+ // event helpers
+ getCellX: function(e){
+ var n, x = e.layerX;
+ if(dojo.isMoz){
+ n = ascendDom(e.target, makeNotTagName("th"));
+ x -= (n && n.offsetLeft) || 0;
+ var t = e.sourceView.getScrollbarWidth();
+ if(!dojo._isBodyLtr()/*&& e.sourceView.headerNode.scrollLeft < t*/){
+ //fix #11253
+ table = ascendDom(n,makeNotTagName("table"));
+ x -= (table && table.offsetLeft) || 0;
+ }
+ //x -= getProp(ascendDom(e.target, mkNotTagName("td")), "offsetLeft") || 0;
+ }
+ n = ascendDom(e.target, function(){
+ if(!n || n == e.cellNode){
+ return false;
+ }
+ // Mozilla 1.8 (FF 1.5) has a bug that makes offsetLeft = -parent border width
+ // when parent has border, overflow: hidden, and is positioned
+ // handle this problem here ... not a general solution!
+ x += (n.offsetLeft < 0 ? 0 : n.offsetLeft);
+ return true;
+ });
+ return x;
+ },
+
+ // event decoration
+ decorateEvent: function(e){
+ this.baseDecorateEvent(e);
+ e.rowIndex = -1;
+ e.cellX = this.getCellX(e);
+ return true;
+ },
+
+ // event handlers
+ // resizing
+ prepareResize: function(e, mod){
+ do{
+ var i = getTdIndex(e.cellNode);
+ e.cellNode = (i ? e.cellNode.parentNode.cells[i+mod] : null);
+ e.cellIndex = (e.cellNode ? this.getCellNodeIndex(e.cellNode) : -1);
+ }while(e.cellNode && e.cellNode.style.display == "none");
+ return Boolean(e.cellNode);
+ },
+
+ canResize: function(e){
+ if(!e.cellNode || e.cellNode.colSpan > 1){
+ return false;
+ }
+ var cell = this.grid.getCell(e.cellIndex);
+ return !cell.noresize && cell.canResize();
+ },
+
+ overLeftResizeArea: function(e){
+ // We are never over a resize area if we are in the process of moving
+ if(dojo.hasClass(dojo.body(), "dojoDndMove")){
+ return false;
+ }
+ //Bugfix for crazy IE problem (#8807). IE returns position information for the icon and text arrow divs
+ //as if they were still on the left instead of returning the position they were 'float: right' to.
+ //So, the resize check ends up checking the wrong adjacent cell. This checks to see if the hover was over
+ //the image or text nodes, then just ignored them/treat them not in scale range.
+ if(dojo.isIE){
+ var tN = e.target;
+ if(dojo.hasClass(tN, "dojoxGridArrowButtonNode") ||
+ dojo.hasClass(tN, "dojoxGridArrowButtonChar")){
+ return false;
+ }
+ }
+
+ if(dojo._isBodyLtr()){
+ return (e.cellIndex>0) && (e.cellX > 0 && e.cellX < this.overResizeWidth) && this.prepareResize(e, -1);
+ }
+ var t = e.cellNode && (e.cellX > 0 && e.cellX < this.overResizeWidth);
+ return t;
+ },
+
+ overRightResizeArea: function(e){
+ // We are never over a resize area if we are in the process of moving
+ if(dojo.hasClass(dojo.body(), "dojoDndMove")){
+ return false;
+ }
+ //Bugfix for crazy IE problem (#8807). IE returns position information for the icon and text arrow divs
+ //as if they were still on the left instead of returning the position they were 'float: right' to.
+ //So, the resize check ends up checking the wrong adjacent cell. This checks to see if the hover was over
+ //the image or text nodes, then just ignored them/treat them not in scale range.
+ if(dojo.isIE){
+ var tN = e.target;
+ if(dojo.hasClass(tN, "dojoxGridArrowButtonNode") ||
+ dojo.hasClass(tN, "dojoxGridArrowButtonChar")){
+ return false;
+ }
+ }
+
+ if(dojo._isBodyLtr()){
+ return e.cellNode && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth);
+ }
+ return (e.cellIndex>0) && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth) && this.prepareResize(e, -1);
+ },
+
+ domousemove: function(e){
+ //console.log(e.cellIndex, e.cellX, e.cellNode.offsetWidth);
+ if(!this.moveable){
+ var c = (this.overRightResizeArea(e) ? 'dojoxGridColResize' : (this.overLeftResizeArea(e) ? 'dojoxGridColResize' : ''));
+ if(c && !this.canResize(e)){
+ c = 'dojoxGridColNoResize';
+ }
+ dojo.toggleClass(e.sourceView.headerNode, "dojoxGridColNoResize", (c == "dojoxGridColNoResize"));
+ dojo.toggleClass(e.sourceView.headerNode, "dojoxGridColResize", (c == "dojoxGridColResize"));
+ if(dojo.isIE){
+ var t = e.sourceView.headerNode.scrollLeft;
+ e.sourceView.headerNode.scrollLeft = t;
+ }
+ if(c){
+ dojo.stopEvent(e);
+ }
+ }
+ },
+
+ domousedown: function(e){
+ if(!this.moveable){
+ if((this.overRightResizeArea(e) || this.overLeftResizeArea(e)) && this.canResize(e)){
+ this.beginColumnResize(e);
+ }else{
+ this.grid.onMouseDown(e);
+ this.grid.onMouseOverRow(e);
+ }
+ //else{
+ // this.beginMoveColumn(e);
+ //}
+ }
+ },
+
+ doclick: function(e) {
+ if(this._skipBogusClicks){
+ dojo.stopEvent(e);
+ return true;
+ }
+ return false;
+ },
+
+ // column resizing
+ colResizeSetup: function(/*Event Object*/e, /*boolean*/ isMouse ){
+ //Set up the drag object for column resizing
+ // Called with mouse event in case of drag and drop,
+ // Also called from keyboard shift-arrow event when focus is on a header
+ var headContentBox = dojo.contentBox(e.sourceView.headerNode);
+
+ if(isMouse){ //IE draws line even with no mouse down so separate from keyboard
+ this.lineDiv = document.createElement('div');
+
+ // NOTE: this is for backwards compatibility with Dojo 1.3
+ var vw = (dojo.position||dojo._abs)(e.sourceView.headerNode, true);
+ var bodyContentBox = dojo.contentBox(e.sourceView.domNode);
+ //fix #11340
+ var l = e.pageX;
+ if(!dojo._isBodyLtr() && dojo.isIE < 8){
+ l -= dojox.html.metrics.getScrollbar().w;
+ }
+ dojo.style(this.lineDiv, {
+ top: vw.y + "px",
+ left: l + "px",
+ height: (bodyContentBox.h + headContentBox.h) + "px"
+ });
+ dojo.addClass(this.lineDiv, "dojoxGridResizeColLine");
+ this.lineDiv._origLeft = l;
+ dojo.body().appendChild(this.lineDiv);
+ }
+ var spanners = [], nodes = this.tableMap.findOverlappingNodes(e.cellNode);
+ for(var i=0, cell; (cell=nodes[i]); i++){
+ spanners.push({ node: cell, index: this.getCellNodeIndex(cell), width: cell.offsetWidth });
+ //console.log("spanner: " + this.getCellNodeIndex(cell));
+ }
+
+ var view = e.sourceView;
+ var adj = dojo._isBodyLtr() ? 1 : -1;
+ var views = e.grid.views.views;
+ var followers = [];
+ for(var j=view.idx+adj, cView; (cView=views[j]); j=j+adj){
+ followers.push({ node: cView.headerNode, left: window.parseInt(cView.headerNode.style.left) });
+ }
+ var table = view.headerContentNode.firstChild;
+ var drag = {
+ scrollLeft: e.sourceView.headerNode.scrollLeft,
+ view: view,
+ node: e.cellNode,
+ index: e.cellIndex,
+ w: dojo.contentBox(e.cellNode).w,
+ vw: headContentBox.w,
+ table: table,
+ tw: dojo.contentBox(table).w,
+ spanners: spanners,
+ followers: followers
+ };
+ return drag;
+ },
+ beginColumnResize: function(e){
+ this.moverDiv = document.createElement("div");
+ dojo.style(this.moverDiv,{position: "absolute", left:0}); // to make DnD work with dir=rtl
+ dojo.body().appendChild(this.moverDiv);
+ dojo.addClass(this.grid.domNode, "dojoxGridColumnResizing");
+ var m = (this.moveable = new dojo.dnd.Moveable(this.moverDiv));
+
+ var drag = this.colResizeSetup(e,true);
+
+ m.onMove = dojo.hitch(this, "doResizeColumn", drag);
+
+ dojo.connect(m, "onMoveStop", dojo.hitch(this, function(){
+ this.endResizeColumn(drag);
+ if(drag.node.releaseCapture){
+ drag.node.releaseCapture();
+ }
+ this.moveable.destroy();
+ delete this.moveable;
+ this.moveable = null;
+ dojo.removeClass(this.grid.domNode, "dojoxGridColumnResizing");
+ }));
+
+ if(e.cellNode.setCapture){
+ e.cellNode.setCapture();
+ }
+ m.onMouseDown(e);
+ },
+
+ doResizeColumn: function(inDrag, mover, leftTop){
+ var changeX = leftTop.l;
+ var data = {
+ deltaX: changeX,
+ w: inDrag.w + (dojo._isBodyLtr() ? changeX : -changeX),//fix #11341
+ vw: inDrag.vw + changeX,
+ tw: inDrag.tw + changeX
+ };
+
+ this.dragRecord = {inDrag: inDrag, mover: mover, leftTop:leftTop};
+
+ if(data.w >= this.minColWidth){
+ if (!mover) { // we are using keyboard do immediate resize
+ this.doResizeNow(inDrag, data);
+ }
+ else{
+ dojo.style(this.lineDiv, "left", (this.lineDiv._origLeft + data.deltaX) + "px");
+ }
+ }
+ },
+
+ endResizeColumn: function(inDrag){
+ if(this.dragRecord){
+ var leftTop = this.dragRecord.leftTop;
+ var changeX = dojo._isBodyLtr() ? leftTop.l : -leftTop.l;
+ // Make sure we are not under our minimum
+ // http://bugs.dojotoolkit.org/ticket/9390
+ changeX += Math.max(inDrag.w + changeX, this.minColWidth) - (inDrag.w + changeX);
+ if(dojo.isWebKit && inDrag.spanners.length){
+ // Webkit needs the pad border extents back in
+ changeX += dojo._getPadBorderExtents(inDrag.spanners[0].node).w;
+ }
+ var data = {
+ deltaX: changeX,
+ w: inDrag.w + changeX,
+ vw: inDrag.vw + changeX,
+ tw: inDrag.tw + changeX
+ };
+ // Only resize the columns when the drag has finished
+ this.doResizeNow(inDrag, data);
+ delete this.dragRecord;
+ }
+
+ dojo.destroy(this.lineDiv);
+ dojo.destroy(this.moverDiv);
+ dojo.destroy(this.moverDiv);
+ delete this.moverDiv;
+ this._skipBogusClicks = true;
+ inDrag.view.update();
+ this._skipBogusClicks = false;
+ this.grid.onResizeColumn(inDrag.index);
+ },
+ doResizeNow: function(inDrag, data){
+ inDrag.view.convertColPctToFixed();
+ if(inDrag.view.flexCells && !inDrag.view.testFlexCells()){
+ var t = findTable(inDrag.node);
+ if(t){
+ (t.style.width = '');
+ }
+ }
+ var i, s, sw, f, fl;
+ for(i=0; (s=inDrag.spanners[i]); i++){
+ sw = s.width + data.deltaX;
+ s.node.style.width = sw + 'px';
+ inDrag.view.setColWidth(s.index, sw);
+ }
+ if(dojo._isBodyLtr() || !dojo.isIE){//fix #11339
+ for(i=0; (f=inDrag.followers[i]); i++){
+ fl = f.left + data.deltaX;
+ f.node.style.left = fl + 'px';
+ }
+ }
+ inDrag.node.style.width = data.w + 'px';
+ inDrag.view.setColWidth(inDrag.index, data.w);
+ inDrag.view.headerNode.style.width = data.vw + 'px';
+ inDrag.view.setColumnsWidth(data.tw);
+ if(!dojo._isBodyLtr()){
+ inDrag.view.headerNode.scrollLeft = inDrag.scrollLeft + data.deltaX;
+ }
+ }
+ });
+
+ // Maps an html table into a structure parsable for information about cell row and col spanning.
+ // Used by HeaderBuilder.
+ dg._TableMap = dojo.extend(function(rows){
+ this.mapRows(rows);
+ },{
+ map: null,
+
+ mapRows: function(inRows){
+ // summary: Map table topography
+
+ //console.log('mapRows');
+ // # of rows
+ var rowCount = inRows.length;
+ if(!rowCount){
+ return;
+ }
+ // map which columns and rows fill which cells
+ this.map = [];
+ var row;
+ for(var k=0; (row=inRows[k]); k++){
+ this.map[k] = [];
+ }
+ for(var j=0; (row=inRows[j]); j++){
+ for(var i=0, x=0, cell, colSpan, rowSpan; (cell=row[i]); i++){
+ while(this.map[j][x]){x++;}
+ this.map[j][x] = { c: i, r: j };
+ rowSpan = cell.rowSpan || 1;
+ colSpan = cell.colSpan || 1;
+ for(var y=0; y<rowSpan; y++){
+ for(var s=0; s<colSpan; s++){
+ this.map[j+y][x+s] = this.map[j][x];
+ }
+ }
+ x += colSpan;
+ }
+ }
+ //this.dumMap();
+ },
+
+ dumpMap: function(){
+ for(var j=0, row, h=''; (row=this.map[j]); j++,h=''){
+ for(var i=0, cell; (cell=row[i]); i++){
+ h += cell.r + ',' + cell.c + ' ';
+ }
+ }
+ },
+
+ getMapCoords: function(inRow, inCol){
+ // summary: Find node's map coords by it's structure coords
+ for(var j=0, row; (row=this.map[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ if(cell.c==inCol && cell.r == inRow){
+ return { j: j, i: i };
+ }
+ //else{console.log(inRow, inCol, ' : ', i, j, " : ", cell.r, cell.c); };
+ }
+ }
+ return { j: -1, i: -1 };
+ },
+
+ getNode: function(inTable, inRow, inCol){
+ // summary: Find a node in inNode's table with the given structure coords
+ var row = inTable && inTable.rows[inRow];
+ return row && row.cells[inCol];
+ },
+
+ _findOverlappingNodes: function(inTable, inRow, inCol){
+ var nodes = [];
+ var m = this.getMapCoords(inRow, inCol);
+ //console.log("node j: %d, i: %d", m.j, m.i);
+ for(var j=0, row; (row=this.map[j]); j++){
+ if(j == m.j){ continue; }
+ var rw = row[m.i];
+ //console.log("overlaps: r: %d, c: %d", rw.r, rw.c);
+ var n = (rw?this.getNode(inTable, rw.r, rw.c):null);
+ if(n){ nodes.push(n); }
+ }
+ //console.log(nodes);
+ return nodes;
+ },
+
+ findOverlappingNodes: function(inNode){
+ return this._findOverlappingNodes(findTable(inNode), getTrIndex(inNode.parentNode), getTdIndex(inNode));
+ }
+ });
+})();
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Container"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Container"] = true;
+dojo.provide("dojo.dnd.Container");
+
+
+
+
+
+/*
+ Container states:
+ "" - normal state
+ "Over" - mouse over a container
+ Container item states:
+ "" - normal state
+ "Over" - mouse over a container item
+*/
+
+/*=====
+dojo.declare("dojo.dnd.__ContainerArgs", [], {
+ creator: function(){
+ // summary:
+ // a creator function, which takes a data item, and returns an object like that:
+ // {node: newNode, data: usedData, type: arrayOfStrings}
+ },
+
+ // skipForm: Boolean
+ // don't start the drag operation, if clicked on form elements
+ skipForm: false,
+
+ // dropParent: Node||String
+ // node or node's id to use as the parent node for dropped items
+ // (must be underneath the 'node' parameter in the DOM)
+ dropParent: null,
+
+ // _skipStartup: Boolean
+ // skip startup(), which collects children, for deferred initialization
+ // (this is used in the markup mode)
+ _skipStartup: false
+});
+
+dojo.dnd.Item = function(){
+ // summary:
+ // Represents (one of) the source node(s) being dragged.
+ // Contains (at least) the "type" and "data" attributes.
+ // type: String[]
+ // Type(s) of this item, by default this is ["text"]
+ // data: Object
+ // Logical representation of the object being dragged.
+ // If the drag object's type is "text" then data is a String,
+ // if it's another type then data could be a different Object,
+ // perhaps a name/value hash.
+
+ this.type = type;
+ this.data = data;
+}
+=====*/
+
+dojo.declare("dojo.dnd.Container", null, {
+ // summary:
+ // a Container object, which knows when mouse hovers over it,
+ // and over which element it hovers
+
+ // object attributes (for markup)
+ skipForm: false,
+
+ /*=====
+ // current: DomNode
+ // The DOM node the mouse is currently hovered over
+ current: null,
+
+ // map: Hash<String, dojo.dnd.Item>
+ // Map from an item's id (which is also the DOMNode's id) to
+ // the dojo.dnd.Item itself.
+ map: {},
+ =====*/
+
+ constructor: function(node, params){
+ // summary:
+ // a constructor of the Container
+ // node: Node
+ // node or node's id to build the container on
+ // params: dojo.dnd.__ContainerArgs
+ // a dictionary of parameters
+ this.node = dojo.byId(node);
+ if(!params){ params = {}; }
+ this.creator = params.creator || null;
+ this.skipForm = params.skipForm;
+ this.parent = params.dropParent && dojo.byId(params.dropParent);
+
+ // class-specific variables
+ this.map = {};
+ this.current = null;
+
+ // states
+ this.containerState = "";
+ dojo.addClass(this.node, "dojoDndContainer");
+
+ // mark up children
+ if(!(params && params._skipStartup)){
+ this.startup();
+ }
+
+ // set up events
+ this.events = [
+ dojo.connect(this.node, "onmouseover", this, "onMouseOver"),
+ dojo.connect(this.node, "onmouseout", this, "onMouseOut"),
+ // cancel text selection and text dragging
+ dojo.connect(this.node, "ondragstart", this, "onSelectStart"),
+ dojo.connect(this.node, "onselectstart", this, "onSelectStart")
+ ];
+ },
+
+ // object attributes (for markup)
+ creator: function(){
+ // summary:
+ // creator function, dummy at the moment
+ },
+
+ // abstract access to the map
+ getItem: function(/*String*/ key){
+ // summary:
+ // returns a data item by its key (id)
+ return this.map[key]; // dojo.dnd.Item
+ },
+ setItem: function(/*String*/ key, /*dojo.dnd.Item*/ data){
+ // summary:
+ // associates a data item with its key (id)
+ this.map[key] = data;
+ },
+ delItem: function(/*String*/ key){
+ // summary:
+ // removes a data item from the map by its key (id)
+ delete this.map[key];
+ },
+ forInItems: function(/*Function*/ f, /*Object?*/ o){
+ // summary:
+ // iterates over a data map skipping members that
+ // are present in the empty object (IE and/or 3rd-party libraries).
+ o = o || dojo.global;
+ var m = this.map, e = dojo.dnd._empty;
+ for(var i in m){
+ if(i in e){ continue; }
+ f.call(o, m[i], i, this);
+ }
+ return o; // Object
+ },
+ clearItems: function(){
+ // summary:
+ // removes all data items from the map
+ this.map = {};
+ },
+
+ // methods
+ getAllNodes: function(){
+ // summary:
+ // returns a list (an array) of all valid child nodes
+ return dojo.query("> .dojoDndItem", this.parent); // NodeList
+ },
+ sync: function(){
+ // summary:
+ // sync up the node list with the data map
+ var map = {};
+ this.getAllNodes().forEach(function(node){
+ if(node.id){
+ var item = this.getItem(node.id);
+ if(item){
+ map[node.id] = item;
+ return;
+ }
+ }else{
+ node.id = dojo.dnd.getUniqueId();
+ }
+ var type = node.getAttribute("dndType"),
+ data = node.getAttribute("dndData");
+ map[node.id] = {
+ data: data || node.innerHTML,
+ type: type ? type.split(/\s*,\s*/) : ["text"]
+ };
+ }, this);
+ this.map = map;
+ return this; // self
+ },
+ insertNodes: function(data, before, anchor){
+ // summary:
+ // inserts an array of new nodes before/after an anchor node
+ // data: Array
+ // a list of data items, which should be processed by the creator function
+ // before: Boolean
+ // insert before the anchor, if true, and after the anchor otherwise
+ // anchor: Node
+ // the anchor node to be used as a point of insertion
+ if(!this.parent.firstChild){
+ anchor = null;
+ }else if(before){
+ if(!anchor){
+ anchor = this.parent.firstChild;
+ }
+ }else{
+ if(anchor){
+ anchor = anchor.nextSibling;
+ }
+ }
+ if(anchor){
+ for(var i = 0; i < data.length; ++i){
+ var t = this._normalizedCreator(data[i]);
+ this.setItem(t.node.id, {data: t.data, type: t.type});
+ this.parent.insertBefore(t.node, anchor);
+ }
+ }else{
+ for(var i = 0; i < data.length; ++i){
+ var t = this._normalizedCreator(data[i]);
+ this.setItem(t.node.id, {data: t.data, type: t.type});
+ this.parent.appendChild(t.node);
+ }
+ }
+ return this; // self
+ },
+ destroy: function(){
+ // summary:
+ // prepares this object to be garbage-collected
+ dojo.forEach(this.events, dojo.disconnect);
+ this.clearItems();
+ this.node = this.parent = this.current = null;
+ },
+
+ // markup methods
+ markupFactory: function(params, node){
+ params._skipStartup = true;
+ return new dojo.dnd.Container(node, params);
+ },
+ startup: function(){
+ // summary:
+ // collects valid child items and populate the map
+
+ // set up the real parent node
+ if(!this.parent){
+ // use the standard algorithm, if not assigned
+ this.parent = this.node;
+ if(this.parent.tagName.toLowerCase() == "table"){
+ var c = this.parent.getElementsByTagName("tbody");
+ if(c && c.length){ this.parent = c[0]; }
+ }
+ }
+ this.defaultCreator = dojo.dnd._defaultCreator(this.parent);
+
+ // process specially marked children
+ this.sync();
+ },
+
+ // mouse events
+ onMouseOver: function(e){
+ // summary:
+ // event processor for onmouseover
+ // e: Event
+ // mouse event
+ var n = e.relatedTarget;
+ while(n){
+ if(n == this.node){ break; }
+ try{
+ n = n.parentNode;
+ }catch(x){
+ n = null;
+ }
+ }
+ if(!n){
+ this._changeState("Container", "Over");
+ this.onOverEvent();
+ }
+ n = this._getChildByEvent(e);
+ if(this.current == n){ return; }
+ if(this.current){ this._removeItemClass(this.current, "Over"); }
+ if(n){ this._addItemClass(n, "Over"); }
+ this.current = n;
+ },
+ onMouseOut: function(e){
+ // summary:
+ // event processor for onmouseout
+ // e: Event
+ // mouse event
+ for(var n = e.relatedTarget; n;){
+ if(n == this.node){ return; }
+ try{
+ n = n.parentNode;
+ }catch(x){
+ n = null;
+ }
+ }
+ if(this.current){
+ this._removeItemClass(this.current, "Over");
+ this.current = null;
+ }
+ this._changeState("Container", "");
+ this.onOutEvent();
+ },
+ onSelectStart: function(e){
+ // summary:
+ // event processor for onselectevent and ondragevent
+ // e: Event
+ // mouse event
+ if(!this.skipForm || !dojo.dnd.isFormElement(e)){
+ dojo.stopEvent(e);
+ }
+ },
+
+ // utilities
+ onOverEvent: function(){
+ // summary:
+ // this function is called once, when mouse is over our container
+ },
+ onOutEvent: function(){
+ // summary:
+ // this function is called once, when mouse is out of our container
+ },
+ _changeState: function(type, newState){
+ // summary:
+ // changes a named state to new state value
+ // type: String
+ // a name of the state to change
+ // newState: String
+ // new state
+ var prefix = "dojoDnd" + type;
+ var state = type.toLowerCase() + "State";
+ //dojo.replaceClass(this.node, prefix + newState, prefix + this[state]);
+ dojo.replaceClass(this.node, prefix + newState, prefix + this[state]);
+ this[state] = newState;
+ },
+ _addItemClass: function(node, type){
+ // summary:
+ // adds a class with prefix "dojoDndItem"
+ // node: Node
+ // a node
+ // type: String
+ // a variable suffix for a class name
+ dojo.addClass(node, "dojoDndItem" + type);
+ },
+ _removeItemClass: function(node, type){
+ // summary:
+ // removes a class with prefix "dojoDndItem"
+ // node: Node
+ // a node
+ // type: String
+ // a variable suffix for a class name
+ dojo.removeClass(node, "dojoDndItem" + type);
+ },
+ _getChildByEvent: function(e){
+ // summary:
+ // gets a child, which is under the mouse at the moment, or null
+ // e: Event
+ // a mouse event
+ var node = e.target;
+ if(node){
+ for(var parent = node.parentNode; parent; node = parent, parent = node.parentNode){
+ if(parent == this.parent && dojo.hasClass(node, "dojoDndItem")){ return node; }
+ }
+ }
+ return null;
+ },
+ _normalizedCreator: function(/*dojo.dnd.Item*/ item, /*String*/ hint){
+ // summary:
+ // adds all necessary data to the output of the user-supplied creator function
+ var t = (this.creator || this.defaultCreator).call(this, item, hint);
+ if(!dojo.isArray(t.type)){ t.type = ["text"]; }
+ if(!t.node.id){ t.node.id = dojo.dnd.getUniqueId(); }
+ dojo.addClass(t.node, "dojoDndItem");
+ return t;
+ }
+});
+
+dojo.dnd._createNode = function(tag){
+ // summary:
+ // returns a function, which creates an element of given tag
+ // (SPAN by default) and sets its innerHTML to given text
+ // tag: String
+ // a tag name or empty for SPAN
+ if(!tag){ return dojo.dnd._createSpan; }
+ return function(text){ // Function
+ return dojo.create(tag, {innerHTML: text}); // Node
+ };
+};
+
+dojo.dnd._createTrTd = function(text){
+ // summary:
+ // creates a TR/TD structure with given text as an innerHTML of TD
+ // text: String
+ // a text for TD
+ var tr = dojo.create("tr");
+ dojo.create("td", {innerHTML: text}, tr);
+ return tr; // Node
+};
+
+dojo.dnd._createSpan = function(text){
+ // summary:
+ // creates a SPAN element with given text as its innerHTML
+ // text: String
+ // a text for SPAN
+ return dojo.create("span", {innerHTML: text}); // Node
+};
+
+// dojo.dnd._defaultCreatorNodes: Object
+// a dictionary that maps container tag names to child tag names
+dojo.dnd._defaultCreatorNodes = {ul: "li", ol: "li", div: "div", p: "div"};
+
+dojo.dnd._defaultCreator = function(node){
+ // summary:
+ // takes a parent node, and returns an appropriate creator function
+ // node: Node
+ // a container node
+ var tag = node.tagName.toLowerCase();
+ var c = tag == "tbody" || tag == "thead" ? dojo.dnd._createTrTd :
+ dojo.dnd._createNode(dojo.dnd._defaultCreatorNodes[tag]);
+ return function(item, hint){ // Function
+ var isObj = item && dojo.isObject(item), data, type, n;
+ if(isObj && item.tagName && item.nodeType && item.getAttribute){
+ // process a DOM node
+ data = item.getAttribute("dndData") || item.innerHTML;
+ type = item.getAttribute("dndType");
+ type = type ? type.split(/\s*,\s*/) : ["text"];
+ n = item; // this node is going to be moved rather than copied
+ }else{
+ // process a DnD item object or a string
+ data = (isObj && item.data) ? item.data : item;
+ type = (isObj && item.type) ? item.type : ["text"];
+ n = (hint == "avatar" ? dojo.dnd._createSpan : c)(String(data));
+ }
+ if(!n.id){
+ n.id = dojo.dnd.getUniqueId();
+ }
+ return {node: n, data: data, type: type};
+ };
+};
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Selector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Selector"] = true;
+dojo.provide("dojo.dnd.Selector");
+
+
+
+
+
+/*
+ Container item states:
+ "" - an item is not selected
+ "Selected" - an item is selected
+ "Anchor" - an item is selected, and is an anchor for a "shift" selection
+*/
+
+/*=====
+dojo.declare("dojo.dnd.__SelectorArgs", [dojo.dnd.__ContainerArgs], {
+ // singular: Boolean
+ // allows selection of only one element, if true
+ singular: false,
+
+ // autoSync: Boolean
+ // autosynchronizes the source with its list of DnD nodes,
+ autoSync: false
+});
+=====*/
+
+dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
+ // summary:
+ // a Selector object, which knows how to select its children
+
+ /*=====
+ // selection: Set<String>
+ // The set of id's that are currently selected, such that this.selection[id] == 1
+ // if the node w/that id is selected. Can iterate over selected node's id's like:
+ // | for(var id in this.selection)
+ selection: {},
+ =====*/
+
+ constructor: function(node, params){
+ // summary:
+ // constructor of the Selector
+ // node: Node||String
+ // node or node's id to build the selector on
+ // params: dojo.dnd.__SelectorArgs?
+ // a dictionary of parameters
+ if(!params){ params = {}; }
+ this.singular = params.singular;
+ this.autoSync = params.autoSync;
+ // class-specific variables
+ this.selection = {};
+ this.anchor = null;
+ this.simpleSelection = false;
+ // set up events
+ this.events.push(
+ dojo.connect(this.node, "onmousedown", this, "onMouseDown"),
+ dojo.connect(this.node, "onmouseup", this, "onMouseUp"));
+ },
+
+ // object attributes (for markup)
+ singular: false, // is singular property
+
+ // methods
+ getSelectedNodes: function(){
+ // summary:
+ // returns a list (an array) of selected nodes
+ var t = new dojo.NodeList();
+ var e = dojo.dnd._empty;
+ for(var i in this.selection){
+ if(i in e){ continue; }
+ t.push(dojo.byId(i));
+ }
+ return t; // NodeList
+ },
+ selectNone: function(){
+ // summary:
+ // unselects all items
+ return this._removeSelection()._removeAnchor(); // self
+ },
+ selectAll: function(){
+ // summary:
+ // selects all items
+ this.forInItems(function(data, id){
+ this._addItemClass(dojo.byId(id), "Selected");
+ this.selection[id] = 1;
+ }, this);
+ return this._removeAnchor(); // self
+ },
+ deleteSelectedNodes: function(){
+ // summary:
+ // deletes all selected items
+ var e = dojo.dnd._empty;
+ for(var i in this.selection){
+ if(i in e){ continue; }
+ var n = dojo.byId(i);
+ this.delItem(i);
+ dojo.destroy(n);
+ }
+ this.anchor = null;
+ this.selection = {};
+ return this; // self
+ },
+ forInSelectedItems: function(/*Function*/ f, /*Object?*/ o){
+ // summary:
+ // iterates over selected items;
+ // see `dojo.dnd.Container.forInItems()` for details
+ o = o || dojo.global;
+ var s = this.selection, e = dojo.dnd._empty;
+ for(var i in s){
+ if(i in e){ continue; }
+ f.call(o, this.getItem(i), i, this);
+ }
+ },
+ sync: function(){
+ // summary:
+ // sync up the node list with the data map
+
+ dojo.dnd.Selector.superclass.sync.call(this);
+
+ // fix the anchor
+ if(this.anchor){
+ if(!this.getItem(this.anchor.id)){
+ this.anchor = null;
+ }
+ }
+
+ // fix the selection
+ var t = [], e = dojo.dnd._empty;
+ for(var i in this.selection){
+ if(i in e){ continue; }
+ if(!this.getItem(i)){
+ t.push(i);
+ }
+ }
+ dojo.forEach(t, function(i){
+ delete this.selection[i];
+ }, this);
+
+ return this; // self
+ },
+ insertNodes: function(addSelected, data, before, anchor){
+ // summary:
+ // inserts new data items (see `dojo.dnd.Container.insertNodes()` method for details)
+ // addSelected: Boolean
+ // all new nodes will be added to selected items, if true, no selection change otherwise
+ // data: Array
+ // a list of data items, which should be processed by the creator function
+ // before: Boolean
+ // insert before the anchor, if true, and after the anchor otherwise
+ // anchor: Node
+ // the anchor node to be used as a point of insertion
+ var oldCreator = this._normalizedCreator;
+ this._normalizedCreator = function(item, hint){
+ var t = oldCreator.call(this, item, hint);
+ if(addSelected){
+ if(!this.anchor){
+ this.anchor = t.node;
+ this._removeItemClass(t.node, "Selected");
+ this._addItemClass(this.anchor, "Anchor");
+ }else if(this.anchor != t.node){
+ this._removeItemClass(t.node, "Anchor");
+ this._addItemClass(t.node, "Selected");
+ }
+ this.selection[t.node.id] = 1;
+ }else{
+ this._removeItemClass(t.node, "Selected");
+ this._removeItemClass(t.node, "Anchor");
+ }
+ return t;
+ };
+ dojo.dnd.Selector.superclass.insertNodes.call(this, data, before, anchor);
+ this._normalizedCreator = oldCreator;
+ return this; // self
+ },
+ destroy: function(){
+ // summary:
+ // prepares the object to be garbage-collected
+ dojo.dnd.Selector.superclass.destroy.call(this);
+ this.selection = this.anchor = null;
+ },
+
+ // markup methods
+ markupFactory: function(params, node){
+ params._skipStartup = true;
+ return new dojo.dnd.Selector(node, params);
+ },
+
+ // mouse events
+ onMouseDown: function(e){
+ // summary:
+ // event processor for onmousedown
+ // e: Event
+ // mouse event
+ if(this.autoSync){ this.sync(); }
+ if(!this.current){ return; }
+ if(!this.singular && !dojo.isCopyKey(e) && !e.shiftKey && (this.current.id in this.selection)){
+ this.simpleSelection = true;
+ if(e.button === dojo.mouseButtons.LEFT){
+ // accept the left button and stop the event
+ // for IE we don't stop event when multiple buttons are pressed
+ dojo.stopEvent(e);
+ }
+ return;
+ }
+ if(!this.singular && e.shiftKey){
+ if(!dojo.isCopyKey(e)){
+ this._removeSelection();
+ }
+ var c = this.getAllNodes();
+ if(c.length){
+ if(!this.anchor){
+ this.anchor = c[0];
+ this._addItemClass(this.anchor, "Anchor");
+ }
+ this.selection[this.anchor.id] = 1;
+ if(this.anchor != this.current){
+ var i = 0;
+ for(; i < c.length; ++i){
+ var node = c[i];
+ if(node == this.anchor || node == this.current){ break; }
+ }
+ for(++i; i < c.length; ++i){
+ var node = c[i];
+ if(node == this.anchor || node == this.current){ break; }
+ this._addItemClass(node, "Selected");
+ this.selection[node.id] = 1;
+ }
+ this._addItemClass(this.current, "Selected");
+ this.selection[this.current.id] = 1;
+ }
+ }
+ }else{
+ if(this.singular){
+ if(this.anchor == this.current){
+ if(dojo.isCopyKey(e)){
+ this.selectNone();
+ }
+ }else{
+ this.selectNone();
+ this.anchor = this.current;
+ this._addItemClass(this.anchor, "Anchor");
+ this.selection[this.current.id] = 1;
+ }
+ }else{
+ if(dojo.isCopyKey(e)){
+ if(this.anchor == this.current){
+ delete this.selection[this.anchor.id];
+ this._removeAnchor();
+ }else{
+ if(this.current.id in this.selection){
+ this._removeItemClass(this.current, "Selected");
+ delete this.selection[this.current.id];
+ }else{
+ if(this.anchor){
+ this._removeItemClass(this.anchor, "Anchor");
+ this._addItemClass(this.anchor, "Selected");
+ }
+ this.anchor = this.current;
+ this._addItemClass(this.current, "Anchor");
+ this.selection[this.current.id] = 1;
+ }
+ }
+ }else{
+ if(!(this.current.id in this.selection)){
+ this.selectNone();
+ this.anchor = this.current;
+ this._addItemClass(this.current, "Anchor");
+ this.selection[this.current.id] = 1;
+ }
+ }
+ }
+ }
+ dojo.stopEvent(e);
+ },
+ onMouseUp: function(e){
+ // summary:
+ // event processor for onmouseup
+ // e: Event
+ // mouse event
+ if(!this.simpleSelection){ return; }
+ this.simpleSelection = false;
+ this.selectNone();
+ if(this.current){
+ this.anchor = this.current;
+ this._addItemClass(this.anchor, "Anchor");
+ this.selection[this.current.id] = 1;
+ }
+ },
+ onMouseMove: function(e){
+ // summary
+ // event processor for onmousemove
+ // e: Event
+ // mouse event
+ this.simpleSelection = false;
+ },
+
+ // utilities
+ onOverEvent: function(){
+ // summary:
+ // this function is called once, when mouse is over our container
+ this.onmousemoveEvent = dojo.connect(this.node, "onmousemove", this, "onMouseMove");
+ },
+ onOutEvent: function(){
+ // summary:
+ // this function is called once, when mouse is out of our container
+ dojo.disconnect(this.onmousemoveEvent);
+ delete this.onmousemoveEvent;
+ },
+ _removeSelection: function(){
+ // summary:
+ // unselects all items
+ var e = dojo.dnd._empty;
+ for(var i in this.selection){
+ if(i in e){ continue; }
+ var node = dojo.byId(i);
+ if(node){ this._removeItemClass(node, "Selected"); }
+ }
+ this.selection = {};
+ return this; // self
+ },
+ _removeAnchor: function(){
+ if(this.anchor){
+ this._removeItemClass(this.anchor, "Anchor");
+ this.anchor = null;
+ }
+ return this; // self
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Avatar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Avatar"] = true;
+dojo.provide("dojo.dnd.Avatar");
+
+
+
+
+dojo.declare("dojo.dnd.Avatar", null, {
+ // summary:
+ // Object that represents transferred DnD items visually
+ // manager: Object
+ // a DnD manager object
+
+ constructor: function(manager){
+ this.manager = manager;
+ this.construct();
+ },
+
+ // methods
+ construct: function(){
+ // summary:
+ // constructor function;
+ // it is separate so it can be (dynamically) overwritten in case of need
+ this.isA11y = dojo.hasClass(dojo.body(),"dijit_a11y");
+ var a = dojo.create("table", {
+ "class": "dojoDndAvatar",
+ style: {
+ position: "absolute",
+ zIndex: "1999",
+ margin: "0px"
+ }
+ }),
+ source = this.manager.source, node,
+ b = dojo.create("tbody", null, a),
+ tr = dojo.create("tr", null, b),
+ td = dojo.create("td", null, tr),
+ icon = this.isA11y ? dojo.create("span", {
+ id : "a11yIcon",
+ innerHTML : this.manager.copy ? '+' : "<"
+ }, td) : null,
+ span = dojo.create("span", {
+ innerHTML: source.generateText ? this._generateText() : ""
+ }, td),
+ k = Math.min(5, this.manager.nodes.length), i = 0;
+ // we have to set the opacity on IE only after the node is live
+ dojo.attr(tr, {
+ "class": "dojoDndAvatarHeader",
+ style: {opacity: 0.9}
+ });
+ for(; i < k; ++i){
+ if(source.creator){
+ // create an avatar representation of the node
+ node = source._normalizedCreator(source.getItem(this.manager.nodes[i].id).data, "avatar").node;
+ }else{
+ // or just clone the node and hope it works
+ node = this.manager.nodes[i].cloneNode(true);
+ if(node.tagName.toLowerCase() == "tr"){
+ // insert extra table nodes
+ var table = dojo.create("table"),
+ tbody = dojo.create("tbody", null, table);
+ tbody.appendChild(node);
+ node = table;
+ }
+ }
+ node.id = "";
+ tr = dojo.create("tr", null, b);
+ td = dojo.create("td", null, tr);
+ td.appendChild(node);
+ dojo.attr(tr, {
+ "class": "dojoDndAvatarItem",
+ style: {opacity: (9 - i) / 10}
+ });
+ }
+ this.node = a;
+ },
+ destroy: function(){
+ // summary:
+ // destructor for the avatar; called to remove all references so it can be garbage-collected
+ dojo.destroy(this.node);
+ this.node = false;
+ },
+ update: function(){
+ // summary:
+ // updates the avatar to reflect the current DnD state
+ dojo[(this.manager.canDropFlag ? "add" : "remove") + "Class"](this.node, "dojoDndAvatarCanDrop");
+ if (this.isA11y){
+ var icon = dojo.byId("a11yIcon");
+ var text = '+'; // assume canDrop && copy
+ if (this.manager.canDropFlag && !this.manager.copy) {
+ text = '< '; // canDrop && move
+ }else if (!this.manager.canDropFlag && !this.manager.copy) {
+ text = "o"; //!canDrop && move
+ }else if(!this.manager.canDropFlag){
+ text = 'x'; // !canDrop && copy
+ }
+ icon.innerHTML=text;
+ }
+ // replace text
+ dojo.query(("tr.dojoDndAvatarHeader td span" +(this.isA11y ? " span" : "")), this.node).forEach(
+ function(node){
+ node.innerHTML = this._generateText();
+ }, this);
+ },
+ _generateText: function(){
+ // summary: generates a proper text to reflect copying or moving of items
+ return this.manager.nodes.length.toString();
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Manager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Manager"] = true;
+dojo.provide("dojo.dnd.Manager");
+
+
+
+
+
+
+dojo.declare("dojo.dnd.Manager", null, {
+ // summary:
+ // the manager of DnD operations (usually a singleton)
+ constructor: function(){
+ this.avatar = null;
+ this.source = null;
+ this.nodes = [];
+ this.copy = true;
+ this.target = null;
+ this.canDropFlag = false;
+ this.events = [];
+ },
+
+ // avatar's offset from the mouse
+ OFFSET_X: 16,
+ OFFSET_Y: 16,
+
+ // methods
+ overSource: function(source){
+ // summary:
+ // called when a source detected a mouse-over condition
+ // source: Object
+ // the reporter
+ if(this.avatar){
+ this.target = (source && source.targetState != "Disabled") ? source : null;
+ this.canDropFlag = Boolean(this.target);
+ this.avatar.update();
+ }
+ dojo.publish("/dnd/source/over", [source]);
+ },
+ outSource: function(source){
+ // summary:
+ // called when a source detected a mouse-out condition
+ // source: Object
+ // the reporter
+ if(this.avatar){
+ if(this.target == source){
+ this.target = null;
+ this.canDropFlag = false;
+ this.avatar.update();
+ dojo.publish("/dnd/source/over", [null]);
+ }
+ }else{
+ dojo.publish("/dnd/source/over", [null]);
+ }
+ },
+ startDrag: function(source, nodes, copy){
+ // summary:
+ // called to initiate the DnD operation
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+ this.source = source;
+ this.nodes = nodes;
+ this.copy = Boolean(copy); // normalizing to true boolean
+ this.avatar = this.makeAvatar();
+ dojo.body().appendChild(this.avatar.node);
+ dojo.publish("/dnd/start", [source, nodes, this.copy]);
+ this.events = [
+ dojo.connect(dojo.doc, "onmousemove", this, "onMouseMove"),
+ dojo.connect(dojo.doc, "onmouseup", this, "onMouseUp"),
+ dojo.connect(dojo.doc, "onkeydown", this, "onKeyDown"),
+ dojo.connect(dojo.doc, "onkeyup", this, "onKeyUp"),
+ // cancel text selection and text dragging
+ dojo.connect(dojo.doc, "ondragstart", dojo.stopEvent),
+ dojo.connect(dojo.body(), "onselectstart", dojo.stopEvent)
+ ];
+ var c = "dojoDnd" + (copy ? "Copy" : "Move");
+ dojo.addClass(dojo.body(), c);
+ },
+ canDrop: function(flag){
+ // summary:
+ // called to notify if the current target can accept items
+ var canDropFlag = Boolean(this.target && flag);
+ if(this.canDropFlag != canDropFlag){
+ this.canDropFlag = canDropFlag;
+ this.avatar.update();
+ }
+ },
+ stopDrag: function(){
+ // summary:
+ // stop the DnD in progress
+ dojo.removeClass(dojo.body(), ["dojoDndCopy", "dojoDndMove"]);
+ dojo.forEach(this.events, dojo.disconnect);
+ this.events = [];
+ this.avatar.destroy();
+ this.avatar = null;
+ this.source = this.target = null;
+ this.nodes = [];
+ },
+ makeAvatar: function(){
+ // summary:
+ // makes the avatar; it is separate to be overwritten dynamically, if needed
+ return new dojo.dnd.Avatar(this);
+ },
+ updateAvatar: function(){
+ // summary:
+ // updates the avatar; it is separate to be overwritten dynamically, if needed
+ this.avatar.update();
+ },
+
+ // mouse event processors
+ onMouseMove: function(e){
+ // summary:
+ // event processor for onmousemove
+ // e: Event
+ // mouse event
+ var a = this.avatar;
+ if(a){
+ dojo.dnd.autoScrollNodes(e);
+ //dojo.dnd.autoScroll(e);
+ var s = a.node.style;
+ s.left = (e.pageX + this.OFFSET_X) + "px";
+ s.top = (e.pageY + this.OFFSET_Y) + "px";
+ var copy = Boolean(this.source.copyState(dojo.isCopyKey(e)));
+ if(this.copy != copy){
+ this._setCopyStatus(copy);
+ }
+ }
+ },
+ onMouseUp: function(e){
+ // summary:
+ // event processor for onmouseup
+ // e: Event
+ // mouse event
+ if(this.avatar){
+ if(this.target && this.canDropFlag){
+ var copy = Boolean(this.source.copyState(dojo.isCopyKey(e))),
+ params = [this.source, this.nodes, copy, this.target, e];
+ dojo.publish("/dnd/drop/before", params);
+ dojo.publish("/dnd/drop", params);
+ }else{
+ dojo.publish("/dnd/cancel");
+ }
+ this.stopDrag();
+ }
+ },
+
+ // keyboard event processors
+ onKeyDown: function(e){
+ // summary:
+ // event processor for onkeydown:
+ // watching for CTRL for copy/move status, watching for ESCAPE to cancel the drag
+ // e: Event
+ // keyboard event
+ if(this.avatar){
+ switch(e.keyCode){
+ case dojo.keys.CTRL:
+ var copy = Boolean(this.source.copyState(true));
+ if(this.copy != copy){
+ this._setCopyStatus(copy);
+ }
+ break;
+ case dojo.keys.ESCAPE:
+ dojo.publish("/dnd/cancel");
+ this.stopDrag();
+ break;
+ }
+ }
+ },
+ onKeyUp: function(e){
+ // summary:
+ // event processor for onkeyup, watching for CTRL for copy/move status
+ // e: Event
+ // keyboard event
+ if(this.avatar && e.keyCode == dojo.keys.CTRL){
+ var copy = Boolean(this.source.copyState(false));
+ if(this.copy != copy){
+ this._setCopyStatus(copy);
+ }
+ }
+ },
+
+ // utilities
+ _setCopyStatus: function(copy){
+ // summary:
+ // changes the copy status
+ // copy: Boolean
+ // the copy status
+ this.copy = copy;
+ this.source._markDndStatus(this.copy);
+ this.updateAvatar();
+ dojo.replaceClass(dojo.body(),
+ "dojoDnd" + (this.copy ? "Copy" : "Move"),
+ "dojoDnd" + (this.copy ? "Move" : "Copy"));
+ }
+});
+
+// dojo.dnd._manager:
+// The manager singleton variable. Can be overwritten if needed.
+dojo.dnd._manager = null;
+
+dojo.dnd.manager = function(){
+ // summary:
+ // Returns the current DnD manager. Creates one if it is not created yet.
+ if(!dojo.dnd._manager){
+ dojo.dnd._manager = new dojo.dnd.Manager();
+ }
+ return dojo.dnd._manager; // Object
+};
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Source"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Source"] = true;
+dojo.provide("dojo.dnd.Source");
+
+
+
+
+
+/*
+ Container property:
+ "Horizontal"- if this is the horizontal container
+ Source states:
+ "" - normal state
+ "Moved" - this source is being moved
+ "Copied" - this source is being copied
+ Target states:
+ "" - normal state
+ "Disabled" - the target cannot accept an avatar
+ Target anchor state:
+ "" - item is not selected
+ "Before" - insert point is before the anchor
+ "After" - insert point is after the anchor
+*/
+
+/*=====
+dojo.dnd.__SourceArgs = function(){
+ // summary:
+ // a dict of parameters for DnD Source configuration. Note that any
+ // property on Source elements may be configured, but this is the
+ // short-list
+ // isSource: Boolean?
+ // can be used as a DnD source. Defaults to true.
+ // accept: Array?
+ // list of accepted types (text strings) for a target; defaults to
+ // ["text"]
+ // autoSync: Boolean
+ // if true refreshes the node list on every operation; false by default
+ // copyOnly: Boolean?
+ // copy items, if true, use a state of Ctrl key otherwise,
+ // see selfCopy and selfAccept for more details
+ // delay: Number
+ // the move delay in pixels before detecting a drag; 0 by default
+ // horizontal: Boolean?
+ // a horizontal container, if true, vertical otherwise or when omitted
+ // selfCopy: Boolean?
+ // copy items by default when dropping on itself,
+ // false by default, works only if copyOnly is true
+ // selfAccept: Boolean?
+ // accept its own items when copyOnly is true,
+ // true by default, works only if copyOnly is true
+ // withHandles: Boolean?
+ // allows dragging only by handles, false by default
+ // generateText: Boolean?
+ // generate text node for drag and drop, true by default
+ this.isSource = isSource;
+ this.accept = accept;
+ this.autoSync = autoSync;
+ this.copyOnly = copyOnly;
+ this.delay = delay;
+ this.horizontal = horizontal;
+ this.selfCopy = selfCopy;
+ this.selfAccept = selfAccept;
+ this.withHandles = withHandles;
+ this.generateText = true;
+}
+=====*/
+
+dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
+ // summary:
+ // a Source object, which can be used as a DnD source, or a DnD target
+
+ // object attributes (for markup)
+ isSource: true,
+ horizontal: false,
+ copyOnly: false,
+ selfCopy: false,
+ selfAccept: true,
+ skipForm: false,
+ withHandles: false,
+ autoSync: false,
+ delay: 0, // pixels
+ accept: ["text"],
+ generateText: true,
+
+ constructor: function(/*DOMNode|String*/node, /*dojo.dnd.__SourceArgs?*/params){
+ // summary:
+ // a constructor of the Source
+ // node:
+ // node or node's id to build the source on
+ // params:
+ // any property of this class may be configured via the params
+ // object which is mixed-in to the `dojo.dnd.Source` instance
+ dojo.mixin(this, dojo.mixin({}, params));
+ var type = this.accept;
+ if(type.length){
+ this.accept = {};
+ for(var i = 0; i < type.length; ++i){
+ this.accept[type[i]] = 1;
+ }
+ }
+ // class-specific variables
+ this.isDragging = false;
+ this.mouseDown = false;
+ this.targetAnchor = null;
+ this.targetBox = null;
+ this.before = true;
+ this._lastX = 0;
+ this._lastY = 0;
+ // states
+ this.sourceState = "";
+ if(this.isSource){
+ dojo.addClass(this.node, "dojoDndSource");
+ }
+ this.targetState = "";
+ if(this.accept){
+ dojo.addClass(this.node, "dojoDndTarget");
+ }
+ if(this.horizontal){
+ dojo.addClass(this.node, "dojoDndHorizontal");
+ }
+ // set up events
+ this.topics = [
+ dojo.subscribe("/dnd/source/over", this, "onDndSourceOver"),
+ dojo.subscribe("/dnd/start", this, "onDndStart"),
+ dojo.subscribe("/dnd/drop", this, "onDndDrop"),
+ dojo.subscribe("/dnd/cancel", this, "onDndCancel")
+ ];
+ },
+
+ // methods
+ checkAcceptance: function(source, nodes){
+ // summary:
+ // checks if the target can accept nodes from this source
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ if(this == source){
+ return !this.copyOnly || this.selfAccept;
+ }
+ for(var i = 0; i < nodes.length; ++i){
+ var type = source.getItem(nodes[i].id).type;
+ // type instanceof Array
+ var flag = false;
+ for(var j = 0; j < type.length; ++j){
+ if(type[j] in this.accept){
+ flag = true;
+ break;
+ }
+ }
+ if(!flag){
+ return false; // Boolean
+ }
+ }
+ return true; // Boolean
+ },
+ copyState: function(keyPressed, self){
+ // summary:
+ // Returns true if we need to copy items, false to move.
+ // It is separated to be overwritten dynamically, if needed.
+ // keyPressed: Boolean
+ // the "copy" key was pressed
+ // self: Boolean?
+ // optional flag that means that we are about to drop on itself
+
+ if(keyPressed){ return true; }
+ if(arguments.length < 2){
+ self = this == dojo.dnd.manager().target;
+ }
+ if(self){
+ if(this.copyOnly){
+ return this.selfCopy;
+ }
+ }else{
+ return this.copyOnly;
+ }
+ return false; // Boolean
+ },
+ destroy: function(){
+ // summary:
+ // prepares the object to be garbage-collected
+ dojo.dnd.Source.superclass.destroy.call(this);
+ dojo.forEach(this.topics, dojo.unsubscribe);
+ this.targetAnchor = null;
+ },
+
+ // markup methods
+ markupFactory: function(params, node){
+ params._skipStartup = true;
+ return new dojo.dnd.Source(node, params);
+ },
+
+ // mouse event processors
+ onMouseMove: function(e){
+ // summary:
+ // event processor for onmousemove
+ // e: Event
+ // mouse event
+ if(this.isDragging && this.targetState == "Disabled"){ return; }
+ dojo.dnd.Source.superclass.onMouseMove.call(this, e);
+ var m = dojo.dnd.manager();
+ if(!this.isDragging){
+ if(this.mouseDown && this.isSource &&
+ (Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.pageY - this._lastY) > this.delay)){
+ var nodes = this.getSelectedNodes();
+ if(nodes.length){
+ m.startDrag(this, nodes, this.copyState(dojo.isCopyKey(e), true));
+ }
+ }
+ }
+ if(this.isDragging){
+ // calculate before/after
+ var before = false;
+ if(this.current){
+ if(!this.targetBox || this.targetAnchor != this.current){
+ this.targetBox = dojo.position(this.current, true);
+ }
+ if(this.horizontal){
+ before = (e.pageX - this.targetBox.x) < (this.targetBox.w / 2);
+ }else{
+ before = (e.pageY - this.targetBox.y) < (this.targetBox.h / 2);
+ }
+ }
+ if(this.current != this.targetAnchor || before != this.before){
+ this._markTargetAnchor(before);
+ m.canDrop(!this.current || m.source != this || !(this.current.id in this.selection));
+ }
+ }
+ },
+ onMouseDown: function(e){
+ // summary:
+ // event processor for onmousedown
+ // e: Event
+ // mouse event
+ if(!this.mouseDown && this._legalMouseDown(e) && (!this.skipForm || !dojo.dnd.isFormElement(e))){
+ this.mouseDown = true;
+ this._lastX = e.pageX;
+ this._lastY = e.pageY;
+ dojo.dnd.Source.superclass.onMouseDown.call(this, e);
+ }
+ },
+ onMouseUp: function(e){
+ // summary:
+ // event processor for onmouseup
+ // e: Event
+ // mouse event
+ if(this.mouseDown){
+ this.mouseDown = false;
+ dojo.dnd.Source.superclass.onMouseUp.call(this, e);
+ }
+ },
+
+ // topic event processors
+ onDndSourceOver: function(source){
+ // summary:
+ // topic event processor for /dnd/source/over, called when detected a current source
+ // source: Object
+ // the source which has the mouse over it
+ if(this != source){
+ this.mouseDown = false;
+ if(this.targetAnchor){
+ this._unmarkTargetAnchor();
+ }
+ }else if(this.isDragging){
+ var m = dojo.dnd.manager();
+ m.canDrop(this.targetState != "Disabled" && (!this.current || m.source != this || !(this.current.id in this.selection)));
+ }
+ },
+ onDndStart: function(source, nodes, copy){
+ // summary:
+ // topic event processor for /dnd/start, called to initiate the DnD operation
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+ if(this.autoSync){ this.sync(); }
+ if(this.isSource){
+ this._changeState("Source", this == source ? (copy ? "Copied" : "Moved") : "");
+ }
+ var accepted = this.accept && this.checkAcceptance(source, nodes);
+ this._changeState("Target", accepted ? "" : "Disabled");
+ if(this == source){
+ dojo.dnd.manager().overSource(this);
+ }
+ this.isDragging = true;
+ },
+ onDndDrop: function(source, nodes, copy, target){
+ // summary:
+ // topic event processor for /dnd/drop, called to finish the DnD operation
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+ // target: Object
+ // the target which accepts items
+ if(this == target){
+ // this one is for us => move nodes!
+ this.onDrop(source, nodes, copy);
+ }
+ this.onDndCancel();
+ },
+ onDndCancel: function(){
+ // summary:
+ // topic event processor for /dnd/cancel, called to cancel the DnD operation
+ if(this.targetAnchor){
+ this._unmarkTargetAnchor();
+ this.targetAnchor = null;
+ }
+ this.before = true;
+ this.isDragging = false;
+ this.mouseDown = false;
+ this._changeState("Source", "");
+ this._changeState("Target", "");
+ },
+
+ // local events
+ onDrop: function(source, nodes, copy){
+ // summary:
+ // called only on the current target, when drop is performed
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+
+ if(this != source){
+ this.onDropExternal(source, nodes, copy);
+ }else{
+ this.onDropInternal(nodes, copy);
+ }
+ },
+ onDropExternal: function(source, nodes, copy){
+ // summary:
+ // called only on the current target, when drop is performed
+ // from an external source
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+
+ var oldCreator = this._normalizedCreator;
+ // transferring nodes from the source to the target
+ if(this.creator){
+ // use defined creator
+ this._normalizedCreator = function(node, hint){
+ return oldCreator.call(this, source.getItem(node.id).data, hint);
+ };
+ }else{
+ // we have no creator defined => move/clone nodes
+ if(copy){
+ // clone nodes
+ this._normalizedCreator = function(node, hint){
+ var t = source.getItem(node.id);
+ var n = node.cloneNode(true);
+ n.id = dojo.dnd.getUniqueId();
+ return {node: n, data: t.data, type: t.type};
+ };
+ }else{
+ // move nodes
+ this._normalizedCreator = function(node, hint){
+ var t = source.getItem(node.id);
+ source.delItem(node.id);
+ return {node: node, data: t.data, type: t.type};
+ };
+ }
+ }
+ this.selectNone();
+ if(!copy && !this.creator){
+ source.selectNone();
+ }
+ this.insertNodes(true, nodes, this.before, this.current);
+ if(!copy && this.creator){
+ source.deleteSelectedNodes();
+ }
+ this._normalizedCreator = oldCreator;
+ },
+ onDropInternal: function(nodes, copy){
+ // summary:
+ // called only on the current target, when drop is performed
+ // from the same target/source
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+
+ var oldCreator = this._normalizedCreator;
+ // transferring nodes within the single source
+ if(this.current && this.current.id in this.selection){
+ // do nothing
+ return;
+ }
+ if(copy){
+ if(this.creator){
+ // create new copies of data items
+ this._normalizedCreator = function(node, hint){
+ return oldCreator.call(this, this.getItem(node.id).data, hint);
+ };
+ }else{
+ // clone nodes
+ this._normalizedCreator = function(node, hint){
+ var t = this.getItem(node.id);
+ var n = node.cloneNode(true);
+ n.id = dojo.dnd.getUniqueId();
+ return {node: n, data: t.data, type: t.type};
+ };
+ }
+ }else{
+ // move nodes
+ if(!this.current){
+ // do nothing
+ return;
+ }
+ this._normalizedCreator = function(node, hint){
+ var t = this.getItem(node.id);
+ return {node: node, data: t.data, type: t.type};
+ };
+ }
+ this._removeSelection();
+ this.insertNodes(true, nodes, this.before, this.current);
+ this._normalizedCreator = oldCreator;
+ },
+ onDraggingOver: function(){
+ // summary:
+ // called during the active DnD operation, when items
+ // are dragged over this target, and it is not disabled
+ },
+ onDraggingOut: function(){
+ // summary:
+ // called during the active DnD operation, when items
+ // are dragged away from this target, and it is not disabled
+ },
+
+ // utilities
+ onOverEvent: function(){
+ // summary:
+ // this function is called once, when mouse is over our container
+ dojo.dnd.Source.superclass.onOverEvent.call(this);
+ dojo.dnd.manager().overSource(this);
+ if(this.isDragging && this.targetState != "Disabled"){
+ this.onDraggingOver();
+ }
+ },
+ onOutEvent: function(){
+ // summary:
+ // this function is called once, when mouse is out of our container
+ dojo.dnd.Source.superclass.onOutEvent.call(this);
+ dojo.dnd.manager().outSource(this);
+ if(this.isDragging && this.targetState != "Disabled"){
+ this.onDraggingOut();
+ }
+ },
+ _markTargetAnchor: function(before){
+ // summary:
+ // assigns a class to the current target anchor based on "before" status
+ // before: Boolean
+ // insert before, if true, after otherwise
+ if(this.current == this.targetAnchor && this.before == before){ return; }
+ if(this.targetAnchor){
+ this._removeItemClass(this.targetAnchor, this.before ? "Before" : "After");
+ }
+ this.targetAnchor = this.current;
+ this.targetBox = null;
+ this.before = before;
+ if(this.targetAnchor){
+ this._addItemClass(this.targetAnchor, this.before ? "Before" : "After");
+ }
+ },
+ _unmarkTargetAnchor: function(){
+ // summary:
+ // removes a class of the current target anchor based on "before" status
+ if(!this.targetAnchor){ return; }
+ this._removeItemClass(this.targetAnchor, this.before ? "Before" : "After");
+ this.targetAnchor = null;
+ this.targetBox = null;
+ this.before = true;
+ },
+ _markDndStatus: function(copy){
+ // summary:
+ // changes source's state based on "copy" status
+ this._changeState("Source", copy ? "Copied" : "Moved");
+ },
+ _legalMouseDown: function(e){
+ // summary:
+ // checks if user clicked on "approved" items
+ // e: Event
+ // mouse event
+
+ // accept only the left mouse button
+ if(!dojo.mouseButtons.isLeft(e)){ return false; }
+
+ if(!this.withHandles){ return true; }
+
+ // check for handles
+ for(var node = e.target; node && node !== this.node; node = node.parentNode){
+ if(dojo.hasClass(node, "dojoDndHandle")){ return true; }
+ if(dojo.hasClass(node, "dojoDndItem") || dojo.hasClass(node, "dojoDndIgnore")){ break; }
+ }
+ return false; // Boolean
+ }
+});
+
+dojo.declare("dojo.dnd.Target", dojo.dnd.Source, {
+ // summary: a Target object, which can be used as a DnD target
+
+ constructor: function(node, params){
+ // summary:
+ // a constructor of the Target --- see the `dojo.dnd.Source.constructor` for details
+ this.isSource = false;
+ dojo.removeClass(this.node, "dojoDndSource");
+ },
+
+ // markup methods
+ markupFactory: function(params, node){
+ params._skipStartup = true;
+ return new dojo.dnd.Target(node, params);
+ }
+});
+
+dojo.declare("dojo.dnd.AutoSource", dojo.dnd.Source, {
+ // summary:
+ // a source that syncs its DnD nodes by default
+
+ constructor: function(node, params){
+ // summary:
+ // constructor of the AutoSource --- see the Source constructor for details
+ this.autoSync = true;
+ },
+
+ // markup methods
+ markupFactory: function(params, node){
+ params._skipStartup = true;
+ return new dojo.dnd.AutoSource(node, params);
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._View"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._View"] = true;
+dojo.provide("dojox.grid._View");
+
+
+
+
+
+
+
+
+
+
+(function(){
+ // a private function
+ var getStyleText = function(inNode, inStyleText){
+ return inNode.style.cssText == undefined ? inNode.getAttribute("style") : inNode.style.cssText;
+ };
+
+ // some public functions
+ dojo.declare('dojox.grid._View', [dijit._Widget, dijit._Templated], {
+ // summary:
+ // A collection of grid columns. A grid is comprised of a set of views that stack horizontally.
+ // Grid creates views automatically based on grid's layout structure.
+ // Users should typically not need to access individual views directly.
+ //
+ // defaultWidth: String
+ // Default width of the view
+ defaultWidth: "18em",
+
+ // viewWidth: String
+ // Width for the view, in valid css unit
+ viewWidth: "",
+
+ templateString:"<div class=\"dojoxGridView\" role=\"presentation\">\r\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" role=\"presentation\">\r\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" role=\"presentation\">\r\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" role=\"row\"></div>\r\n\t\t</div>\r\n\t</div>\r\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" role=\"presentation\" />\r\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" role=\"presentation\" />\r\n\t<div class=\"dojoxGridScrollbox\" dojoAttachPoint=\"scrollboxNode\" role=\"presentation\">\r\n\t\t<div class=\"dojoxGridContent\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\" role=\"presentation\"></div>\r\n\t</div>\r\n</div>\r\n",
+
+ themeable: false,
+ classTag: 'dojoxGrid',
+ marginBottom: 0,
+ rowPad: 2,
+
+ // _togglingColumn: int
+ // Width of the column being toggled (-1 for none)
+ _togglingColumn: -1,
+
+ // _headerBuilderClass: Object
+ // The class to use for our header builder
+ _headerBuilderClass: dojox.grid._HeaderBuilder,
+
+ // _contentBuilderClass: Object
+ // The class to use for our content builder
+ _contentBuilderClass: dojox.grid._ContentBuilder,
+
+ postMixInProperties: function(){
+ this.rowNodes = {};
+ },
+
+ postCreate: function(){
+ this.connect(this.scrollboxNode,"onscroll","doscroll");
+ dojox.grid.util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]);
+ dojox.grid.util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]);
+ this.content = new this._contentBuilderClass(this);
+ this.header = new this._headerBuilderClass(this);
+ //BiDi: in RTL case, style width='9000em' causes scrolling problem in head node
+ if(!dojo._isBodyLtr()){
+ this.headerNodeContainer.style.width = "";
+ }
+ },
+
+ destroy: function(){
+ dojo.destroy(this.headerNode);
+ delete this.headerNode;
+ for(var i in this.rowNodes){
+ dojo.destroy(this.rowNodes[i]);
+ }
+ this.rowNodes = {};
+ if(this.source){
+ this.source.destroy();
+ }
+ this.inherited(arguments);
+ },
+
+ // focus
+ focus: function(){
+ if(dojo.isIE || dojo.isWebKit || dojo.isOpera){
+ this.hiddenFocusNode.focus();
+ }else{
+ this.scrollboxNode.focus();
+ }
+ },
+
+ setStructure: function(inStructure){
+ var vs = (this.structure = inStructure);
+ // FIXME: similar logic is duplicated in layout
+ if(vs.width && !isNaN(vs.width)){
+ this.viewWidth = vs.width + 'em';
+ }else{
+ this.viewWidth = vs.width || (vs.noscroll ? 'auto' : this.viewWidth); //|| this.defaultWidth;
+ }
+ this._onBeforeRow = vs.onBeforeRow||function(){};
+ this._onAfterRow = vs.onAfterRow||function(){};
+ this.noscroll = vs.noscroll;
+ if(this.noscroll){
+ this.scrollboxNode.style.overflow = "hidden";
+ }
+ this.simpleStructure = Boolean(vs.cells.length == 1);
+ // bookkeeping
+ this.testFlexCells();
+ // accomodate new structure
+ this.updateStructure();
+ },
+
+ _cleanupRowWidgets: function(inRowNode){
+ // Summary:
+ // Cleans up the widgets for the given row node so that
+ // we can reattach them if needed
+ if(inRowNode){
+ dojo.forEach(dojo.query("[widgetId]", inRowNode).map(dijit.byNode), function(w){
+ if(w._destroyOnRemove){
+ w.destroy();
+ delete w;
+ }else if(w.domNode && w.domNode.parentNode){
+ w.domNode.parentNode.removeChild(w.domNode);
+ }
+ });
+ }
+ },
+
+ onBeforeRow: function(inRowIndex, cells){
+ this._onBeforeRow(inRowIndex, cells);
+ if(inRowIndex >= 0){
+ this._cleanupRowWidgets(this.getRowNode(inRowIndex));
+ }
+ },
+
+ onAfterRow: function(inRowIndex, cells, inRowNode){
+ this._onAfterRow(inRowIndex, cells, inRowNode);
+ var g = this.grid;
+ dojo.forEach(dojo.query(".dojoxGridStubNode", inRowNode), function(n){
+ if(n && n.parentNode){
+ var lw = n.getAttribute("linkWidget");
+ var cellIdx = window.parseInt(dojo.attr(n, "cellIdx"), 10);
+ var cellDef = g.getCell(cellIdx);
+ var w = dijit.byId(lw);
+ if(w){
+ n.parentNode.replaceChild(w.domNode, n);
+ if(!w._started){
+ w.startup();
+ }
+ }else{
+ n.innerHTML = "";
+ }
+ }
+ }, this);
+ },
+
+ testFlexCells: function(){
+ // FIXME: cheater, this function does double duty as initializer and tester
+ this.flexCells = false;
+ for(var j=0, row; (row=this.structure.cells[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ cell.view = this;
+ this.flexCells = this.flexCells || cell.isFlex();
+ }
+ }
+ return this.flexCells;
+ },
+
+ updateStructure: function(){
+ // header builder needs to update table map
+ this.header.update();
+ // content builder needs to update markup cache
+ this.content.update();
+ },
+
+ getScrollbarWidth: function(){
+ var hasScrollSpace = this.hasVScrollbar();
+ var overflow = dojo.style(this.scrollboxNode, "overflow");
+ if(this.noscroll || !overflow || overflow == "hidden"){
+ hasScrollSpace = false;
+ }else if(overflow == "scroll"){
+ hasScrollSpace = true;
+ }
+ return (hasScrollSpace ? dojox.html.metrics.getScrollbar().w : 0); // Integer
+ },
+
+ getColumnsWidth: function(){
+ var h = this.headerContentNode;
+ return h && h.firstChild ? h.firstChild.offsetWidth : 0; // Integer
+ },
+
+ setColumnsWidth: function(width){
+ this.headerContentNode.firstChild.style.width = width + 'px';
+ if(this.viewWidth){
+ this.viewWidth = width + 'px';
+ }
+ },
+
+ getWidth: function(){
+ return this.viewWidth || (this.getColumnsWidth()+this.getScrollbarWidth()) +'px'; // String
+ },
+
+ getContentWidth: function(){
+ return Math.max(0, dojo._getContentBox(this.domNode).w - this.getScrollbarWidth()) + 'px'; // String
+ },
+
+ render: function(){
+ this.scrollboxNode.style.height = '';
+ this.renderHeader();
+ if(this._togglingColumn >= 0){
+ this.setColumnsWidth(this.getColumnsWidth() - this._togglingColumn);
+ this._togglingColumn = -1;
+ }
+ var cells = this.grid.layout.cells;
+ var getSibling = dojo.hitch(this, function(node, before){
+ !dojo._isBodyLtr() && (before = !before);
+ var inc = before?-1:1;
+ var idx = this.header.getCellNodeIndex(node) + inc;
+ var cell = cells[idx];
+ while(cell && cell.getHeaderNode() && cell.getHeaderNode().style.display == "none"){
+ idx += inc;
+ cell = cells[idx];
+ }
+ if(cell){
+ return cell.getHeaderNode();
+ }
+ return null;
+ });
+ if(this.grid.columnReordering && this.simpleStructure){
+ if(this.source){
+ this.source.destroy();
+ }
+
+ // Create the top and bottom markers
+ var bottomMarkerId = "dojoxGrid_bottomMarker";
+ var topMarkerId = "dojoxGrid_topMarker";
+ if(this.bottomMarker){
+ dojo.destroy(this.bottomMarker);
+ }
+ this.bottomMarker = dojo.byId(bottomMarkerId);
+ if(this.topMarker){
+ dojo.destroy(this.topMarker);
+ }
+ this.topMarker = dojo.byId(topMarkerId);
+ if (!this.bottomMarker) {
+ this.bottomMarker = dojo.create("div", {
+ "id": bottomMarkerId,
+ "class": "dojoxGridColPlaceBottom"
+ }, dojo.body());
+ this._hide(this.bottomMarker);
+
+
+ this.topMarker = dojo.create("div", {
+ "id": topMarkerId,
+ "class": "dojoxGridColPlaceTop"
+ }, dojo.body());
+ this._hide(this.topMarker);
+ }
+ this.arrowDim = dojo.contentBox(this.bottomMarker);
+
+ var headerHeight = dojo.contentBox(this.headerContentNode.firstChild.rows[0]).h;
+
+ this.source = new dojo.dnd.Source(this.headerContentNode.firstChild.rows[0], {
+ horizontal: true,
+ accept: [ "gridColumn_" + this.grid.id ],
+ viewIndex: this.index,
+ generateText: false,
+ onMouseDown: dojo.hitch(this, function(e){
+ this.header.decorateEvent(e);
+ if((this.header.overRightResizeArea(e) || this.header.overLeftResizeArea(e)) &&
+ this.header.canResize(e) && !this.header.moveable){
+ this.header.beginColumnResize(e);
+ }else{
+ if(this.grid.headerMenu){
+ this.grid.headerMenu.onCancel(true);
+ }
+ // IE reports a left click as 1, where everything else reports 0
+ if(e.button === (dojo.isIE ? 1 : 0)){
+ dojo.dnd.Source.prototype.onMouseDown.call(this.source, e);
+ }
+ }
+ }),
+ onMouseOver: dojo.hitch(this, function(e){
+ var src = this.source;
+ if(src._getChildByEvent(e)){
+ dojo.dnd.Source.prototype.onMouseOver.apply(src, arguments);
+ }
+ }),
+ _markTargetAnchor: dojo.hitch(this, function(before){
+ var src = this.source;
+ if(src.current == src.targetAnchor && src.before == before){ return; }
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ dojo.dnd.Source.prototype._markTargetAnchor.call(src, before);
+
+ var target = before ? src.targetAnchor : getSibling(src.targetAnchor, src.before);
+ var endAdd = 0;
+
+ if (!target) {
+ target = src.targetAnchor;
+ endAdd = dojo.contentBox(target).w + this.arrowDim.w/2 + 2;
+ }
+
+ // NOTE: this is for backwards compatibility with Dojo 1.3
+ var pos = (dojo.position||dojo._abs)(target, true);
+ var left = Math.floor(pos.x - this.arrowDim.w/2 + endAdd);
+
+ dojo.style(this.bottomMarker, "visibility", "visible");
+ dojo.style(this.topMarker, "visibility", "visible");
+ dojo.style(this.bottomMarker, {
+ "left": left + "px",
+ "top" : (headerHeight + pos.y) + "px"
+ });
+
+ dojo.style(this.topMarker, {
+ "left": left + "px",
+ "top" : (pos.y - this.arrowDim.h) + "px"
+ });
+
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._addItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ }),
+ _unmarkTargetAnchor: dojo.hitch(this, function(){
+ var src = this.source;
+ if(!src.targetAnchor){ return; }
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+ dojo.dnd.Source.prototype._unmarkTargetAnchor.call(src);
+ }),
+ destroy: dojo.hitch(this, function(){
+ dojo.disconnect(this._source_conn);
+ dojo.unsubscribe(this._source_sub);
+ dojo.dnd.Source.prototype.destroy.call(this.source);
+ if(this.bottomMarker){
+ dojo.destroy(this.bottomMarker);
+ delete this.bottomMarker;
+ }
+ if(this.topMarker){
+ dojo.destroy(this.topMarker);
+ delete this.topMarker;
+ }
+ }),
+ onDndCancel: dojo.hitch(this, function(){
+ dojo.dnd.Source.prototype.onDndCancel.call(this.source);
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+ })
+ });
+
+ this._source_conn = dojo.connect(this.source, "onDndDrop", this, "_onDndDrop");
+ this._source_sub = dojo.subscribe("/dnd/drop/before", this, "_onDndDropBefore");
+ this.source.startup();
+ }
+ },
+
+ _hide: function(node){
+ dojo.style(node, {
+ left: "-10000px",
+ top: "-10000px",
+ "visibility": "hidden"
+ });
+ },
+
+ _onDndDropBefore: function(source, nodes, copy){
+ if(dojo.dnd.manager().target !== this.source){
+ return;
+ }
+ this.source._targetNode = this.source.targetAnchor;
+ this.source._beforeTarget = this.source.before;
+ var views = this.grid.views.views;
+ var srcView = views[source.viewIndex];
+ var tgtView = views[this.index];
+ if(tgtView != srcView){
+ srcView.convertColPctToFixed();
+ tgtView.convertColPctToFixed();
+ }
+ },
+
+ _onDndDrop: function(source, nodes, copy){
+ if(dojo.dnd.manager().target !== this.source){
+ if(dojo.dnd.manager().source === this.source){
+ this._removingColumn = true;
+ }
+ return;
+ }
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+
+ var getIdx = function(n){
+ return n ? dojo.attr(n, "idx") : null;
+ };
+ var w = dojo.marginBox(nodes[0]).w;
+ if(source.viewIndex !== this.index){
+ var views = this.grid.views.views;
+ var srcView = views[source.viewIndex];
+ var tgtView = views[this.index];
+ if(srcView.viewWidth && srcView.viewWidth != "auto"){
+ srcView.setColumnsWidth(srcView.getColumnsWidth() - w);
+ }
+ if(tgtView.viewWidth && tgtView.viewWidth != "auto"){
+ tgtView.setColumnsWidth(tgtView.getColumnsWidth());
+ }
+ }
+ var stn = this.source._targetNode;
+ var stb = this.source._beforeTarget;
+ !dojo._isBodyLtr() && (stb = !stb);
+ var layout = this.grid.layout;
+ var idx = this.index;
+ delete this.source._targetNode;
+ delete this.source._beforeTarget;
+
+ layout.moveColumn(
+ source.viewIndex,
+ idx,
+ getIdx(nodes[0]),
+ getIdx(stn),
+ stb);
+ },
+
+ renderHeader: function(){
+ this.headerContentNode.innerHTML = this.header.generateHtml(this._getHeaderContent);
+ if(this.flexCells){
+ this.contentWidth = this.getContentWidth();
+ this.headerContentNode.firstChild.style.width = this.contentWidth;
+ }
+ dojox.grid.util.fire(this, "onAfterRow", [-1, this.structure.cells, this.headerContentNode]);
+ },
+
+ // note: not called in 'view' context
+ _getHeaderContent: function(inCell){
+ var n = inCell.name || inCell.grid.getCellName(inCell);
+ var ret = [ '<div class="dojoxGridSortNode' ];
+
+ if(inCell.index != inCell.grid.getSortIndex()){
+ ret.push('">');
+ }else{
+ ret = ret.concat([ ' ',
+ inCell.grid.sortInfo > 0 ? 'dojoxGridSortUp' : 'dojoxGridSortDown',
+ '"><div class="dojoxGridArrowButtonChar">',
+ inCell.grid.sortInfo > 0 ? '&#9650;' : '&#9660;',
+ '</div><div class="dojoxGridArrowButtonNode" role="presentation"></div>',
+ '<div class="dojoxGridColCaption">']);
+ }
+ ret = ret.concat([n, '</div></div>']);
+ return ret.join('');
+ },
+
+ resize: function(){
+ this.adaptHeight();
+ this.adaptWidth();
+ },
+
+ hasHScrollbar: function(reset){
+ var hadScroll = this._hasHScroll||false;
+ if(this._hasHScroll == undefined || reset){
+ if(this.noscroll){
+ this._hasHScroll = false;
+ }else{
+ var style = dojo.style(this.scrollboxNode, "overflow");
+ if(style == "hidden"){
+ this._hasHScroll = false;
+ }else if(style == "scroll"){
+ this._hasHScroll = true;
+ }else{
+ this._hasHScroll = (this.scrollboxNode.offsetWidth - this.getScrollbarWidth() < this.contentNode.offsetWidth );
+ }
+ }
+ }
+ if(hadScroll !== this._hasHScroll){
+ this.grid.update();
+ }
+ return this._hasHScroll; // Boolean
+ },
+
+ hasVScrollbar: function(reset){
+ var hadScroll = this._hasVScroll||false;
+ if(this._hasVScroll == undefined || reset){
+ if(this.noscroll){
+ this._hasVScroll = false;
+ }else{
+ var style = dojo.style(this.scrollboxNode, "overflow");
+ if(style == "hidden"){
+ this._hasVScroll = false;
+ }else if(style == "scroll"){
+ this._hasVScroll = true;
+ }else{
+ this._hasVScroll = (this.scrollboxNode.scrollHeight > this.scrollboxNode.clientHeight);
+ }
+ }
+ }
+ if(hadScroll !== this._hasVScroll){
+ this.grid.update();
+ }
+ return this._hasVScroll; // Boolean
+ },
+
+ convertColPctToFixed: function(){
+ // Fix any percentage widths to be pixel values
+ var hasPct = false;
+ this.grid.initialWidth = "";
+ var cellNodes = dojo.query("th", this.headerContentNode);
+ var fixedWidths = dojo.map(cellNodes, function(c, vIdx){
+ var w = c.style.width;
+ dojo.attr(c, "vIdx", vIdx);
+ if(w && w.slice(-1) == "%"){
+ hasPct = true;
+ }else if(w && w.slice(-2) == "px"){
+ return window.parseInt(w, 10);
+ }
+ return dojo.contentBox(c).w;
+ });
+ if(hasPct){
+ dojo.forEach(this.grid.layout.cells, function(cell, idx){
+ if(cell.view == this){
+ var cellNode = cell.view.getHeaderCellNode(cell.index);
+ if(cellNode && dojo.hasAttr(cellNode, "vIdx")){
+ var vIdx = window.parseInt(dojo.attr(cellNode, "vIdx"));
+ this.setColWidth(idx, fixedWidths[vIdx]);
+ dojo.removeAttr(cellNode, "vIdx");
+ }
+ }
+ }, this);
+ return true;
+ }
+ return false;
+ },
+
+ adaptHeight: function(minusScroll){
+ if(!this.grid._autoHeight){
+ var h = (this.domNode.style.height && parseInt(this.domNode.style.height.replace(/px/,''), 10)) || this.domNode.clientHeight;
+ var self = this;
+ var checkOtherViewScrollers = function(){
+ var v;
+ for(var i in self.grid.views.views){
+ v = self.grid.views.views[i];
+ if(v !== self && v.hasHScrollbar()){
+ return true;
+ }
+ }
+ return false;
+ };
+ if(minusScroll || (this.noscroll && checkOtherViewScrollers())){
+ h -= dojox.html.metrics.getScrollbar().h;
+ }
+ dojox.grid.util.setStyleHeightPx(this.scrollboxNode, h);
+ }
+ this.hasVScrollbar(true);
+ },
+
+ adaptWidth: function(){
+ if(this.flexCells){
+ // the view content width
+ this.contentWidth = this.getContentWidth();
+ this.headerContentNode.firstChild.style.width = this.contentWidth;
+ }
+ // FIXME: it should be easier to get w from this.scrollboxNode.clientWidth,
+ // but clientWidth seemingly does not include scrollbar width in some cases
+ var w = this.scrollboxNode.offsetWidth - this.getScrollbarWidth();
+ if(!this._removingColumn){
+ w = Math.max(w, this.getColumnsWidth()) + 'px';
+ }else{
+ w = Math.min(w, this.getColumnsWidth()) + 'px';
+ this._removingColumn = false;
+ }
+ var cn = this.contentNode;
+ cn.style.width = w;
+ this.hasHScrollbar(true);
+ },
+
+ setSize: function(w, h){
+ var ds = this.domNode.style;
+ var hs = this.headerNode.style;
+
+ if(w){
+ ds.width = w;
+ hs.width = w;
+ }
+ ds.height = (h >= 0 ? h + 'px' : '');
+ },
+
+ renderRow: function(inRowIndex){
+ var rowNode = this.createRowNode(inRowIndex);
+ this.buildRow(inRowIndex, rowNode);
+ this.grid.edit.restore(this, inRowIndex);
+ return rowNode;
+ },
+
+ createRowNode: function(inRowIndex){
+ var node = document.createElement("div");
+ node.className = this.classTag + 'Row';
+ if (this instanceof dojox.grid._RowSelector){
+ dojo.attr(node,"role","presentation");
+ }else{
+ dojo.attr(node,"role","row");
+ if (this.grid.selectionMode != "none") {
+ dojo.attr(node, "aria-selected", "false"); //rows can be selected so add aria-selected prop
+ }
+ }
+ node[dojox.grid.util.gridViewTag] = this.id;
+ node[dojox.grid.util.rowIndexTag] = inRowIndex;
+ this.rowNodes[inRowIndex] = node;
+ return node;
+ },
+
+ buildRow: function(inRowIndex, inRowNode){
+
+ this.buildRowContent(inRowIndex, inRowNode);
+
+ this.styleRow(inRowIndex, inRowNode);
+
+
+ },
+
+ buildRowContent: function(inRowIndex, inRowNode){
+ inRowNode.innerHTML = this.content.generateHtml(inRowIndex, inRowIndex);
+ if(this.flexCells && this.contentWidth){
+ // FIXME: accessing firstChild here breaks encapsulation
+ inRowNode.firstChild.style.width = this.contentWidth;
+ }
+ dojox.grid.util.fire(this, "onAfterRow", [inRowIndex, this.structure.cells, inRowNode]);
+ },
+
+ rowRemoved:function(inRowIndex){
+ if(inRowIndex >= 0){
+ this._cleanupRowWidgets(this.getRowNode(inRowIndex));
+ }
+ this.grid.edit.save(this, inRowIndex);
+ delete this.rowNodes[inRowIndex];
+ },
+
+ getRowNode: function(inRowIndex){
+ return this.rowNodes[inRowIndex];
+ },
+
+ getCellNode: function(inRowIndex, inCellIndex){
+ var row = this.getRowNode(inRowIndex);
+ if(row){
+ return this.content.getCellNode(row, inCellIndex);
+ }
+ },
+
+ getHeaderCellNode: function(inCellIndex){
+ if(this.headerContentNode){
+ return this.header.getCellNode(this.headerContentNode, inCellIndex);
+ }
+ },
+
+ // styling
+ styleRow: function(inRowIndex, inRowNode){
+ inRowNode._style = getStyleText(inRowNode);
+ this.styleRowNode(inRowIndex, inRowNode);
+ },
+
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ this.doStyleRowNode(inRowIndex, inRowNode);
+ }
+ },
+
+ doStyleRowNode: function(inRowIndex, inRowNode){
+ this.grid.styleRowNode(inRowIndex, inRowNode);
+ },
+
+ // updating
+ updateRow: function(inRowIndex){
+ var rowNode = this.getRowNode(inRowIndex);
+ if(rowNode){
+ rowNode.style.height = '';
+ this.buildRow(inRowIndex, rowNode);
+ }
+ return rowNode;
+ },
+
+ updateRowStyles: function(inRowIndex){
+ this.styleRowNode(inRowIndex, this.getRowNode(inRowIndex));
+ },
+
+ // scrolling
+ lastTop: 0,
+ firstScroll:0,
+
+ doscroll: function(inEvent){
+ //var s = dojo.marginBox(this.headerContentNode.firstChild);
+ var isLtr = dojo._isBodyLtr();
+ if(this.firstScroll < 2){
+ if((!isLtr && this.firstScroll == 1) || (isLtr && this.firstScroll === 0)){
+ var s = dojo.marginBox(this.headerNodeContainer);
+ if(dojo.isIE){
+ this.headerNodeContainer.style.width = s.w + this.getScrollbarWidth() + 'px';
+ }else if(dojo.isMoz){
+ //TODO currently only for FF, not sure for safari and opera
+ this.headerNodeContainer.style.width = s.w - this.getScrollbarWidth() + 'px';
+ //this.headerNodeContainer.style.width = s.w + 'px';
+ //set scroll to right in FF
+ this.scrollboxNode.scrollLeft = isLtr ?
+ this.scrollboxNode.clientWidth - this.scrollboxNode.scrollWidth :
+ this.scrollboxNode.scrollWidth - this.scrollboxNode.clientWidth;
+ }
+ }
+ this.firstScroll++;
+ }
+ this.headerNode.scrollLeft = this.scrollboxNode.scrollLeft;
+ // 'lastTop' is a semaphore to prevent feedback-loop with setScrollTop below
+ var top = this.scrollboxNode.scrollTop;
+ if(top !== this.lastTop){
+ this.grid.scrollTo(top);
+ }
+ },
+
+ setScrollTop: function(inTop){
+ // 'lastTop' is a semaphore to prevent feedback-loop with doScroll above
+ this.lastTop = inTop;
+ this.scrollboxNode.scrollTop = inTop;
+ return this.scrollboxNode.scrollTop;
+ },
+
+ // event handlers (direct from DOM)
+ doContentEvent: function(e){
+ if(this.content.decorateEvent(e)){
+ this.grid.onContentEvent(e);
+ }
+ },
+
+ doHeaderEvent: function(e){
+ if(this.header.decorateEvent(e)){
+ this.grid.onHeaderEvent(e);
+ }
+ },
+
+ // event dispatch(from Grid)
+ dispatchContentEvent: function(e){
+ return this.content.dispatchEvent(e);
+ },
+
+ dispatchHeaderEvent: function(e){
+ return this.header.dispatchEvent(e);
+ },
+
+ // column resizing
+ setColWidth: function(inIndex, inWidth){
+ this.grid.setCellWidth(inIndex, inWidth + 'px');
+ },
+
+ update: function(){
+ if(!this.domNode){
+ return;
+ }
+ this.content.update();
+ this.grid.update();
+ //get scroll after update or scroll left setting goes wrong on IE.
+ //See trac: #8040
+ var left = this.scrollboxNode.scrollLeft;
+ this.scrollboxNode.scrollLeft = left;
+ this.headerNode.scrollLeft = left;
+ }
+ });
+
+ dojo.declare("dojox.grid._GridAvatar", dojo.dnd.Avatar, {
+ construct: function(){
+ var dd = dojo.doc;
+
+ var a = dd.createElement("table");
+ a.cellPadding = a.cellSpacing = "0";
+ a.className = "dojoxGridDndAvatar";
+ a.style.position = "absolute";
+ a.style.zIndex = 1999;
+ a.style.margin = "0px"; // to avoid dojo.marginBox() problems with table's margins
+ var b = dd.createElement("tbody");
+ var tr = dd.createElement("tr");
+ var td = dd.createElement("td");
+ var img = dd.createElement("td");
+ tr.className = "dojoxGridDndAvatarItem";
+ img.className = "dojoxGridDndAvatarItemImage";
+ img.style.width = "16px";
+ var source = this.manager.source, node;
+ if(source.creator){
+ // create an avatar representation of the node
+ node = source._normalizedCreator(source.getItem(this.manager.nodes[0].id).data, "avatar").node;
+ }else{
+ // or just clone the node and hope it works
+ node = this.manager.nodes[0].cloneNode(true);
+ var table, tbody;
+ if(node.tagName.toLowerCase() == "tr"){
+ // insert extra table nodes
+ table = dd.createElement("table");
+ tbody = dd.createElement("tbody");
+ tbody.appendChild(node);
+ table.appendChild(tbody);
+ node = table;
+ }else if(node.tagName.toLowerCase() == "th"){
+ // insert extra table nodes
+ table = dd.createElement("table");
+ tbody = dd.createElement("tbody");
+ var r = dd.createElement("tr");
+ table.cellPadding = table.cellSpacing = "0";
+ r.appendChild(node);
+ tbody.appendChild(r);
+ table.appendChild(tbody);
+ node = table;
+ }
+ }
+ node.id = "";
+ td.appendChild(node);
+ tr.appendChild(img);
+ tr.appendChild(td);
+ dojo.style(tr, "opacity", 0.9);
+ b.appendChild(tr);
+
+ a.appendChild(b);
+ this.node = a;
+
+ var m = dojo.dnd.manager();
+ this.oldOffsetY = m.OFFSET_Y;
+ m.OFFSET_Y = 1;
+ },
+ destroy: function(){
+ dojo.dnd.manager().OFFSET_Y = this.oldOffsetY;
+ this.inherited(arguments);
+ }
+ });
+
+ var oldMakeAvatar = dojo.dnd.manager().makeAvatar;
+ dojo.dnd.manager().makeAvatar = function(){
+ var src = this.source;
+ if(src.viewIndex !== undefined && !dojo.hasClass(dojo.body(),"dijit_a11y")){
+ return new dojox.grid._GridAvatar(this);
+ }
+ return oldMakeAvatar.call(dojo.dnd.manager());
+ };
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid._RowSelector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._RowSelector"] = true;
+dojo.provide("dojox.grid._RowSelector");
+
+
+dojo.declare('dojox.grid._RowSelector', dojox.grid._View, {
+ // summary:
+ // Custom grid view. If used in a grid structure, provides a small selectable region for grid rows.
+ defaultWidth: "2em",
+ noscroll: true,
+ padBorderWidth: 2,
+ buildRendering: function(){
+ this.inherited('buildRendering', arguments);
+ this.scrollboxNode.style.overflow = "hidden";
+ this.headerNode.style.visibility = "hidden";
+ },
+ getWidth: function(){
+ return this.viewWidth || this.defaultWidth;
+ },
+ buildRowContent: function(inRowIndex, inRowNode){
+ var w = this.contentWidth || 0;
+ inRowNode.innerHTML = '<table class="dojoxGridRowbarTable" style="width:' + w + 'px;height:1px;" border="0" cellspacing="0" cellpadding="0" role="presentation"><tr><td class="dojoxGridRowbarInner">&nbsp;</td></tr></table>';
+ },
+ renderHeader: function(){
+ },
+ updateRow: function(){
+ },
+ resize: function(){
+ this.adaptHeight();
+ },
+ adaptWidth: function(){
+ // Only calculate this here - rather than every call to buildRowContent
+ if(!("contentWidth" in this) && this.contentNode){
+ this.contentWidth = this.contentNode.offsetWidth - this.padBorderWidth;
+ }
+ },
+ // styling
+ doStyleRowNode: function(inRowIndex, inRowNode){
+ var n = [ "dojoxGridRowbar dojoxGridNonNormalizedCell" ];
+ if(this.grid.rows.isOver(inRowIndex)){
+ n.push("dojoxGridRowbarOver");
+ }
+ if(this.grid.selection.isSelected(inRowIndex)){
+ n.push("dojoxGridRowbarSelected");
+ }
+ inRowNode.className = n.join(" ");
+ },
+ // event handlers
+ domouseover: function(e){
+ this.grid.onMouseOverRow(e);
+ },
+ domouseout: function(e){
+ if(!this.isIntraRowEvent(e)){
+ this.grid.onMouseOutRow(e);
+ }
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._Layout"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Layout"] = true;
+dojo.provide("dojox.grid._Layout");
+
+
+
+dojo.declare("dojox.grid._Layout", null, {
+ // summary:
+ // Controls grid cell layout. Owned by grid and used internally.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+ // flat array of grid cells
+ cells: [],
+ // structured array of grid cells
+ structure: null,
+ // default cell width
+ defaultWidth: '6em',
+
+ // methods
+ moveColumn: function(sourceViewIndex, destViewIndex, cellIndex, targetIndex, before){
+ var source_cells = this.structure[sourceViewIndex].cells[0];
+ var dest_cells = this.structure[destViewIndex].cells[0];
+
+ var cell = null;
+ var cell_ri = 0;
+ var target_ri = 0;
+
+ for(var i=0, c; c=source_cells[i]; i++){
+ if(c.index == cellIndex){
+ cell_ri = i;
+ break;
+ }
+ }
+ cell = source_cells.splice(cell_ri, 1)[0];
+ cell.view = this.grid.views.views[destViewIndex];
+
+ for(i=0, c=null; c=dest_cells[i]; i++){
+ if(c.index == targetIndex){
+ target_ri = i;
+ break;
+ }
+ }
+ if(!before){
+ target_ri += 1;
+ }
+ dest_cells.splice(target_ri, 0, cell);
+
+ var sortedCell = this.grid.getCell(this.grid.getSortIndex());
+ if(sortedCell){
+ sortedCell._currentlySorted = this.grid.getSortAsc();
+ }
+
+ this.cells = [];
+ cellIndex = 0;
+ var v;
+ for(i=0; v=this.structure[i]; i++){
+ for(var j=0, cs; cs=v.cells[j]; j++){
+ for(var k=0; c=cs[k]; k++){
+ c.index = cellIndex;
+ this.cells.push(c);
+ if("_currentlySorted" in c){
+ var si = cellIndex + 1;
+ si *= c._currentlySorted ? 1 : -1;
+ this.grid.sortInfo = si;
+ delete c._currentlySorted;
+ }
+ cellIndex++;
+ }
+ }
+ }
+
+ //Fix #9481 - reset idx in cell markup
+ dojo.forEach(this.cells, function(c){
+ var marks = c.markup[2].split(" ");
+ var oldIdx = parseInt(marks[1].substring(5));//get old "idx"
+ if(oldIdx != c.index){
+ marks[1] = "idx=\"" + c.index + "\"";
+ c.markup[2] = marks.join(" ");
+ }
+ });
+
+ this.grid.setupHeaderMenu();
+ //this.grid.renderOnIdle();
+ },
+
+ setColumnVisibility: function(columnIndex, visible){
+ var cell = this.cells[columnIndex];
+ if(cell.hidden == visible){
+ cell.hidden = !visible;
+ var v = cell.view, w = v.viewWidth;
+ if(w && w != "auto"){
+ v._togglingColumn = dojo.marginBox(cell.getHeaderNode()).w || 0;
+ }
+ v.update();
+ return true;
+ }else{
+ return false;
+ }
+ },
+
+ addCellDef: function(inRowIndex, inCellIndex, inDef){
+ var self = this;
+ var getCellWidth = function(inDef){
+ var w = 0;
+ if(inDef.colSpan > 1){
+ w = 0;
+ }else{
+ w = inDef.width || self._defaultCellProps.width || self.defaultWidth;
+
+ if(!isNaN(w)){
+ w = w + "em";
+ }
+ }
+ return w;
+ };
+
+ var props = {
+ grid: this.grid,
+ subrow: inRowIndex,
+ layoutIndex: inCellIndex,
+ index: this.cells.length
+ };
+
+ if(inDef && inDef instanceof dojox.grid.cells._Base){
+ var new_cell = dojo.clone(inDef);
+ props.unitWidth = getCellWidth(new_cell._props);
+ new_cell = dojo.mixin(new_cell, this._defaultCellProps, inDef._props, props);
+ return new_cell;
+ }
+
+ var cell_type = inDef.type || inDef.cellType || this._defaultCellProps.type || this._defaultCellProps.cellType || dojox.grid.cells.Cell;
+
+ props.unitWidth = getCellWidth(inDef);
+ return new cell_type(dojo.mixin({}, this._defaultCellProps, inDef, props));
+ },
+
+ addRowDef: function(inRowIndex, inDef){
+ var result = [];
+ var relSum = 0, pctSum = 0, doRel = true;
+ for(var i=0, def, cell; (def=inDef[i]); i++){
+ cell = this.addCellDef(inRowIndex, i, def);
+ result.push(cell);
+ this.cells.push(cell);
+ // Check and calculate the sum of all relative widths
+ if(doRel && cell.relWidth){
+ relSum += cell.relWidth;
+ }else if(cell.width){
+ var w = cell.width;
+ if(typeof w == "string" && w.slice(-1) == "%"){
+ pctSum += window.parseInt(w, 10);
+ }else if(w == "auto"){
+ // relative widths doesn't play nice with auto - since we
+ // don't have a way of knowing how much space the auto is
+ // supposed to take up.
+ doRel = false;
+ }
+ }
+ }
+ if(relSum && doRel){
+ // We have some kind of relWidths specified - so change them to %
+ dojo.forEach(result, function(cell){
+ if(cell.relWidth){
+ cell.width = cell.unitWidth = ((cell.relWidth / relSum) * (100 - pctSum)) + "%";
+ }
+ });
+ }
+ return result;
+
+ },
+
+ addRowsDef: function(inDef){
+ var result = [];
+ if(dojo.isArray(inDef)){
+ if(dojo.isArray(inDef[0])){
+ for(var i=0, row; inDef && (row=inDef[i]); i++){
+ result.push(this.addRowDef(i, row));
+ }
+ }else{
+ result.push(this.addRowDef(0, inDef));
+ }
+ }
+ return result;
+ },
+
+ addViewDef: function(inDef){
+ this._defaultCellProps = inDef.defaultCell || {};
+ if(inDef.width && inDef.width == "auto"){
+ delete inDef.width;
+ }
+ return dojo.mixin({}, inDef, {cells: this.addRowsDef(inDef.rows || inDef.cells)});
+ },
+
+ setStructure: function(inStructure){
+ this.fieldIndex = 0;
+ this.cells = [];
+ var s = this.structure = [];
+
+ if(this.grid.rowSelector){
+ var sel = { type: dojox._scopeName + ".grid._RowSelector" };
+
+ if(dojo.isString(this.grid.rowSelector)){
+ var width = this.grid.rowSelector;
+
+ if(width == "false"){
+ sel = null;
+ }else if(width != "true"){
+ sel['width'] = width;
+ }
+ }else{
+ if(!this.grid.rowSelector){
+ sel = null;
+ }
+ }
+
+ if(sel){
+ s.push(this.addViewDef(sel));
+ }
+ }
+
+ var isCell = function(def){
+ return ("name" in def || "field" in def || "get" in def);
+ };
+
+ var isRowDef = function(def){
+ if(dojo.isArray(def)){
+ if(dojo.isArray(def[0]) || isCell(def[0])){
+ return true;
+ }
+ }
+ return false;
+ };
+
+ var isView = function(def){
+ return (def !== null && dojo.isObject(def) &&
+ ("cells" in def || "rows" in def || ("type" in def && !isCell(def))));
+ };
+
+ if(dojo.isArray(inStructure)){
+ var hasViews = false;
+ for(var i=0, st; (st=inStructure[i]); i++){
+ if(isView(st)){
+ hasViews = true;
+ break;
+ }
+ }
+ if(!hasViews){
+ s.push(this.addViewDef({ cells: inStructure }));
+ }else{
+ for(i=0; (st=inStructure[i]); i++){
+ if(isRowDef(st)){
+ s.push(this.addViewDef({ cells: st }));
+ }else if(isView(st)){
+ s.push(this.addViewDef(st));
+ }
+ }
+ }
+ }else if(isView(inStructure)){
+ // it's a view object
+ s.push(this.addViewDef(inStructure));
+ }
+
+ this.cellCount = this.cells.length;
+ this.grid.setupHeaderMenu();
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._ViewManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._ViewManager"] = true;
+dojo.provide("dojox.grid._ViewManager");
+
+dojo.declare('dojox.grid._ViewManager', null, {
+ // summary:
+ // A collection of grid views. Owned by grid and used internally for managing grid views.
+ // description:
+ // Grid creates views automatically based on grid's layout structure.
+ // Users should typically not need to access individual views or the views collection directly.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+
+ defaultWidth: 200,
+
+ views: [],
+
+ // operations
+ resize: function(){
+ this.onEach("resize");
+ },
+
+ render: function(){
+ this.onEach("render");
+ },
+
+ // views
+ addView: function(inView){
+ inView.idx = this.views.length;
+ this.views.push(inView);
+ },
+
+ destroyViews: function(){
+ for(var i=0, v; v=this.views[i]; i++){
+ v.destroy();
+ }
+ this.views = [];
+ },
+
+ getContentNodes: function(){
+ var nodes = [];
+ for(var i=0, v; v=this.views[i]; i++){
+ nodes.push(v.contentNode);
+ }
+ return nodes;
+ },
+
+ forEach: function(inCallback){
+ for(var i=0, v; v=this.views[i]; i++){
+ inCallback(v, i);
+ }
+ },
+
+ onEach: function(inMethod, inArgs){
+ inArgs = inArgs || [];
+ for(var i=0, v; v=this.views[i]; i++){
+ if(inMethod in v){
+ v[inMethod].apply(v, inArgs);
+ }
+ }
+ },
+
+ // layout
+ normalizeHeaderNodeHeight: function(){
+ var rowNodes = [];
+ for(var i=0, v; (v=this.views[i]); i++){
+ if(v.headerContentNode.firstChild){
+ rowNodes.push(v.headerContentNode);
+ }
+ }
+ this.normalizeRowNodeHeights(rowNodes);
+ },
+
+ normalizeRowNodeHeights: function(inRowNodes){
+ var h = 0;
+ var currHeights = [];
+ if(this.grid.rowHeight){
+ h = this.grid.rowHeight;
+ }else{
+ if(inRowNodes.length <= 1){
+ // no need to normalize if we are the only one...
+ return;
+ }
+ for(var i=0, n; (n=inRowNodes[i]); i++){
+ // We only care about the height - so don't use marginBox. This
+ // depends on the container not having any margin (which it shouldn't)
+ // Also - we only look up the height if the cell doesn't have the
+ // dojoxGridNonNormalizedCell class (like for row selectors)
+ if(!dojo.hasClass(n, "dojoxGridNonNormalizedCell")){
+ currHeights[i] = n.firstChild.offsetHeight;
+ h = Math.max(h, currHeights[i]);
+ }
+ }
+ h = (h >= 0 ? h : 0);
+
+ //Work around odd FF3 rendering bug: #8864.
+ //A one px increase fixes FireFox 3's rounding bug for fractional font sizes.
+ if(dojo.isMoz && h){h++;}
+ }
+ for(i=0; (n=inRowNodes[i]); i++){
+ if(currHeights[i] != h){
+ n.firstChild.style.height = h + "px";
+ }
+ }
+ },
+
+ resetHeaderNodeHeight: function(){
+ for(var i=0, v, n; (v=this.views[i]); i++){
+ n = v.headerContentNode.firstChild;
+ if(n){
+ n.style.height = "";
+ }
+ }
+ },
+
+ renormalizeRow: function(inRowIndex){
+ var rowNodes = [];
+ for(var i=0, v, n; (v=this.views[i])&&(n=v.getRowNode(inRowIndex)); i++){
+ n.firstChild.style.height = '';
+ rowNodes.push(n);
+ }
+ this.normalizeRowNodeHeights(rowNodes);
+ },
+
+ getViewWidth: function(inIndex){
+ return this.views[inIndex].getWidth() || this.defaultWidth;
+ },
+
+ // must be called after view widths are properly set or height can be miscalculated
+ // if there are flex columns
+ measureHeader: function(){
+ // need to reset view header heights so they are properly measured.
+ this.resetHeaderNodeHeight();
+ this.forEach(function(inView){
+ inView.headerContentNode.style.height = '';
+ });
+ var h = 0;
+ // calculate maximum view header height
+ this.forEach(function(inView){
+ h = Math.max(inView.headerNode.offsetHeight, h);
+ });
+ return h;
+ },
+
+ measureContent: function(){
+ var h = 0;
+ this.forEach(function(inView){
+ h = Math.max(inView.domNode.offsetHeight, h);
+ });
+ return h;
+ },
+
+ findClient: function(inAutoWidth){
+ // try to use user defined client
+ var c = this.grid.elasticView || -1;
+ // attempt to find implicit client
+ if(c < 0){
+ for(var i=1, v; (v=this.views[i]); i++){
+ if(v.viewWidth){
+ for(i=1; (v=this.views[i]); i++){
+ if(!v.viewWidth){
+ c = i;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ // client is in the middle by default
+ if(c < 0){
+ c = Math.floor(this.views.length / 2);
+ }
+ return c;
+ },
+
+ arrange: function(l, w){
+ var i, v, vw, len = this.views.length;
+ // find the client
+ var c = (w <= 0 ? len : this.findClient());
+ // layout views
+ var setPosition = function(v, l){
+ var ds = v.domNode.style;
+ var hs = v.headerNode.style;
+
+ if(!dojo._isBodyLtr()){
+ ds.right = l + 'px';
+ // fixed rtl, the scrollbar is on the right side in FF
+ if (dojo.isMoz) {
+ hs.right = l + v.getScrollbarWidth() + 'px';
+ hs.width = parseInt(hs.width, 10) - v.getScrollbarWidth() + 'px';
+ }else{
+ hs.right = l + 'px';
+ }
+ }else{
+ ds.left = l + 'px';
+ hs.left = l + 'px';
+ }
+ ds.top = 0 + 'px';
+ hs.top = 0;
+ };
+ // for views left of the client
+ //BiDi TODO: The left and right should not appear in BIDI environment. Should be replaced with
+ //leading and tailing concept.
+ for(i=0; (v=this.views[i])&&(i<c); i++){
+ // get width
+ vw = this.getViewWidth(i);
+ // process boxes
+ v.setSize(vw, 0);
+ setPosition(v, l);
+ if(v.headerContentNode && v.headerContentNode.firstChild){
+ vw = v.getColumnsWidth()+v.getScrollbarWidth();
+ }else{
+ vw = v.domNode.offsetWidth;
+ }
+ // update position
+ l += vw;
+ }
+ // next view (is the client, i++ == c)
+ i++;
+ // start from the right edge
+ var r = w;
+ // for views right of the client (iterated from the right)
+ for(var j=len-1; (v=this.views[j])&&(i<=j); j--){
+ // get width
+ vw = this.getViewWidth(j);
+ // set size
+ v.setSize(vw, 0);
+ // measure in pixels
+ vw = v.domNode.offsetWidth;
+ // update position
+ r -= vw;
+ // set position
+ setPosition(v, r);
+ }
+ if(c<len){
+ v = this.views[c];
+ // position the client box between left and right boxes
+ vw = Math.max(1, r-l);
+ // set size
+ v.setSize(vw + 'px', 0);
+ setPosition(v, l);
+ }
+ return l;
+ },
+
+ // rendering
+ renderRow: function(inRowIndex, inNodes, skipRenorm){
+ var rowNodes = [];
+ for(var i=0, v, n, rowNode; (v=this.views[i])&&(n=inNodes[i]); i++){
+ rowNode = v.renderRow(inRowIndex);
+ n.appendChild(rowNode);
+ rowNodes.push(rowNode);
+ }
+ if(!skipRenorm){
+ this.normalizeRowNodeHeights(rowNodes);
+ }
+ },
+
+ rowRemoved: function(inRowIndex){
+ this.onEach("rowRemoved", [ inRowIndex ]);
+ },
+
+ // updating
+ updateRow: function(inRowIndex, skipRenorm){
+ for(var i=0, v; v=this.views[i]; i++){
+ v.updateRow(inRowIndex);
+ }
+ if(!skipRenorm){
+ this.renormalizeRow(inRowIndex);
+ }
+ },
+
+ updateRowStyles: function(inRowIndex){
+ this.onEach("updateRowStyles", [ inRowIndex ]);
+ },
+
+ // scrolling
+ setScrollTop: function(inTop){
+ var top = inTop;
+ for(var i=0, v; v=this.views[i]; i++){
+ top = v.setScrollTop(inTop);
+ // Work around IE not firing scroll events that cause header offset
+ // issues to occur.
+ if(dojo.isIE && v.headerNode && v.scrollboxNode){
+ v.headerNode.scrollLeft = v.scrollboxNode.scrollLeft;
+ }
+ }
+ return top;
+ //this.onEach("setScrollTop", [ inTop ]);
+ },
+
+ getFirstScrollingView: function(){
+ // summary: Returns the first grid view with a scroll bar
+ for(var i=0, v; (v=this.views[i]); i++){
+ if(v.hasHScrollbar() || v.hasVScrollbar()){
+ return v;
+ }
+ }
+ return null;
+ }
+
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._RowManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._RowManager"] = true;
+dojo.provide("dojox.grid._RowManager");
+
+(function(){
+ var setStyleText = function(inNode, inStyleText){
+ if(inNode.style.cssText == undefined){
+ inNode.setAttribute("style", inStyleText);
+ }else{
+ inNode.style.cssText = inStyleText;
+ }
+ };
+
+ dojo.declare("dojox.grid._RowManager", null, {
+ // Stores information about grid rows. Owned by grid and used internally.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+ linesToEms: 2,
+ overRow: -2,
+ // styles
+ prepareStylingRow: function(inRowIndex, inRowNode){
+ return {
+ index: inRowIndex,
+ node: inRowNode,
+ odd: Boolean(inRowIndex&1),
+ selected: !!this.grid.selection.isSelected(inRowIndex),
+ over: this.isOver(inRowIndex),
+ customStyles: "",
+ customClasses: "dojoxGridRow"
+ };
+ },
+ styleRowNode: function(inRowIndex, inRowNode){
+ var row = this.prepareStylingRow(inRowIndex, inRowNode);
+ this.grid.onStyleRow(row);
+ this.applyStyles(row);
+ },
+ applyStyles: function(inRow){
+ var i = inRow;
+
+ i.node.className = i.customClasses;
+ var h = i.node.style.height;
+ setStyleText(i.node, i.customStyles + ';' + (i.node._style||''));
+ i.node.style.height = h;
+ },
+ updateStyles: function(inRowIndex){
+ this.grid.updateRowStyles(inRowIndex);
+ },
+ // states and events
+ setOverRow: function(inRowIndex){
+ var last = this.overRow;
+ this.overRow = inRowIndex;
+ if((last!=this.overRow)&&(dojo.isString(last) || last >= 0)){
+ this.updateStyles(last);
+ }
+ this.updateStyles(this.overRow);
+ },
+ isOver: function(inRowIndex){
+ return (this.overRow == inRowIndex && !dojo.hasClass(this.grid.domNode, "dojoxGridColumnResizing"));
+ }
+ });
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid._FocusManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._FocusManager"] = true;
+dojo.provide("dojox.grid._FocusManager");
+
+
+
+// focus management
+dojo.declare("dojox.grid._FocusManager", null, {
+ // summary:
+ // Controls grid cell focus. Owned by grid and used internally for focusing.
+ // Note: grid cell actually receives keyboard input only when cell is being edited.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ this.cell = null;
+ this.rowIndex = -1;
+ this._connects = [];
+ this._headerConnects = [];
+ this.headerMenu = this.grid.headerMenu;
+ this._connects.push(dojo.connect(this.grid.domNode, "onfocus", this, "doFocus"));
+ this._connects.push(dojo.connect(this.grid.domNode, "onblur", this, "doBlur"));
+ this._connects.push(dojo.connect(this.grid.domNode, "oncontextmenu", this, "doContextMenu"));
+ this._connects.push(dojo.connect(this.grid.lastFocusNode, "onfocus", this, "doLastNodeFocus"));
+ this._connects.push(dojo.connect(this.grid.lastFocusNode, "onblur", this, "doLastNodeBlur"));
+ this._connects.push(dojo.connect(this.grid,"_onFetchComplete", this, "_delayedCellFocus"));
+ this._connects.push(dojo.connect(this.grid,"postrender", this, "_delayedHeaderFocus"));
+ },
+ destroy: function(){
+ dojo.forEach(this._connects, dojo.disconnect);
+ dojo.forEach(this._headerConnects, dojo.disconnect);
+ delete this.grid;
+ delete this.cell;
+ },
+ _colHeadNode: null,
+ _colHeadFocusIdx: null,
+ _contextMenuBindNode: null,
+ tabbingOut: false,
+ focusClass: "dojoxGridCellFocus",
+ focusView: null,
+ initFocusView: function(){
+ this.focusView = this.grid.views.getFirstScrollingView() || this.focusView || this.grid.views.views[0];
+ this._initColumnHeaders();
+ },
+ isFocusCell: function(inCell, inRowIndex){
+ // summary:
+ // states if the given cell is focused
+ // inCell: object
+ // grid cell object
+ // inRowIndex: int
+ // grid row index
+ // returns:
+ // true of the given grid cell is focused
+ return (this.cell == inCell) && (this.rowIndex == inRowIndex);
+ },
+ isLastFocusCell: function(){
+ if(this.cell){
+ return (this.rowIndex == this.grid.rowCount-1) && (this.cell.index == this.grid.layout.cellCount-1);
+ }
+ return false;
+ },
+ isFirstFocusCell: function(){
+ if(this.cell){
+ return (this.rowIndex === 0) && (this.cell.index === 0);
+ }
+ return false;
+ },
+ isNoFocusCell: function(){
+ return (this.rowIndex < 0) || !this.cell;
+ },
+ isNavHeader: function(){
+ // summary:
+ // states whether currently navigating among column headers.
+ // returns:
+ // true if focus is on a column header; false otherwise.
+ return (!!this._colHeadNode);
+ },
+ getHeaderIndex: function(){
+ // summary:
+ // if one of the column headers currently has focus, return its index.
+ // returns:
+ // index of the focused column header, or -1 if none have focus.
+ if(this._colHeadNode){
+ return dojo.indexOf(this._findHeaderCells(), this._colHeadNode);
+ }else{
+ return -1;
+ }
+ },
+ _focusifyCellNode: function(inBork){
+ var n = this.cell && this.cell.getNode(this.rowIndex);
+ if(n){
+ dojo.toggleClass(n, this.focusClass, inBork);
+ if(inBork){
+ var sl = this.scrollIntoView();
+ try{
+ if(!this.grid.edit.isEditing()){
+ dojox.grid.util.fire(n, "focus");
+ if(sl){ this.cell.view.scrollboxNode.scrollLeft = sl; }
+ }
+ }catch(e){}
+ }
+ }
+ },
+ _delayedCellFocus: function(){
+ if(this.isNavHeader()||!this.grid._focused){
+ return;
+ }
+ var n = this.cell && this.cell.getNode(this.rowIndex);
+ if(n){
+ try{
+ if(!this.grid.edit.isEditing()){
+ dojo.toggleClass(n, this.focusClass, true);
+ this.blurHeader();
+ dojox.grid.util.fire(n, "focus");
+ }
+ }
+ catch(e){}
+ }
+ },
+ _delayedHeaderFocus: function(){
+ if(this.isNavHeader()){
+ this.focusHeader();
+ this.grid.domNode.focus();
+ }
+ },
+ _initColumnHeaders: function(){
+ dojo.forEach(this._headerConnects, dojo.disconnect);
+ this._headerConnects = [];
+ var headers = this._findHeaderCells();
+ for(var i = 0; i < headers.length; i++){
+ this._headerConnects.push(dojo.connect(headers[i], "onfocus", this, "doColHeaderFocus"));
+ this._headerConnects.push(dojo.connect(headers[i], "onblur", this, "doColHeaderBlur"));
+ }
+ },
+ _findHeaderCells: function(){
+ // This should be a one liner:
+ // dojo.query("th[tabindex=-1]", this.grid.viewsHeaderNode);
+ // But there is a bug in dojo.query() for IE -- see trac #7037.
+ var allHeads = dojo.query("th", this.grid.viewsHeaderNode);
+ var headers = [];
+ for (var i = 0; i < allHeads.length; i++){
+ var aHead = allHeads[i];
+ var hasTabIdx = dojo.hasAttr(aHead, "tabIndex");
+ var tabindex = dojo.attr(aHead, "tabIndex");
+ if (hasTabIdx && tabindex < 0) {
+ headers.push(aHead);
+ }
+ }
+ return headers;
+ },
+ _setActiveColHeader: function(/*Node*/colHeaderNode, /*Integer*/colFocusIdx, /*Integer*/ prevColFocusIdx){
+ //console.log("setActiveColHeader() - colHeaderNode:colFocusIdx:prevColFocusIdx = " + colHeaderNode + ":" + colFocusIdx + ":" + prevColFocusIdx);
+ dojo.attr(this.grid.domNode, "aria-activedescendant",colHeaderNode.id);
+ if (prevColFocusIdx != null && prevColFocusIdx >= 0 && prevColFocusIdx != colFocusIdx){
+ dojo.toggleClass(this._findHeaderCells()[prevColFocusIdx],this.focusClass,false);
+ }
+ dojo.toggleClass(colHeaderNode,this.focusClass, true);
+ this._colHeadNode = colHeaderNode;
+ this._colHeadFocusIdx = colFocusIdx;
+ this._scrollHeader(this._colHeadFocusIdx);
+ },
+ scrollIntoView: function(){
+ var info = (this.cell ? this._scrollInfo(this.cell) : null);
+ if(!info || !info.s){
+ return null;
+ }
+ var rt = this.grid.scroller.findScrollTop(this.rowIndex);
+ // place cell within horizontal view
+ if(info.n && info.sr){
+ if(info.n.offsetLeft + info.n.offsetWidth > info.sr.l + info.sr.w){
+ info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w;
+ }else if(info.n.offsetLeft < info.sr.l){
+ info.s.scrollLeft = info.n.offsetLeft;
+ }
+ }
+ // place cell within vertical view
+ if(info.r && info.sr){
+ if(rt + info.r.offsetHeight > info.sr.t + info.sr.h){
+ this.grid.setScrollTop(rt + info.r.offsetHeight - info.sr.h);
+ }else if(rt < info.sr.t){
+ this.grid.setScrollTop(rt);
+ }
+ }
+
+ return info.s.scrollLeft;
+ },
+ _scrollInfo: function(cell, domNode){
+ if(cell){
+ var cl = cell,
+ sbn = cl.view.scrollboxNode,
+ sbnr = {
+ w: sbn.clientWidth,
+ l: sbn.scrollLeft,
+ t: sbn.scrollTop,
+ h: sbn.clientHeight
+ },
+ rn = cl.view.getRowNode(this.rowIndex);
+ return {
+ c: cl,
+ s: sbn,
+ sr: sbnr,
+ n: (domNode ? domNode : cell.getNode(this.rowIndex)),
+ r: rn
+ };
+ }
+ return null;
+ },
+ _scrollHeader: function(currentIdx){
+ var info = null;
+ if(this._colHeadNode){
+ var cell = this.grid.getCell(currentIdx);
+ info = this._scrollInfo(cell, cell.getNode(0));
+ }
+ if(info && info.s && info.sr && info.n){
+ // scroll horizontally as needed.
+ var scroll = info.sr.l + info.sr.w;
+ if(info.n.offsetLeft + info.n.offsetWidth > scroll){
+ info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w;
+ }else if(info.n.offsetLeft < info.sr.l){
+ info.s.scrollLeft = info.n.offsetLeft;
+ }else if(dojo.isIE <= 7 && cell && cell.view.headerNode){
+ // Trac 7158: scroll dojoxGridHeader for IE7 and lower
+ cell.view.headerNode.scrollLeft = info.s.scrollLeft;
+ }
+ }
+ },
+ _isHeaderHidden: function(){
+ // summary:
+ // determine if the grid headers are hidden
+ // relies on documented technique of setting .dojoxGridHeader { display:none; }
+ // returns: Boolean
+ // true if headers are hidden
+ // false if headers are not hidden
+
+ var curView = this.focusView;
+ if (!curView){
+ // find one so we can determine if headers are hidden
+ // there is no focusView after adding items to empty grid (test_data_grid_empty.html)
+ for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) {
+ if(cView.headerNode ){
+ curView=cView;
+ break;
+ }
+ }
+ }
+ return (curView && dojo.getComputedStyle(curView.headerNode).display == "none");
+ },
+ colSizeAdjust: function (e, colIdx, delta){ // adjust the column specified by colIdx by the specified delta px
+ var headers = this._findHeaderCells();
+ var view = this.focusView;
+ if (!view) {
+ for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) {
+ // find first view with a tableMap in order to work with empty grid
+ if(cView.header.tableMap.map ){
+ view=cView;
+ break;
+ }
+ }
+ }
+ var curHeader = headers[colIdx];
+ if (!view || (colIdx == headers.length-1 && colIdx === 0)){
+ return; // can't adjust single col. grid
+ }
+ view.content.baseDecorateEvent(e);
+ // need to adjust event with header cell info since focus is no longer on header cell
+ e.cellNode = curHeader; //this.findCellTarget(e.target, e.rowNode);
+ e.cellIndex = view.content.getCellNodeIndex(e.cellNode);
+ e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null);
+ if (view.header.canResize(e)){
+ var deltaObj = {
+ l: delta
+ };
+ var drag = view.header.colResizeSetup(e,false);
+ view.header.doResizeColumn(drag, null, deltaObj);
+ view.update();
+ }
+ },
+ styleRow: function(inRow){
+ return;
+ },
+ setFocusIndex: function(inRowIndex, inCellIndex){
+ // summary:
+ // focuses the given grid cell
+ // inRowIndex: int
+ // grid row index
+ // inCellIndex: int
+ // grid cell index
+ this.setFocusCell(this.grid.getCell(inCellIndex), inRowIndex);
+ },
+ setFocusCell: function(inCell, inRowIndex){
+ // summary:
+ // focuses the given grid cell
+ // inCell: object
+ // grid cell object
+ // inRowIndex: int
+ // grid row index
+ if(inCell && !this.isFocusCell(inCell, inRowIndex)){
+ this.tabbingOut = false;
+ if (this._colHeadNode){
+ this.blurHeader();
+ }
+ this._colHeadNode = this._colHeadFocusIdx = null;
+ this.focusGridView();
+ this._focusifyCellNode(false);
+ this.cell = inCell;
+ this.rowIndex = inRowIndex;
+ this._focusifyCellNode(true);
+ }
+ // even if this cell isFocusCell, the document focus may need to be rejiggered
+ // call opera on delay to prevent keypress from altering focus
+ if(dojo.isOpera){
+ setTimeout(dojo.hitch(this.grid, 'onCellFocus', this.cell, this.rowIndex), 1);
+ }else{
+ this.grid.onCellFocus(this.cell, this.rowIndex);
+ }
+ },
+ next: function(){
+ // summary:
+ // focus next grid cell
+ if(this.cell){
+ var row=this.rowIndex, col=this.cell.index+1, cc=this.grid.layout.cellCount-1, rc=this.grid.rowCount-1;
+ if(col > cc){
+ col = 0;
+ row++;
+ }
+ if(row > rc){
+ col = cc;
+ row = rc;
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var nextCell = this.grid.getCell(col);
+ if (!this.isLastFocusCell() && (!nextCell.editable ||
+ this.grid.canEdit && !this.grid.canEdit(nextCell, row))){
+ this.cell=nextCell;
+ this.rowIndex=row;
+ this.next();
+ return;
+ }
+ }
+ this.setFocusIndex(row, col);
+ }
+ },
+ previous: function(){
+ // summary:
+ // focus previous grid cell
+ if(this.cell){
+ var row=(this.rowIndex || 0), col=(this.cell.index || 0) - 1;
+ if(col < 0){
+ col = this.grid.layout.cellCount-1;
+ row--;
+ }
+ if(row < 0){
+ row = 0;
+ col = 0;
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var prevCell = this.grid.getCell(col);
+ if (!this.isFirstFocusCell() && !prevCell.editable){
+ this.cell=prevCell;
+ this.rowIndex=row;
+ this.previous();
+ return;
+ }
+ }
+ this.setFocusIndex(row, col);
+ }
+ },
+ move: function(inRowDelta, inColDelta) {
+ // summary:
+ // focus grid cell or simulate focus to column header based on position relative to current focus
+ // inRowDelta: int
+ // vertical distance from current focus
+ // inColDelta: int
+ // horizontal distance from current focus
+
+ var colDir = inColDelta < 0 ? -1 : 1;
+ // Handle column headers.
+ if(this.isNavHeader()){
+ var headers = this._findHeaderCells();
+ var savedIdx = currentIdx = dojo.indexOf(headers, this._colHeadNode);
+ currentIdx += inColDelta;
+ while(currentIdx >=0 && currentIdx < headers.length && headers[currentIdx].style.display == "none"){
+ // skip over hidden column headers
+ currentIdx += colDir;
+ }
+ if((currentIdx >= 0) && (currentIdx < headers.length)){
+ this._setActiveColHeader(headers[currentIdx],currentIdx, savedIdx);
+ }
+ }else{
+ if(this.cell){
+ // Handle grid proper.
+ var sc = this.grid.scroller,
+ r = this.rowIndex,
+ rc = this.grid.rowCount-1,
+ row = Math.min(rc, Math.max(0, r+inRowDelta));
+ if(inRowDelta){
+ if(inRowDelta>0){
+ if(row > sc.getLastPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r));
+ }
+ }else if(inRowDelta<0){
+ if(row <= sc.getPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row));
+ }
+ }
+ }
+ var cc = this.grid.layout.cellCount-1,
+ i = this.cell.index,
+ col = Math.min(cc, Math.max(0, i+inColDelta));
+ var cell = this.grid.getCell(col);
+ while(col>=0 && col < cc && cell && cell.hidden === true){
+ // skip hidden cells
+ col += colDir;
+ cell = this.grid.getCell(col);
+ }
+ if (!cell || cell.hidden === true){
+ // don't change col if would move to hidden
+ col = i;
+ }
+ this.setFocusIndex(row, col);
+ if(inRowDelta){
+ this.grid.updateRow(r);
+ }
+ }
+ }
+ },
+ previousKey: function(e){
+ if(this.grid.edit.isEditing()){
+ dojo.stopEvent(e);
+ this.previous();
+ }else if(!this.isNavHeader() && !this._isHeaderHidden()) {
+ this.grid.domNode.focus(); // will call doFocus and set focus into header.
+ dojo.stopEvent(e);
+ }else{
+ this.tabOut(this.grid.domNode);
+ if (this._colHeadFocusIdx != null) { // clear grid header focus
+ dojo.toggleClass(this._findHeaderCells()[this._colHeadFocusIdx], this.focusClass, false);
+ this._colHeadFocusIdx = null;
+ }
+ this._focusifyCellNode(false);
+ }
+ },
+ nextKey: function(e) {
+ var isEmpty = (this.grid.rowCount === 0);
+ if(e.target === this.grid.domNode && this._colHeadFocusIdx == null){
+ this.focusHeader();
+ dojo.stopEvent(e);
+ }else if(this.isNavHeader()){
+ // if tabbing from col header, then go to grid proper.
+ this.blurHeader();
+ if(!this.findAndFocusGridCell()){
+ this.tabOut(this.grid.lastFocusNode);
+ }
+ this._colHeadNode = this._colHeadFocusIdx= null;
+ }else if(this.grid.edit.isEditing()){
+ dojo.stopEvent(e);
+ this.next();
+ }else{
+ this.tabOut(this.grid.lastFocusNode);
+ }
+ },
+ tabOut: function(inFocusNode){
+ this.tabbingOut = true;
+ inFocusNode.focus();
+ },
+ focusGridView: function(){
+ dojox.grid.util.fire(this.focusView, "focus");
+ },
+ focusGrid: function(inSkipFocusCell){
+ this.focusGridView();
+ this._focusifyCellNode(true);
+ },
+ findAndFocusGridCell: function(){
+ // summary:
+ // find the first focusable grid cell
+ // returns: Boolean
+ // true if focus was set to a cell
+ // false if no cell found to set focus onto
+
+ var didFocus = true;
+ var isEmpty = (this.grid.rowCount === 0); // If grid is empty this.grid.rowCount == 0
+ if (this.isNoFocusCell() && !isEmpty){
+ var cellIdx = 0;
+ var cell = this.grid.getCell(cellIdx);
+ if (cell.hidden) {
+ // if first cell isn't visible, use _colHeadFocusIdx
+ // could also use a while loop to find first visible cell - not sure that is worth it
+ cellIdx = this.isNavHeader() ? this._colHeadFocusIdx : 0;
+ }
+ this.setFocusIndex(0, cellIdx);
+ }
+ else if (this.cell && !isEmpty){
+ if (this.focusView && !this.focusView.rowNodes[this.rowIndex]){
+ // if rowNode for current index is undefined (likely as a result of a sort and because of #7304)
+ // scroll to that row
+ this.grid.scrollToRow(this.rowIndex);
+ }
+ this.focusGrid();
+ }else {
+ didFocus = false;
+ }
+ this._colHeadNode = this._colHeadFocusIdx= null;
+ return didFocus;
+ },
+ focusHeader: function(){
+ var headerNodes = this._findHeaderCells();
+ var saveColHeadFocusIdx = this._colHeadFocusIdx;
+ if (this._isHeaderHidden()){
+ // grid header is hidden, focus a cell
+ this.findAndFocusGridCell();
+ }
+ else if (!this._colHeadFocusIdx) {
+ if (this.isNoFocusCell()) {
+ this._colHeadFocusIdx = 0;
+ }
+ else {
+ this._colHeadFocusIdx = this.cell.index;
+ }
+ }
+ this._colHeadNode = headerNodes[this._colHeadFocusIdx];
+ while(this._colHeadNode && this._colHeadFocusIdx >=0 && this._colHeadFocusIdx < headerNodes.length &&
+ this._colHeadNode.style.display == "none"){
+ // skip over hidden column headers
+ this._colHeadFocusIdx++;
+ this._colHeadNode = headerNodes[this._colHeadFocusIdx];
+ }
+ if(this._colHeadNode && this._colHeadNode.style.display != "none"){
+ // Column header cells know longer receive actual focus. So, for keyboard invocation of
+ // contextMenu to work, the contextMenu must be bound to the grid.domNode rather than the viewsHeaderNode.
+ // unbind the contextmenu from the viewsHeaderNode and to the grid when header cells are active. Reset
+ // the binding back to the viewsHeaderNode when header cells are no longer acive (in blurHeader) #10483
+ if (this.headerMenu && this._contextMenuBindNode != this.grid.domNode){
+ this.headerMenu.unBindDomNode(this.grid.viewsHeaderNode);
+ this.headerMenu.bindDomNode(this.grid.domNode);
+ this._contextMenuBindNode = this.grid.domNode;
+ }
+ this._setActiveColHeader(this._colHeadNode, this._colHeadFocusIdx, saveColHeadFocusIdx);
+ this._scrollHeader(this._colHeadFocusIdx);
+ this._focusifyCellNode(false);
+ }else {
+ // all col head nodes are hidden - focus the grid
+ this.findAndFocusGridCell();
+ }
+ },
+ blurHeader: function(){
+ dojo.removeClass(this._colHeadNode, this.focusClass);
+ dojo.removeAttr(this.grid.domNode,"aria-activedescendant");
+ // reset contextMenu onto viewsHeaderNode so right mouse on header will invoke (see focusHeader)
+ if (this.headerMenu && this._contextMenuBindNode == this.grid.domNode) {
+ var viewsHeader = this.grid.viewsHeaderNode;
+ this.headerMenu.unBindDomNode(this.grid.domNode);
+ this.headerMenu.bindDomNode(viewsHeader);
+ this._contextMenuBindNode = viewsHeader;
+ }
+ },
+ doFocus: function(e){
+ // trap focus only for grid dom node
+ if(e && e.target != e.currentTarget){
+ dojo.stopEvent(e);
+ return;
+ }
+ // do not focus for scrolling if grid is about to blur
+ if(!this.tabbingOut){
+ this.focusHeader();
+ }
+ this.tabbingOut = false;
+ dojo.stopEvent(e);
+ },
+ doBlur: function(e){
+ dojo.stopEvent(e); // FF2
+ },
+ doContextMenu: function(e){
+ //stop contextMenu event if no header Menu to prevent default/browser contextMenu
+ if (!this.headerMenu){
+ dojo.stopEvent(e);
+ }
+ },
+ doLastNodeFocus: function(e){
+ if (this.tabbingOut){
+ this._focusifyCellNode(false);
+ }else if(this.grid.rowCount >0){
+ if (this.isNoFocusCell()){
+ this.setFocusIndex(0,0);
+ }
+ this._focusifyCellNode(true);
+ }else {
+ this.focusHeader();
+ }
+ this.tabbingOut = false;
+ dojo.stopEvent(e); // FF2
+ },
+ doLastNodeBlur: function(e){
+ dojo.stopEvent(e); // FF2
+ },
+ doColHeaderFocus: function(e){
+ this._setActiveColHeader(e.target,dojo.attr(e.target, "idx"),this._colHeadFocusIdx);
+ this._scrollHeader(this.getHeaderIndex());
+ dojo.stopEvent(e);
+ },
+ doColHeaderBlur: function(e){
+ dojo.toggleClass(e.target, this.focusClass, false);
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._EditManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._EditManager"] = true;
+dojo.provide("dojox.grid._EditManager");
+
+
+
+dojo.declare("dojox.grid._EditManager", null, {
+ // summary:
+ // Controls grid cell editing process. Owned by grid and used internally for editing.
+ constructor: function(inGrid){
+ // inGrid: dojox.Grid
+ // The dojox.Grid this editor should be attached to
+ this.grid = inGrid;
+ if(dojo.isIE){
+ this.connections = [dojo.connect(document.body, "onfocus", dojo.hitch(this, "_boomerangFocus"))];
+ }else{
+ this.connections = [dojo.connect(this.grid, 'onBlur', this, 'apply')];
+ }
+ },
+
+ info: {},
+
+ destroy: function(){
+ dojo.forEach(this.connections,dojo.disconnect);
+ },
+
+ cellFocus: function(inCell, inRowIndex){
+ // summary:
+ // Invoke editing when cell is focused
+ // inCell: cell object
+ // Grid cell object
+ // inRowIndex: Integer
+ // Grid row index
+ if(this.grid.singleClickEdit || this.isEditRow(inRowIndex)){
+ // if same row or quick editing, edit
+ this.setEditCell(inCell, inRowIndex);
+ }else{
+ // otherwise, apply any pending row edits
+ this.apply();
+ }
+ // if dynamic or static editing...
+ if(this.isEditing() || (inCell && inCell.editable && inCell.alwaysEditing)){
+ // let the editor focus itself as needed
+ this._focusEditor(inCell, inRowIndex);
+ }
+ },
+
+ rowClick: function(e){
+ if(this.isEditing() && !this.isEditRow(e.rowIndex)){
+ this.apply();
+ }
+ },
+
+ styleRow: function(inRow){
+ if(inRow.index == this.info.rowIndex){
+ inRow.customClasses += ' dojoxGridRowEditing';
+ }
+ },
+
+ dispatchEvent: function(e){
+ var c = e.cell, ed = (c && c["editable"]) ? c : 0;
+ return ed && ed.dispatchEvent(e.dispatch, e);
+ },
+
+ // Editing
+ isEditing: function(){
+ // summary:
+ // Indicates editing state of the grid.
+ // returns: Boolean
+ // True if grid is actively editing
+ return this.info.rowIndex !== undefined;
+ },
+
+ isEditCell: function(inRowIndex, inCellIndex){
+ // summary:
+ // Indicates if the given cell is being edited.
+ // inRowIndex: Integer
+ // Grid row index
+ // inCellIndex: Integer
+ // Grid cell index
+ // returns: Boolean
+ // True if given cell is being edited
+ return (this.info.rowIndex === inRowIndex) && (this.info.cell.index == inCellIndex);
+ },
+
+ isEditRow: function(inRowIndex){
+ // summary:
+ // Indicates if the given row is being edited.
+ // inRowIndex: Integer
+ // Grid row index
+ // returns: Boolean
+ // True if given row is being edited
+ return this.info.rowIndex === inRowIndex;
+ },
+
+ setEditCell: function(inCell, inRowIndex){
+ // summary:
+ // Set the given cell to be edited
+ // inRowIndex: Integer
+ // Grid row index
+ // inCell: Object
+ // Grid cell object
+ if(!this.isEditCell(inRowIndex, inCell.index) && this.grid.canEdit && this.grid.canEdit(inCell, inRowIndex)){
+ this.start(inCell, inRowIndex, this.isEditRow(inRowIndex) || inCell.editable);
+ }
+ },
+
+ _focusEditor: function(inCell, inRowIndex){
+ dojox.grid.util.fire(inCell, "focus", [inRowIndex]);
+ },
+
+ focusEditor: function(){
+ if(this.isEditing()){
+ this._focusEditor(this.info.cell, this.info.rowIndex);
+ }
+ },
+
+ // implement fix for focus boomerang effect on IE
+ _boomerangWindow: 500,
+ _shouldCatchBoomerang: function(){
+ return this._catchBoomerang > new Date().getTime();
+ },
+ _boomerangFocus: function(){
+ //console.log("_boomerangFocus");
+ if(this._shouldCatchBoomerang()){
+ // make sure we don't utterly lose focus
+ this.grid.focus.focusGrid();
+ // let the editor focus itself as needed
+ this.focusEditor();
+ // only catch once
+ this._catchBoomerang = 0;
+ }
+ },
+ _doCatchBoomerang: function(){
+ // give ourselves a few ms to boomerang IE focus effects
+ if(dojo.isIE){this._catchBoomerang = new Date().getTime() + this._boomerangWindow;}
+ },
+ // end boomerang fix API
+
+ start: function(inCell, inRowIndex, inEditing){
+ this.grid.beginUpdate();
+ this.editorApply();
+ if(this.isEditing() && !this.isEditRow(inRowIndex)){
+ this.applyRowEdit();
+ this.grid.updateRow(inRowIndex);
+ }
+ if(inEditing){
+ this.info = { cell: inCell, rowIndex: inRowIndex };
+ this.grid.doStartEdit(inCell, inRowIndex);
+ this.grid.updateRow(inRowIndex);
+ }else{
+ this.info = {};
+ }
+ this.grid.endUpdate();
+ // make sure we don't utterly lose focus
+ this.grid.focus.focusGrid();
+ // let the editor focus itself as needed
+ this._focusEditor(inCell, inRowIndex);
+ // give ourselves a few ms to boomerang IE focus effects
+ this._doCatchBoomerang();
+ },
+
+ _editorDo: function(inMethod){
+ var c = this.info.cell;
+ //c && c.editor && c.editor[inMethod](c, this.info.rowIndex);
+ if(c && c.editable){
+ c[inMethod](this.info.rowIndex);
+ }
+ },
+
+ editorApply: function(){
+ this._editorDo("apply");
+ },
+
+ editorCancel: function(){
+ this._editorDo("cancel");
+ },
+
+ applyCellEdit: function(inValue, inCell, inRowIndex){
+ if(this.grid.canEdit(inCell, inRowIndex)){
+ this.grid.doApplyCellEdit(inValue, inRowIndex, inCell.field);
+ }
+ },
+
+ applyRowEdit: function(){
+ this.grid.doApplyEdit(this.info.rowIndex, this.info.cell.field);
+ },
+
+ apply: function(){
+ // summary:
+ // Apply a grid edit
+ if(this.isEditing()){
+ this.grid.beginUpdate();
+ this.editorApply();
+ this.applyRowEdit();
+ this.info = {};
+ this.grid.endUpdate();
+ this.grid.focus.focusGrid();
+ this._doCatchBoomerang();
+ }
+ },
+
+ cancel: function(){
+ // summary:
+ // Cancel a grid edit
+ if(this.isEditing()){
+ this.grid.beginUpdate();
+ this.editorCancel();
+ this.info = {};
+ this.grid.endUpdate();
+ this.grid.focus.focusGrid();
+ this._doCatchBoomerang();
+ }
+ },
+
+ save: function(inRowIndex, inView){
+ // summary:
+ // Save the grid editing state
+ // inRowIndex: Integer
+ // Grid row index
+ // inView: Object
+ // Grid view
+ var c = this.info.cell;
+ if(this.isEditRow(inRowIndex) && (!inView || c.view==inView) && c.editable){
+ c.save(c, this.info.rowIndex);
+ }
+ },
+
+ restore: function(inView, inRowIndex){
+ // summary:
+ // Restores the grid editing state
+ // inRowIndex: Integer
+ // Grid row index
+ // inView: Object
+ // Grid view
+ var c = this.info.cell;
+ if(this.isEditRow(inRowIndex) && c.view == inView && c.editable){
+ c.restore(c, this.info.rowIndex);
+ }
+ }
+});
+
+}
+
+if(!dojo._hasResource['dojox.grid.Selection']){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource['dojox.grid.Selection'] = true;
+dojo.provide('dojox.grid.Selection');
+
+dojo.declare("dojox.grid.Selection", null, {
+ // summary:
+ // Manages row selection for grid. Owned by grid and used internally
+ // for selection. Override to implement custom selection.
+
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ this.selected = [];
+
+ this.setMode(inGrid.selectionMode);
+ },
+
+ mode: 'extended',
+
+ selected: null,
+ updating: 0,
+ selectedIndex: -1,
+
+ setMode: function(mode){
+ if(this.selected.length){
+ this.deselectAll();
+ }
+ if(mode != 'extended' && mode != 'multiple' && mode != 'single' && mode != 'none'){
+ this.mode = 'extended';
+ }else{
+ this.mode = mode;
+ }
+ },
+
+ onCanSelect: function(inIndex){
+ return this.grid.onCanSelect(inIndex);
+ },
+
+ onCanDeselect: function(inIndex){
+ return this.grid.onCanDeselect(inIndex);
+ },
+
+ onSelected: function(inIndex){
+ },
+
+ onDeselected: function(inIndex){
+ },
+
+ //onSetSelected: function(inIndex, inSelect) { };
+ onChanging: function(){
+ },
+
+ onChanged: function(){
+ },
+
+ isSelected: function(inIndex){
+ if(this.mode == 'none'){
+ return false;
+ }
+ return this.selected[inIndex];
+ },
+
+ getFirstSelected: function(){
+ if(!this.selected.length||this.mode == 'none'){ return -1; }
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ getNextSelected: function(inPrev){
+ if(this.mode == 'none'){ return -1; }
+ for(var i=inPrev+1, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ getSelected: function(){
+ var result = [];
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ result.push(i);
+ }
+ }
+ return result;
+ },
+
+ getSelectedCount: function(){
+ var c = 0;
+ for(var i=0; i<this.selected.length; i++){
+ if(this.selected[i]){
+ c++;
+ }
+ }
+ return c;
+ },
+
+ _beginUpdate: function(){
+ if(this.updating === 0){
+ this.onChanging();
+ }
+ this.updating++;
+ },
+
+ _endUpdate: function(){
+ this.updating--;
+ if(this.updating === 0){
+ this.onChanged();
+ }
+ },
+
+ select: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(this.mode != 'multiple'){
+ this.deselectAll(inIndex);
+ this.addToSelection(inIndex);
+ }else{
+ this.toggleSelect(inIndex);
+ }
+ },
+
+ addToSelection: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(dojo.isArray(inIndex)){
+ dojo.forEach(inIndex, this.addToSelection, this);
+ return;
+ }
+ inIndex = Number(inIndex);
+ if(this.selected[inIndex]){
+ this.selectedIndex = inIndex;
+ }else{
+ if(this.onCanSelect(inIndex) !== false){
+ this.selectedIndex = inIndex;
+ var rowNode = this.grid.getRowNode(inIndex);
+ if(rowNode){
+ dojo.attr(rowNode,"aria-selected","true");
+ }
+ this._beginUpdate();
+ this.selected[inIndex] = true;
+ //this.grid.onSelected(inIndex);
+ this.onSelected(inIndex);
+ //this.onSetSelected(inIndex, true);
+ this._endUpdate();
+ }
+ }
+ },
+
+ deselect: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(dojo.isArray(inIndex)){
+ dojo.forEach(inIndex, this.deselect, this);
+ return;
+ }
+ inIndex = Number(inIndex);
+ if(this.selectedIndex == inIndex){
+ this.selectedIndex = -1;
+ }
+ if(this.selected[inIndex]){
+ if(this.onCanDeselect(inIndex) === false){
+ return;
+ }
+ var rowNode = this.grid.getRowNode(inIndex);
+ if(rowNode){
+ dojo.attr(rowNode,"aria-selected","false");
+ }
+ this._beginUpdate();
+ delete this.selected[inIndex];
+ //this.grid.onDeselected(inIndex);
+ this.onDeselected(inIndex);
+ //this.onSetSelected(inIndex, false);
+ this._endUpdate();
+ }
+ },
+
+ setSelected: function(inIndex, inSelect){
+ this[(inSelect ? 'addToSelection' : 'deselect')](inIndex);
+ },
+
+ toggleSelect: function(inIndex){
+ if(dojo.isArray(inIndex)){
+ dojo.forEach(inIndex, this.toggleSelect, this);
+ return;
+ }
+ this.setSelected(inIndex, !this.selected[inIndex]);
+ },
+
+ _range: function(inFrom, inTo, func){
+ var s = (inFrom >= 0 ? inFrom : inTo), e = inTo;
+ if(s > e){
+ e = s;
+ s = inTo;
+ }
+ for(var i=s; i<=e; i++){
+ func(i);
+ }
+ },
+
+ selectRange: function(inFrom, inTo){
+ this._range(inFrom, inTo, dojo.hitch(this, "addToSelection"));
+ },
+
+ deselectRange: function(inFrom, inTo){
+ this._range(inFrom, inTo, dojo.hitch(this, "deselect"));
+ },
+
+ insert: function(inIndex){
+ this.selected.splice(inIndex, 0, false);
+ if(this.selectedIndex >= inIndex){
+ this.selectedIndex++;
+ }
+ },
+
+ remove: function(inIndex){
+ this.selected.splice(inIndex, 1);
+ if(this.selectedIndex >= inIndex){
+ this.selectedIndex--;
+ }
+ },
+
+ deselectAll: function(inExcept){
+ for(var i in this.selected){
+ if((i!=inExcept)&&(this.selected[i]===true)){
+ this.deselect(i);
+ }
+ }
+ },
+
+ clickSelect: function(inIndex, inCtrlKey, inShiftKey){
+ if(this.mode == 'none'){ return; }
+ this._beginUpdate();
+ if(this.mode != 'extended'){
+ this.select(inIndex);
+ }else{
+ var lastSelected = this.selectedIndex;
+ if(!inCtrlKey){
+ this.deselectAll(inIndex);
+ }
+ if(inShiftKey){
+ this.selectRange(lastSelected, inIndex);
+ }else if(inCtrlKey){
+ this.toggleSelect(inIndex);
+ }else{
+ this.addToSelection(inIndex);
+ }
+ }
+ this._endUpdate();
+ },
+
+ clickSelectEvent: function(e){
+ this.clickSelect(e.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ },
+
+ clear: function(){
+ this._beginUpdate();
+ this.deselectAll();
+ this._endUpdate();
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._Events"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Events"] = true;
+dojo.provide("dojox.grid._Events");
+
+dojo.declare("dojox.grid._Events", null, {
+ // summary:
+ // _Grid mixin that provides default implementations for grid events.
+ // description:
+ // Default synthetic events dispatched for _Grid. dojo.connect to events to
+ // retain default implementation or override them for custom handling.
+
+ // cellOverClass: String
+ // css class to apply to grid cells over which the cursor is placed.
+ cellOverClass: "dojoxGridCellOver",
+
+ onKeyEvent: function(e){
+ // summary: top level handler for Key Events
+ this.dispatchKeyEvent(e);
+ },
+
+ onContentEvent: function(e){
+ // summary: Top level handler for Content events
+ this.dispatchContentEvent(e);
+ },
+
+ onHeaderEvent: function(e){
+ // summary: Top level handler for header events
+ this.dispatchHeaderEvent(e);
+ },
+
+ onStyleRow: function(inRow){
+ // summary:
+ // Perform row styling on a given row. Called whenever row styling is updated.
+ //
+ // inRow: Object
+ // Object containing row state information: selected, true if the row is selcted; over:
+ // true of the mouse is over the row; odd: true if the row is odd. Use customClasses and
+ // customStyles to control row css classes and styles; both properties are strings.
+ //
+ // example: onStyleRow({ selected: true, over:true, odd:false })
+ var i = inRow;
+ i.customClasses += (i.odd?" dojoxGridRowOdd":"") + (i.selected?" dojoxGridRowSelected":"") + (i.over?" dojoxGridRowOver":"");
+ this.focus.styleRow(inRow);
+ this.edit.styleRow(inRow);
+ },
+
+ onKeyDown: function(e){
+ // summary:
+ // Grid key event handler. By default enter begins editing and applies edits, escape cancels an edit,
+ // tab, shift-tab, and arrow keys move grid cell focus.
+ if(e.altKey || e.metaKey){
+ return;
+ }
+ var dk = dojo.keys;
+ var colIdx;
+ switch(e.keyCode){
+ case dk.ESCAPE:
+ this.edit.cancel();
+ break;
+ case dk.ENTER:
+ if(!this.edit.isEditing()){
+ colIdx = this.focus.getHeaderIndex();
+ if(colIdx >= 0) {
+ this.setSortIndex(colIdx);
+ break;
+ }else {
+ this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ }
+ dojo.stopEvent(e);
+ }
+ if(!e.shiftKey){
+ var isEditing = this.edit.isEditing();
+ this.edit.apply();
+ if(!isEditing){
+ this.edit.setEditCell(this.focus.cell, this.focus.rowIndex);
+ }
+ }
+ if (!this.edit.isEditing()){
+ var curView = this.focus.focusView || this.views.views[0]; //if no focusView than only one view
+ curView.content.decorateEvent(e);
+ this.onRowClick(e);
+ }
+ break;
+ case dk.SPACE:
+ if(!this.edit.isEditing()){
+ colIdx = this.focus.getHeaderIndex();
+ if(colIdx >= 0) {
+ this.setSortIndex(colIdx);
+ break;
+ }else {
+ this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ }
+ dojo.stopEvent(e);
+ }
+ break;
+ case dk.TAB:
+ this.focus[e.shiftKey ? 'previousKey' : 'nextKey'](e);
+ break;
+ case dk.LEFT_ARROW:
+ case dk.RIGHT_ARROW:
+ if(!this.edit.isEditing()){
+ var keyCode = e.keyCode; // IE seems to lose after stopEvent when modifier keys
+ dojo.stopEvent(e);
+ colIdx = this.focus.getHeaderIndex();
+ if (colIdx >= 0 && (e.shiftKey && e.ctrlKey)){
+ this.focus.colSizeAdjust(e, colIdx, (keyCode == dk.LEFT_ARROW ? -1 : 1)*5);
+ }
+ else{
+ var offset = (keyCode == dk.LEFT_ARROW) ? 1 : -1;
+ if(dojo._isBodyLtr()){ offset *= -1; }
+ this.focus.move(0, offset);
+ }
+ }
+ break;
+ case dk.UP_ARROW:
+ if(!this.edit.isEditing() && this.focus.rowIndex !== 0){
+ dojo.stopEvent(e);
+ this.focus.move(-1, 0);
+ }
+ break;
+ case dk.DOWN_ARROW:
+ if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){
+ dojo.stopEvent(e);
+ this.focus.move(1, 0);
+ }
+ break;
+ case dk.PAGE_UP:
+ if(!this.edit.isEditing() && this.focus.rowIndex !== 0){
+ dojo.stopEvent(e);
+ if(this.focus.rowIndex != this.scroller.firstVisibleRow+1){
+ this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex, 0);
+ }else{
+ this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1));
+ this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1, 0);
+ }
+ }
+ break;
+ case dk.PAGE_DOWN:
+ if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){
+ dojo.stopEvent(e);
+ if(this.focus.rowIndex != this.scroller.lastVisibleRow-1){
+ this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1, 0);
+ }else{
+ this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1));
+ this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1, 0);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ },
+
+ onMouseOver: function(e){
+ // summary:
+ // Event fired when mouse is over the grid.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseOver(e) : this.onCellMouseOver(e);
+ },
+
+ onMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of the grid.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseOut(e) : this.onCellMouseOut(e);
+ },
+
+ onMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down inside grid.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseDown(e) : this.onCellMouseDown(e);
+ },
+
+ onMouseOverRow: function(e){
+ // summary:
+ // Event fired when mouse is over any row (data or header).
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(!this.rows.isOver(e.rowIndex)){
+ this.rows.setOverRow(e.rowIndex);
+ e.rowIndex == -1 ? this.onHeaderMouseOver(e) : this.onRowMouseOver(e);
+ }
+ },
+ onMouseOutRow: function(e){
+ // summary:
+ // Event fired when mouse moves out of any row (data or header).
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(this.rows.isOver(-1)){
+ this.onHeaderMouseOut(e);
+ }else if(!this.rows.isOver(-2)){
+ this.rows.setOverRow(-2);
+ this.onRowMouseOut(e);
+ }
+ },
+
+ onMouseDownRow: function(e){
+ // summary:
+ // Event fired when mouse is down inside grid row
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ if(e.rowIndex != -1)
+ this.onRowMouseDown(e);
+ },
+
+ // cell events
+ onCellMouseOver: function(e){
+ // summary:
+ // Event fired when mouse is over a cell.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ dojo.addClass(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onCellMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ dojo.removeClass(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onCellMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down in a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onCellClick: function(e){
+ // summary:
+ // Event fired when a cell is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this._click[0] = this._click[1];
+ this._click[1] = e;
+ if(!this.edit.isEditCell(e.rowIndex, e.cellIndex)){
+ this.focus.setFocusCell(e.cell, e.rowIndex);
+ }
+ this.onRowClick(e);
+ },
+
+ onCellDblClick: function(e){
+ // summary:
+ // Event fired when a cell is double-clicked.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(this._click.length > 1 && dojo.isIE){
+ this.edit.setEditCell(this._click[1].cell, this._click[1].rowIndex);
+ }else if(this._click.length > 1 && this._click[0].rowIndex != this._click[1].rowIndex){
+ this.edit.setEditCell(this._click[0].cell, this._click[0].rowIndex);
+ }else{
+ this.edit.setEditCell(e.cell, e.rowIndex);
+ }
+ this.onRowDblClick(e);
+ },
+
+ onCellContextMenu: function(e){
+ // summary:
+ // Event fired when a cell context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onRowContextMenu(e);
+ },
+
+ onCellFocus: function(inCell, inRowIndex){
+ // summary:
+ // Event fired when a cell receives focus.
+ // inCell: Object
+ // Cell object containing properties of the grid column.
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.edit.cellFocus(inCell, inRowIndex);
+ },
+
+ // row events
+ onRowClick: function(e){
+ // summary:
+ // Event fired when a row is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.edit.rowClick(e);
+ this.selection.clickSelectEvent(e);
+ },
+
+ onRowDblClick: function(e){
+ // summary:
+ // Event fired when a row is double clicked.
+ // e: Event
+ // decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over a data row.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a data row.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down in a row.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowContextMenu: function(e){
+ // summary:
+ // Event fired when a row context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ dojo.stopEvent(e);
+ },
+
+ // header events
+ onHeaderMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over the grid header.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of the grid header.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ dojo.addClass(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onHeaderCellMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ dojo.removeClass(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onHeaderCellMouseDown: function(e) {
+ // summary:
+ // Event fired when mouse is down in a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderClick: function(e){
+ // summary:
+ // Event fired when the grid header is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellClick: function(e){
+ // summary:
+ // Event fired when a header cell is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.setSortIndex(e.cell.index);
+ this.onHeaderClick(e);
+ },
+
+ onHeaderDblClick: function(e){
+ // summary:
+ // Event fired when the grid header is double clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellDblClick: function(e){
+ // summary:
+ // Event fired when a header cell is double clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onHeaderDblClick(e);
+ },
+
+ onHeaderCellContextMenu: function(e){
+ // summary:
+ // Event fired when a header cell context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onHeaderContextMenu(e);
+ },
+
+ onHeaderContextMenu: function(e){
+ // summary:
+ // Event fired when the grid header context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(!this.headerMenu){
+ dojo.stopEvent(e);
+ }
+ },
+
+ // editing
+ onStartEdit: function(inCell, inRowIndex){
+ // summary:
+ // Event fired when editing is started for a given grid cell
+ // inCell: Object
+ // Cell object containing properties of the grid column.
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
+ // summary:
+ // Event fired when editing is applied for a given grid cell
+ // inValue: String
+ // Value from cell editor
+ // inRowIndex: Integer
+ // Index of the grid row
+ // inFieldIndex: Integer
+ // Index in the grid's data store
+ },
+
+ onCancelEdit: function(inRowIndex){
+ // summary:
+ // Event fired when editing is cancelled for a given grid cell
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onApplyEdit: function(inRowIndex){
+ // summary:
+ // Event fired when editing is applied for a given grid row
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onCanSelect: function(inRowIndex){
+ // summary:
+ // Event to determine if a grid row may be selected
+ // inRowIndex: Integer
+ // Index of the grid row
+ // returns: Boolean
+ // true if the row can be selected
+ return true;
+ },
+
+ onCanDeselect: function(inRowIndex){
+ // summary:
+ // Event to determine if a grid row may be deselected
+ // inRowIndex: Integer
+ // Index of the grid row
+ // returns: Boolean
+ // true if the row can be deselected
+ return true;
+ },
+
+ onSelected: function(inRowIndex){
+ // summary:
+ // Event fired when a grid row is selected
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.updateRowStyles(inRowIndex);
+ },
+
+ onDeselected: function(inRowIndex){
+ // summary:
+ // Event fired when a grid row is deselected
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.updateRowStyles(inRowIndex);
+ },
+
+ onSelectionChanged: function(){
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._Grid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Grid"] = true;
+dojo.provide("dojox.grid._Grid");
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+(function(){
+ // NOTE: this is for backwards compatibility with Dojo 1.3
+ if(!dojo.isCopyKey){
+ dojo.isCopyKey = dojo.dnd.getCopyKeyState;
+ }
+ /*=====
+ dojox.grid.__CellDef = function(){
+ // name: String?
+ // The text to use in the header of the grid for this cell.
+ // get: Function?
+ // function(rowIndex){} rowIndex is of type Integer. This
+ // function will be called when a cell requests data. Returns the
+ // unformatted data for the cell.
+ // value: String?
+ // If "get" is not specified, this is used as the data for the cell.
+ // defaultValue: String?
+ // If "get" and "value" aren't specified or if "get" returns an undefined
+ // value, this is used as the data for the cell. "formatter" is not run
+ // on this if "get" returns an undefined value.
+ // formatter: Function?
+ // function(data, rowIndex){} data is of type anything, rowIndex
+ // is of type Integer. This function will be called after the cell
+ // has its data but before it passes it back to the grid to render.
+ // Returns the formatted version of the cell's data.
+ // type: dojox.grid.cells._Base|Function?
+ // TODO
+ // editable: Boolean?
+ // Whether this cell should be editable or not.
+ // hidden: Boolean?
+ // If true, the cell will not be displayed.
+ // noresize: Boolean?
+ // If true, the cell will not be able to be resized.
+ // width: Integer|String?
+ // A CSS size. If it's an Integer, the width will be in em's.
+ // colSpan: Integer?
+ // How many columns to span this cell. Will not work in the first
+ // sub-row of cells.
+ // rowSpan: Integer?
+ // How many sub-rows to span this cell.
+ // styles: String?
+ // A string of styles to apply to both the header cell and main
+ // grid cells. Must end in a ';'.
+ // headerStyles: String?
+ // A string of styles to apply to just the header cell. Must end
+ // in a ';'
+ // cellStyles: String?
+ // A string of styles to apply to just the main grid cells. Must
+ // end in a ';'
+ // classes: String?
+ // A space separated list of classes to apply to both the header
+ // cell and the main grid cells.
+ // headerClasses: String?
+ // A space separated list of classes to apply to just the header
+ // cell.
+ // cellClasses: String?
+ // A space separated list of classes to apply to just the main
+ // grid cells.
+ // attrs: String?
+ // A space separated string of attribute='value' pairs to add to
+ // the header cell element and main grid cell elements.
+ this.name = name;
+ this.value = value;
+ this.get = get;
+ this.formatter = formatter;
+ this.type = type;
+ this.editable = editable;
+ this.hidden = hidden;
+ this.width = width;
+ this.colSpan = colSpan;
+ this.rowSpan = rowSpan;
+ this.styles = styles;
+ this.headerStyles = headerStyles;
+ this.cellStyles = cellStyles;
+ this.classes = classes;
+ this.headerClasses = headerClasses;
+ this.cellClasses = cellClasses;
+ this.attrs = attrs;
+ }
+ =====*/
+
+ /*=====
+ dojox.grid.__ViewDef = function(){
+ // noscroll: Boolean?
+ // If true, no scrollbars will be rendered without scrollbars.
+ // width: Integer|String?
+ // A CSS size. If it's an Integer, the width will be in em's. If
+ // "noscroll" is true, this value is ignored.
+ // cells: dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]?
+ // The structure of the cells within this grid.
+ // type: String?
+ // A string containing the constructor of a subclass of
+ // dojox.grid._View. If this is not specified, dojox.grid._View
+ // is used.
+ // defaultCell: dojox.grid.__CellDef?
+ // A cell definition with default values for all cells in this view. If
+ // a property is defined in a cell definition in the "cells" array and
+ // this property, the cell definition's property will override this
+ // property's property.
+ // onBeforeRow: Function?
+ // function(rowIndex, cells){} rowIndex is of type Integer, cells
+ // is of type Array[dojox.grid.__CellDef[]]. This function is called
+ // before each row of data is rendered. Before the header is
+ // rendered, rowIndex will be -1. "cells" is a reference to the
+ // internal structure of this view's cells so any changes you make to
+ // it will persist between calls.
+ // onAfterRow: Function?
+ // function(rowIndex, cells, rowNode){} rowIndex is of type Integer, cells
+ // is of type Array[dojox.grid.__CellDef[]], rowNode is of type DOMNode.
+ // This function is called after each row of data is rendered. After the
+ // header is rendered, rowIndex will be -1. "cells" is a reference to the
+ // internal structure of this view's cells so any changes you make to
+ // it will persist between calls.
+ this.noscroll = noscroll;
+ this.width = width;
+ this.cells = cells;
+ this.type = type;
+ this.defaultCell = defaultCell;
+ this.onBeforeRow = onBeforeRow;
+ this.onAfterRow = onAfterRow;
+ }
+ =====*/
+
+ dojo.declare('dojox.grid._Grid',
+ [ dijit._Widget, dijit._Templated, dojox.grid._Events ],
+ {
+ // summary:
+ // A grid widget with virtual scrolling, cell editing, complex rows,
+ // sorting, fixed columns, sizeable columns, etc.
+ //
+ // description:
+ // _Grid provides the full set of grid features without any
+ // direct connection to a data store.
+ //
+ // The grid exposes a get function for the grid, or optionally
+ // individual columns, to populate cell contents.
+ //
+ // The grid is rendered based on its structure, an object describing
+ // column and cell layout.
+ //
+ // example:
+ // A quick sample:
+ //
+ // define a get function
+ // | function get(inRowIndex){ // called in cell context
+ // | return [this.index, inRowIndex].join(', ');
+ // | }
+ //
+ // define the grid structure:
+ // | var structure = [ // array of view objects
+ // | { cells: [// array of rows, a row is an array of cells
+ // | [
+ // | { name: "Alpha", width: 6 },
+ // | { name: "Beta" },
+ // | { name: "Gamma", get: get }]
+ // | ]}
+ // | ];
+ //
+ // | <div id="grid"
+ // | rowCount="100" get="get"
+ // | structure="structure"
+ // | dojoType="dojox.grid._Grid"></div>
+
+ templateString:"<div hidefocus=\"hidefocus\" role=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\r\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" role=\"presentation\"></div>\r\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" role=\"presentation\"></div>\r\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\r\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\r\n</div>\r\n",
+
+ // classTag: String
+ // CSS class applied to the grid's domNode
+ classTag: 'dojoxGrid',
+
+ // settings
+ // rowCount: Integer
+ // Number of rows to display.
+ rowCount: 5,
+
+ // keepRows: Integer
+ // Number of rows to keep in the rendering cache.
+ keepRows: 75,
+
+ // rowsPerPage: Integer
+ // Number of rows to render at a time.
+ rowsPerPage: 25,
+
+ // autoWidth: Boolean
+ // If autoWidth is true, grid width is automatically set to fit the data.
+ autoWidth: false,
+
+ // initialWidth: String
+ // A css string to use to set our initial width (only used if autoWidth
+ // is true). The first rendering of the grid will be this width, any
+ // resizing of columns, etc will result in the grid switching to
+ // autoWidth mode. Note, this width will override any styling in a
+ // stylesheet or directly on the node.
+ initialWidth: "",
+
+ // autoHeight: Boolean|Integer
+ // If autoHeight is true, grid height is automatically set to fit the data.
+ // If it is an integer, the height will be automatically set to fit the data
+ // if there are fewer than that many rows - and the height will be set to show
+ // that many rows if there are more
+ autoHeight: '',
+
+ // rowHeight: Integer
+ // If rowHeight is set to a positive number, it will define the height of the rows
+ // in pixels. This can provide a significant performance advantage, since it
+ // eliminates the need to measure row sizes during rendering, which is one
+ // the primary bottlenecks in the DataGrid's performance.
+ rowHeight: 0,
+
+ // autoRender: Boolean
+ // If autoRender is true, grid will render itself after initialization.
+ autoRender: true,
+
+ // defaultHeight: String
+ // default height of the grid, measured in any valid css unit.
+ defaultHeight: '15em',
+
+ // height: String
+ // explicit height of the grid, measured in any valid css unit. This will be populated (and overridden)
+ // if the height: css attribute exists on the source node.
+ height: '',
+
+ // structure: dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]
+ // View layout defintion.
+ structure: null,
+
+ // elasticView: Integer
+ // Override defaults and make the indexed grid view elastic, thus filling available horizontal space.
+ elasticView: -1,
+
+ // singleClickEdit: boolean
+ // Single-click starts editing. Default is double-click
+ singleClickEdit: false,
+
+ // selectionMode: String
+ // Set the selection mode of grid's Selection. Value must be 'single', 'multiple',
+ // or 'extended'. Default is 'extended'.
+ selectionMode: 'extended',
+
+ // rowSelector: Boolean|String
+ // If set to true, will add a row selector view to this grid. If set to a CSS width, will add
+ // a row selector of that width to this grid.
+ rowSelector: '',
+
+ // columnReordering: Boolean
+ // If set to true, will add drag and drop reordering to views with one row of columns.
+ columnReordering: false,
+
+ // headerMenu: dijit.Menu
+ // If set to a dijit.Menu, will use this as a context menu for the grid headers.
+ headerMenu: null,
+
+ // placeholderLabel: String
+ // Label of placeholders to search for in the header menu to replace with column toggling
+ // menu items.
+ placeholderLabel: "GridColumns",
+
+ // selectable: Boolean
+ // Set to true if you want to be able to select the text within the grid.
+ selectable: false,
+
+ // Used to store the last two clicks, to ensure double-clicking occurs based on the intended row
+ _click: null,
+
+ // loadingMessage: String
+ // Message that shows while the grid is loading
+ loadingMessage: "<span class='dojoxGridLoading'>${loadingState}</span>",
+
+ // errorMessage: String
+ // Message that shows when the grid encounters an error loading
+ errorMessage: "<span class='dojoxGridError'>${errorState}</span>",
+
+ // noDataMessage: String
+ // Message that shows if the grid has no data - wrap it in a
+ // span with class 'dojoxGridNoData' if you want it to be
+ // styled similar to the loading and error messages
+ noDataMessage: "",
+
+ // escapeHTMLInData: Boolean
+ // This will escape HTML brackets from the data to prevent HTML from
+ // user-inputted data being rendered with may contain JavaScript and result in
+ // XSS attacks. This is true by default, and it is recommended that it remain
+ // true. Setting this to false will allow data to be displayed in the grid without
+ // filtering, and should be only used if it is known that the data won't contain
+ // malicious scripts. If HTML is needed in grid cells, it is recommended that
+ // you use the formatter function to generate the HTML (the output of
+ // formatter functions is not filtered, even with escapeHTMLInData set to true).
+ escapeHTMLInData: true,
+
+ // formatterScope: Object
+ // An object to execute format functions within. If not set, the
+ // format functions will execute within the scope of the cell that
+ // has a format function.
+ formatterScope: null,
+
+ // editable: boolean
+ // indicates if the grid contains editable cells, default is false
+ // set to true if editable cell encountered during rendering
+ editable: false,
+
+ // private
+ sortInfo: 0,
+ themeable: true,
+ _placeholders: null,
+
+ // _layoutClass: Object
+ // The class to use for our layout - can be overridden by grid subclasses
+ _layoutClass: dojox.grid._Layout,
+
+ // initialization
+ buildRendering: function(){
+ this.inherited(arguments);
+ if(!this.domNode.getAttribute('tabIndex')){
+ this.domNode.tabIndex = "0";
+ }
+ this.createScroller();
+ this.createLayout();
+ this.createViews();
+ this.createManagers();
+
+ this.createSelection();
+
+ this.connect(this.selection, "onSelected", "onSelected");
+ this.connect(this.selection, "onDeselected", "onDeselected");
+ this.connect(this.selection, "onChanged", "onSelectionChanged");
+
+ dojox.html.metrics.initOnFontResize();
+ this.connect(dojox.html.metrics, "onFontResize", "textSizeChanged");
+ dojox.grid.util.funnelEvents(this.domNode, this, 'doKeyEvent', dojox.grid.util.keyEvents);
+ if (this.selectionMode != "none") {
+ dojo.attr(this.domNode, "aria-multiselectable", this.selectionMode == "single" ? "false" : "true");
+ }
+
+ dojo.addClass(this.domNode, this.classTag);
+ if(!this.isLeftToRight()){
+ dojo.addClass(this.domNode, this.classTag+"Rtl");
+ }
+ },
+
+ postMixInProperties: function(){
+ this.inherited(arguments);
+ var messages = dojo.i18n.getLocalization("dijit", "loading", this.lang);
+ this.loadingMessage = dojo.string.substitute(this.loadingMessage, messages);
+ this.errorMessage = dojo.string.substitute(this.errorMessage, messages);
+ if(this.srcNodeRef && this.srcNodeRef.style.height){
+ this.height = this.srcNodeRef.style.height;
+ }
+ // Call this to update our autoheight to start out
+ this._setAutoHeightAttr(this.autoHeight, true);
+ this.lastScrollTop = this.scrollTop = 0;
+ },
+
+ postCreate: function(){
+ this._placeholders = [];
+ this._setHeaderMenuAttr(this.headerMenu);
+ this._setStructureAttr(this.structure);
+ this._click = [];
+ this.inherited(arguments);
+ if(this.domNode && this.autoWidth && this.initialWidth){
+ this.domNode.style.width = this.initialWidth;
+ }
+ if (this.domNode && !this.editable){
+ // default value for aria-readonly is false, set to true if grid is not editable
+ dojo.attr(this.domNode,"aria-readonly", "true");
+ }
+ },
+
+ destroy: function(){
+ this.domNode.onReveal = null;
+ this.domNode.onSizeChange = null;
+
+ // Fixes IE domNode leak
+ delete this._click;
+
+ this.edit.destroy();
+ delete this.edit;
+
+ this.views.destroyViews();
+ if(this.scroller){
+ this.scroller.destroy();
+ delete this.scroller;
+ }
+ if(this.focus){
+ this.focus.destroy();
+ delete this.focus;
+ }
+ if(this.headerMenu&&this._placeholders.length){
+ dojo.forEach(this._placeholders, function(p){ p.unReplace(true); });
+ this.headerMenu.unBindDomNode(this.viewsHeaderNode);
+ }
+ this.inherited(arguments);
+ },
+
+ _setAutoHeightAttr: function(ah, skipRender){
+ // Calculate our autoheight - turn it into a boolean or an integer
+ if(typeof ah == "string"){
+ if(!ah || ah == "false"){
+ ah = false;
+ }else if (ah == "true"){
+ ah = true;
+ }else{
+ ah = window.parseInt(ah, 10);
+ }
+ }
+ if(typeof ah == "number"){
+ if(isNaN(ah)){
+ ah = false;
+ }
+ // Autoheight must be at least 1, if it's a number. If it's
+ // less than 0, we'll take that to mean "all" rows (same as
+ // autoHeight=true - if it is equal to zero, we'll take that
+ // to mean autoHeight=false
+ if(ah < 0){
+ ah = true;
+ }else if (ah === 0){
+ ah = false;
+ }
+ }
+ this.autoHeight = ah;
+ if(typeof ah == "boolean"){
+ this._autoHeight = ah;
+ }else if(typeof ah == "number"){
+ this._autoHeight = (ah >= this.get('rowCount'));
+ }else{
+ this._autoHeight = false;
+ }
+ if(this._started && !skipRender){
+ this.render();
+ }
+ },
+
+ _getRowCountAttr: function(){
+ return this.updating && this.invalidated && this.invalidated.rowCount != undefined ?
+ this.invalidated.rowCount : this.rowCount;
+ },
+
+ textSizeChanged: function(){
+ this.render();
+ },
+
+ sizeChange: function(){
+ this.update();
+ },
+
+ createManagers: function(){
+ // summary:
+ // create grid managers for various tasks including rows, focus, selection, editing
+
+ // row manager
+ this.rows = new dojox.grid._RowManager(this);
+ // focus manager
+ this.focus = new dojox.grid._FocusManager(this);
+ // edit manager
+ this.edit = new dojox.grid._EditManager(this);
+ },
+
+ createSelection: function(){
+ // summary: Creates a new Grid selection manager.
+
+ // selection manager
+ this.selection = new dojox.grid.Selection(this);
+ },
+
+ createScroller: function(){
+ // summary: Creates a new virtual scroller
+ this.scroller = new dojox.grid._Scroller();
+ this.scroller.grid = this;
+ this.scroller.renderRow = dojo.hitch(this, "renderRow");
+ this.scroller.removeRow = dojo.hitch(this, "rowRemoved");
+ },
+
+ createLayout: function(){
+ // summary: Creates a new Grid layout
+ this.layout = new this._layoutClass(this);
+ this.connect(this.layout, "moveColumn", "onMoveColumn");
+ },
+
+ onMoveColumn: function(){
+ this.render();
+ },
+
+ onResizeColumn: function(/*int*/ cellIdx){
+ // Called when a column is resized.
+ },
+
+ // views
+ createViews: function(){
+ this.views = new dojox.grid._ViewManager(this);
+ this.views.createView = dojo.hitch(this, "createView");
+ },
+
+ createView: function(inClass, idx){
+ var c = dojo.getObject(inClass);
+ var view = new c({ grid: this, index: idx });
+ this.viewsNode.appendChild(view.domNode);
+ this.viewsHeaderNode.appendChild(view.headerNode);
+ this.views.addView(view);
+ dojo.attr(this.domNode, "align", dojo._isBodyLtr() ? 'left' : 'right');
+ return view;
+ },
+
+ buildViews: function(){
+ for(var i=0, vs; (vs=this.layout.structure[i]); i++){
+ this.createView(vs.type || dojox._scopeName + ".grid._View", i).setStructure(vs);
+ }
+ this.scroller.setContentNodes(this.views.getContentNodes());
+ },
+
+ _setStructureAttr: function(structure){
+ var s = structure;
+ if(s && dojo.isString(s)){
+ dojo.deprecated("dojox.grid._Grid.set('structure', 'objVar')", "use dojox.grid._Grid.set('structure', objVar) instead", "2.0");
+ s=dojo.getObject(s);
+ }
+ this.structure = s;
+ if(!s){
+ if(this.layout.structure){
+ s = this.layout.structure;
+ }else{
+ return;
+ }
+ }
+ this.views.destroyViews();
+ if(s !== this.layout.structure){
+ this.layout.setStructure(s);
+ }
+ this._structureChanged();
+ },
+
+ setStructure: function(/* dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]] */ inStructure){
+ // summary:
+ // Install a new structure and rebuild the grid.
+ dojo.deprecated("dojox.grid._Grid.setStructure(obj)", "use dojox.grid._Grid.set('structure', obj) instead.", "2.0");
+ this._setStructureAttr(inStructure);
+ },
+
+ getColumnTogglingItems: function(){
+ // Summary: returns an array of dijit.CheckedMenuItem widgets that can be
+ // added to a menu for toggling columns on and off.
+ return dojo.map(this.layout.cells, function(cell){
+ if(!cell.menuItems){ cell.menuItems = []; }
+
+ var self = this;
+ var item = new dijit.CheckedMenuItem({
+ label: cell.name,
+ checked: !cell.hidden,
+ _gridCell: cell,
+ onChange: function(checked){
+ if(self.layout.setColumnVisibility(this._gridCell.index, checked)){
+ var items = this._gridCell.menuItems;
+ if(items.length > 1){
+ dojo.forEach(items, function(item){
+ if(item !== this){
+ item.setAttribute("checked", checked);
+ }
+ }, this);
+ }
+ checked = dojo.filter(self.layout.cells, function(c){
+ if(c.menuItems.length > 1){
+ dojo.forEach(c.menuItems, "item.set('disabled', false);");
+ }else{
+ c.menuItems[0].set('disabled', false);
+ }
+ return !c.hidden;
+ });
+ if(checked.length == 1){
+ dojo.forEach(checked[0].menuItems, "item.set('disabled', true);");
+ }
+ }
+ },
+ destroy: function(){
+ var index = dojo.indexOf(this._gridCell.menuItems, this);
+ this._gridCell.menuItems.splice(index, 1);
+ delete this._gridCell;
+ dijit.CheckedMenuItem.prototype.destroy.apply(this, arguments);
+ }
+ });
+ cell.menuItems.push(item);
+ return item;
+ }, this); // dijit.CheckedMenuItem[]
+ },
+
+ _setHeaderMenuAttr: function(menu){
+ if(this._placeholders && this._placeholders.length){
+ dojo.forEach(this._placeholders, function(p){
+ p.unReplace(true);
+ });
+ this._placeholders = [];
+ }
+ if(this.headerMenu){
+ this.headerMenu.unBindDomNode(this.viewsHeaderNode);
+ }
+ this.headerMenu = menu;
+ if(!menu){ return; }
+
+ this.headerMenu.bindDomNode(this.viewsHeaderNode);
+ if(this.headerMenu.getPlaceholders){
+ this._placeholders = this.headerMenu.getPlaceholders(this.placeholderLabel);
+ }
+ },
+
+ setHeaderMenu: function(/* dijit.Menu */ menu){
+ dojo.deprecated("dojox.grid._Grid.setHeaderMenu(obj)", "use dojox.grid._Grid.set('headerMenu', obj) instead.", "2.0");
+ this._setHeaderMenuAttr(menu);
+ },
+
+ setupHeaderMenu: function(){
+ if(this._placeholders && this._placeholders.length){
+ dojo.forEach(this._placeholders, function(p){
+ if(p._replaced){
+ p.unReplace(true);
+ }
+ p.replace(this.getColumnTogglingItems());
+ }, this);
+ }
+ },
+
+ _fetch: function(start){
+ this.setScrollTop(0);
+ },
+
+ getItem: function(inRowIndex){
+ return null;
+ },
+
+ showMessage: function(message){
+ if(message){
+ this.messagesNode.innerHTML = message;
+ this.messagesNode.style.display = "";
+ }else{
+ this.messagesNode.innerHTML = "";
+ this.messagesNode.style.display = "none";
+ }
+ },
+
+ _structureChanged: function() {
+ this.buildViews();
+ if(this.autoRender && this._started){
+ this.render();
+ }
+ },
+
+ hasLayout: function() {
+ return this.layout.cells.length;
+ },
+
+ // sizing
+ resize: function(changeSize, resultSize){
+ // summary:
+ // Update the grid's rendering dimensions and resize it
+
+ // Calling sizeChange calls update() which calls _resize...so let's
+ // save our input values, if any, and use them there when it gets
+ // called. This saves us an extra call to _resize(), which can
+ // get kind of heavy.
+ this._pendingChangeSize = changeSize;
+ this._pendingResultSize = resultSize;
+ this.sizeChange();
+ },
+
+ _getPadBorder: function() {
+ this._padBorder = this._padBorder || dojo._getPadBorderExtents(this.domNode);
+ return this._padBorder;
+ },
+
+ _getHeaderHeight: function(){
+ var vns = this.viewsHeaderNode.style, t = vns.display == "none" ? 0 : this.views.measureHeader();
+ vns.height = t + 'px';
+ // header heights are reset during measuring so must be normalized after measuring.
+ this.views.normalizeHeaderNodeHeight();
+ return t;
+ },
+
+ _resize: function(changeSize, resultSize){
+ // Restore our pending values, if any
+ changeSize = changeSize || this._pendingChangeSize;
+ resultSize = resultSize || this._pendingResultSize;
+ delete this._pendingChangeSize;
+ delete this._pendingResultSize;
+ // if we have set up everything except the DOM, we cannot resize
+ if(!this.domNode){ return; }
+ var pn = this.domNode.parentNode;
+ if(!pn || pn.nodeType != 1 || !this.hasLayout() || pn.style.visibility == "hidden" || pn.style.display == "none"){
+ return;
+ }
+ // useful measurement
+ var padBorder = this._getPadBorder();
+ var hh = undefined;
+ var h;
+ // grid height
+ if(this._autoHeight){
+ this.domNode.style.height = 'auto';
+ }else if(typeof this.autoHeight == "number"){
+ h = hh = this._getHeaderHeight();
+ h += (this.scroller.averageRowHeight * this.autoHeight);
+ this.domNode.style.height = h + "px";
+ }else if(this.domNode.clientHeight <= padBorder.h){
+ if(pn == document.body){
+ this.domNode.style.height = this.defaultHeight;
+ }else if(this.height){
+ this.domNode.style.height = this.height;
+ }else{
+ this.fitTo = "parent";
+ }
+ }
+ // if we are given dimensions, size the grid's domNode to those dimensions
+ if(resultSize){
+ changeSize = resultSize;
+ }
+ if(changeSize){
+ dojo.marginBox(this.domNode, changeSize);
+ this.height = this.domNode.style.height;
+ delete this.fitTo;
+ }else if(this.fitTo == "parent"){
+ h = this._parentContentBoxHeight = this._parentContentBoxHeight || dojo._getContentBox(pn).h;
+ this.domNode.style.height = Math.max(0, h) + "px";
+ }
+
+ var hasFlex = dojo.some(this.views.views, function(v){ return v.flexCells; });
+
+ if(!this._autoHeight && (h || dojo._getContentBox(this.domNode).h) === 0){
+ // We need to hide the header, since the Grid is essentially hidden.
+ this.viewsHeaderNode.style.display = "none";
+ }else{
+ // Otherwise, show the header and give it an appropriate height.
+ this.viewsHeaderNode.style.display = "block";
+ if(!hasFlex && hh === undefined){
+ hh = this._getHeaderHeight();
+ }
+ }
+ if(hasFlex){
+ hh = undefined;
+ }
+
+ // NOTE: it is essential that width be applied before height
+ // Header height can only be calculated properly after view widths have been set.
+ // This is because flex column width is naturally 0 in Firefox.
+ // Therefore prior to width sizing flex columns with spaces are maximally wrapped
+ // and calculated to be too tall.
+ this.adaptWidth();
+ this.adaptHeight(hh);
+
+ this.postresize();
+ },
+
+ adaptWidth: function() {
+ // private: sets width and position for views and update grid width if necessary
+ var doAutoWidth = (!this.initialWidth && this.autoWidth);
+ var w = doAutoWidth ? 0 : this.domNode.clientWidth || (this.domNode.offsetWidth - this._getPadBorder().w),
+ vw = this.views.arrange(1, w);
+ this.views.onEach("adaptWidth");
+ if(doAutoWidth){
+ this.domNode.style.width = vw + "px";
+ }
+ },
+
+ adaptHeight: function(inHeaderHeight){
+ // private: measures and normalizes header height, then sets view heights, and then updates scroller
+ // content extent
+ var t = inHeaderHeight === undefined ? this._getHeaderHeight() : inHeaderHeight;
+ var h = (this._autoHeight ? -1 : Math.max(this.domNode.clientHeight - t, 0) || 0);
+ this.views.onEach('setSize', [0, h]);
+ this.views.onEach('adaptHeight');
+ if(!this._autoHeight){
+ var numScroll = 0, numNoScroll = 0;
+ var noScrolls = dojo.filter(this.views.views, function(v){
+ var has = v.hasHScrollbar();
+ if(has){ numScroll++; }else{ numNoScroll++; }
+ return (!has);
+ });
+ if(numScroll > 0 && numNoScroll > 0){
+ dojo.forEach(noScrolls, function(v){
+ v.adaptHeight(true);
+ });
+ }
+ }
+ if(this.autoHeight === true || h != -1 || (typeof this.autoHeight == "number" && this.autoHeight >= this.get('rowCount'))){
+ this.scroller.windowHeight = h;
+ }else{
+ this.scroller.windowHeight = Math.max(this.domNode.clientHeight - t, 0);
+ }
+ },
+
+ // startup
+ startup: function(){
+ if(this._started){return;}
+ this.inherited(arguments);
+ if(this.autoRender){
+ this.render();
+ }
+ },
+
+ // render
+ render: function(){
+ // summary:
+ // Render the grid, headers, and views. Edit and scrolling states are reset. To retain edit and
+ // scrolling states, see Update.
+
+ if(!this.domNode){return;}
+ if(!this._started){return;}
+
+ if(!this.hasLayout()) {
+ this.scroller.init(0, this.keepRows, this.rowsPerPage);
+ return;
+ }
+ //
+ this.update = this.defaultUpdate;
+ this._render();
+ },
+
+ _render: function(){
+ this.scroller.init(this.get('rowCount'), this.keepRows, this.rowsPerPage);
+ this.prerender();
+ this.setScrollTop(0);
+ this.postrender();
+ },
+
+ prerender: function(){
+ // if autoHeight, make sure scroller knows not to virtualize; everything must be rendered.
+ this.keepRows = this._autoHeight ? 0 : this.keepRows;
+ this.scroller.setKeepInfo(this.keepRows);
+ this.views.render();
+ this._resize();
+ },
+
+ postrender: function(){
+ this.postresize();
+ this.focus.initFocusView();
+ // make rows unselectable
+ dojo.setSelectable(this.domNode, this.selectable);
+ },
+
+ postresize: function(){
+ // views are position absolute, so they do not inflate the parent
+ if(this._autoHeight){
+ var size = Math.max(this.views.measureContent()) + 'px';
+
+ this.viewsNode.style.height = size;
+ }
+ },
+
+ renderRow: function(inRowIndex, inNodes){
+ // summary: private, used internally to render rows
+ this.views.renderRow(inRowIndex, inNodes, this._skipRowRenormalize);
+ },
+
+ rowRemoved: function(inRowIndex){
+ // summary: private, used internally to remove rows
+ this.views.rowRemoved(inRowIndex);
+ },
+
+ invalidated: null,
+
+ updating: false,
+
+ beginUpdate: function(){
+ // summary:
+ // Use to make multiple changes to rows while queueing row updating.
+ // NOTE: not currently supporting nested begin/endUpdate calls
+ this.invalidated = [];
+ this.updating = true;
+ },
+
+ endUpdate: function(){
+ // summary:
+ // Use after calling beginUpdate to render any changes made to rows.
+ this.updating = false;
+ var i = this.invalidated, r;
+ if(i.all){
+ this.update();
+ }else if(i.rowCount != undefined){
+ this.updateRowCount(i.rowCount);
+ }else{
+ for(r in i){
+ this.updateRow(Number(r));
+ }
+ }
+ this.invalidated = [];
+ },
+
+ // update
+ defaultUpdate: function(){
+ // note: initial update calls render and subsequently this function.
+ if(!this.domNode){return;}
+ if(this.updating){
+ this.invalidated.all = true;
+ return;
+ }
+ //this.edit.saveState(inRowIndex);
+ this.lastScrollTop = this.scrollTop;
+ this.prerender();
+ this.scroller.invalidateNodes();
+ this.setScrollTop(this.lastScrollTop);
+ this.postrender();
+ //this.edit.restoreState(inRowIndex);
+ },
+
+ update: function(){
+ // summary:
+ // Update the grid, retaining edit and scrolling states.
+ this.render();
+ },
+
+ updateRow: function(inRowIndex){
+ // summary:
+ // Render a single row.
+ // inRowIndex: Integer
+ // Index of the row to render
+ inRowIndex = Number(inRowIndex);
+ if(this.updating){
+ this.invalidated[inRowIndex]=true;
+ }else{
+ this.views.updateRow(inRowIndex);
+ this.scroller.rowHeightChanged(inRowIndex);
+ }
+ },
+
+ updateRows: function(startIndex, howMany){
+ // summary:
+ // Render consecutive rows at once.
+ // startIndex: Integer
+ // Index of the starting row to render
+ // howMany: Integer
+ // How many rows to update.
+ startIndex = Number(startIndex);
+ howMany = Number(howMany);
+ var i;
+ if(this.updating){
+ for(i=0; i<howMany; i++){
+ this.invalidated[i+startIndex]=true;
+ }
+ }else{
+ for(i=0; i<howMany; i++){
+ this.views.updateRow(i+startIndex, this._skipRowRenormalize);
+ }
+ this.scroller.rowHeightChanged(startIndex);
+ }
+ },
+
+ updateRowCount: function(inRowCount){
+ //summary:
+ // Change the number of rows.
+ // inRowCount: int
+ // Number of rows in the grid.
+ if(this.updating){
+ this.invalidated.rowCount = inRowCount;
+ }else{
+ this.rowCount = inRowCount;
+ this._setAutoHeightAttr(this.autoHeight, true);
+ if(this.layout.cells.length){
+ this.scroller.updateRowCount(inRowCount);
+ }
+ this._resize();
+ if(this.layout.cells.length){
+ this.setScrollTop(this.scrollTop);
+ }
+ }
+ },
+
+ updateRowStyles: function(inRowIndex){
+ // summary:
+ // Update the styles for a row after it's state has changed.
+ this.views.updateRowStyles(inRowIndex);
+ },
+ getRowNode: function(inRowIndex){
+ // summary:
+ // find the rowNode that is not a rowSelector
+ if (this.focus.focusView && !(this.focus.focusView instanceof dojox.grid._RowSelector)){
+ return this.focus.focusView.rowNodes[inRowIndex];
+ }else{ // search through views
+ for (var i = 0, cView; (cView = this.views.views[i]); i++) {
+ if (!(cView instanceof dojox.grid._RowSelector)) {
+ return cView.rowNodes[inRowIndex];
+ }
+ }
+ }
+ return null;
+ },
+ rowHeightChanged: function(inRowIndex){
+ // summary:
+ // Update grid when the height of a row has changed. Row height is handled automatically as rows
+ // are rendered. Use this function only to update a row's height outside the normal rendering process.
+ // inRowIndex: Integer
+ // index of the row that has changed height
+
+ this.views.renormalizeRow(inRowIndex);
+ this.scroller.rowHeightChanged(inRowIndex);
+ },
+
+ // fastScroll: Boolean
+ // flag modifies vertical scrolling behavior. Defaults to true but set to false for slower
+ // scroll performance but more immediate scrolling feedback
+ fastScroll: true,
+
+ delayScroll: false,
+
+ // scrollRedrawThreshold: int
+ // pixel distance a user must scroll vertically to trigger grid scrolling.
+ scrollRedrawThreshold: (dojo.isIE ? 100 : 50),
+
+ // scroll methods
+ scrollTo: function(inTop){
+ // summary:
+ // Vertically scroll the grid to a given pixel position
+ // inTop: Integer
+ // vertical position of the grid in pixels
+ if(!this.fastScroll){
+ this.setScrollTop(inTop);
+ return;
+ }
+ var delta = Math.abs(this.lastScrollTop - inTop);
+ this.lastScrollTop = inTop;
+ if(delta > this.scrollRedrawThreshold || this.delayScroll){
+ this.delayScroll = true;
+ this.scrollTop = inTop;
+ this.views.setScrollTop(inTop);
+ if(this._pendingScroll){
+ window.clearTimeout(this._pendingScroll);
+ }
+ var _this = this;
+ this._pendingScroll = window.setTimeout(function(){
+ delete _this._pendingScroll;
+ _this.finishScrollJob();
+ }, 200);
+ }else{
+ this.setScrollTop(inTop);
+ }
+ },
+
+ finishScrollJob: function(){
+ this.delayScroll = false;
+ this.setScrollTop(this.scrollTop);
+ },
+
+ setScrollTop: function(inTop){
+ this.scroller.scroll(this.views.setScrollTop(inTop));
+ },
+
+ scrollToRow: function(inRowIndex){
+ // summary:
+ // Scroll the grid to a specific row.
+ // inRowIndex: Integer
+ // grid row index
+ this.setScrollTop(this.scroller.findScrollTop(inRowIndex) + 1);
+ },
+
+ // styling (private, used internally to style individual parts of a row)
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ this.rows.styleRowNode(inRowIndex, inRowNode);
+ }
+ },
+
+ // called when the mouse leaves the grid so we can deselect all hover rows
+ _mouseOut: function(e){
+ this.rows.setOverRow(-2);
+ },
+
+ // cells
+ getCell: function(inIndex){
+ // summary:
+ // Retrieves the cell object for a given grid column.
+ // inIndex: Integer
+ // Grid column index of cell to retrieve
+ // returns:
+ // a grid cell
+ return this.layout.cells[inIndex];
+ },
+
+ setCellWidth: function(inIndex, inUnitWidth){
+ this.getCell(inIndex).unitWidth = inUnitWidth;
+ },
+
+ getCellName: function(inCell){
+ // summary: Returns the cell name of a passed cell
+ return "Cell " + inCell.index; // String
+ },
+
+ // sorting
+ canSort: function(inSortInfo){
+ // summary:
+ // Determines if the grid can be sorted
+ // inSortInfo: Integer
+ // Sort information, 1-based index of column on which to sort, positive for an ascending sort
+ // and negative for a descending sort
+ // returns: Boolean
+ // True if grid can be sorted on the given column in the given direction
+ },
+
+ sort: function(){
+ },
+
+ getSortAsc: function(inSortInfo){
+ // summary:
+ // Returns true if grid is sorted in an ascending direction.
+ inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo;
+ return Boolean(inSortInfo > 0); // Boolean
+ },
+
+ getSortIndex: function(inSortInfo){
+ // summary:
+ // Returns the index of the column on which the grid is sorted
+ inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo;
+ return Math.abs(inSortInfo) - 1; // Integer
+ },
+
+ setSortIndex: function(inIndex, inAsc){
+ // summary:
+ // Sort the grid on a column in a specified direction
+ // inIndex: Integer
+ // Column index on which to sort.
+ // inAsc: Boolean
+ // If true, sort the grid in ascending order, otherwise in descending order
+ var si = inIndex +1;
+ if(inAsc != undefined){
+ si *= (inAsc ? 1 : -1);
+ } else if(this.getSortIndex() == inIndex){
+ si = -this.sortInfo;
+ }
+ this.setSortInfo(si);
+ },
+
+ setSortInfo: function(inSortInfo){
+ if(this.canSort(inSortInfo)){
+ this.sortInfo = inSortInfo;
+ this.sort();
+ this.update();
+ }
+ },
+
+ // DOM event handler
+ doKeyEvent: function(e){
+ e.dispatch = 'do' + e.type;
+ this.onKeyEvent(e);
+ },
+
+ // event dispatch
+ //: protected
+ _dispatch: function(m, e){
+ if(m in this){
+ return this[m](e);
+ }
+ return false;
+ },
+
+ dispatchKeyEvent: function(e){
+ this._dispatch(e.dispatch, e);
+ },
+
+ dispatchContentEvent: function(e){
+ this.edit.dispatchEvent(e) || e.sourceView.dispatchContentEvent(e) || this._dispatch(e.dispatch, e);
+ },
+
+ dispatchHeaderEvent: function(e){
+ e.sourceView.dispatchHeaderEvent(e) || this._dispatch('doheader' + e.type, e);
+ },
+
+ dokeydown: function(e){
+ this.onKeyDown(e);
+ },
+
+ doclick: function(e){
+ if(e.cellNode){
+ this.onCellClick(e);
+ }else{
+ this.onRowClick(e);
+ }
+ },
+
+ dodblclick: function(e){
+ if(e.cellNode){
+ this.onCellDblClick(e);
+ }else{
+ this.onRowDblClick(e);
+ }
+ },
+
+ docontextmenu: function(e){
+ if(e.cellNode){
+ this.onCellContextMenu(e);
+ }else{
+ this.onRowContextMenu(e);
+ }
+ },
+
+ doheaderclick: function(e){
+ if(e.cellNode){
+ this.onHeaderCellClick(e);
+ }else{
+ this.onHeaderClick(e);
+ }
+ },
+
+ doheaderdblclick: function(e){
+ if(e.cellNode){
+ this.onHeaderCellDblClick(e);
+ }else{
+ this.onHeaderDblClick(e);
+ }
+ },
+
+ doheadercontextmenu: function(e){
+ if(e.cellNode){
+ this.onHeaderCellContextMenu(e);
+ }else{
+ this.onHeaderContextMenu(e);
+ }
+ },
+
+ // override to modify editing process
+ doStartEdit: function(inCell, inRowIndex){
+ this.onStartEdit(inCell, inRowIndex);
+ },
+
+ doApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
+ this.onApplyCellEdit(inValue, inRowIndex, inFieldIndex);
+ },
+
+ doCancelEdit: function(inRowIndex){
+ this.onCancelEdit(inRowIndex);
+ },
+
+ doApplyEdit: function(inRowIndex){
+ this.onApplyEdit(inRowIndex);
+ },
+
+ // row editing
+ addRow: function(){
+ // summary:
+ // Add a row to the grid.
+ this.updateRowCount(this.get('rowCount')+1);
+ },
+
+ removeSelectedRows: function(){
+ // summary:
+ // Remove the selected rows from the grid.
+ if(this.allItemsSelected){
+ this.updateRowCount(0);
+ }else{
+ this.updateRowCount(Math.max(0, this.get('rowCount') - this.selection.getSelected().length));
+ }
+ this.selection.clear();
+ }
+
+ });
+
+ dojox.grid._Grid.markupFactory = function(props, node, ctor, cellFunc){
+ var d = dojo;
+ var widthFromAttr = function(n){
+ var w = d.attr(n, "width")||"auto";
+ if((w != "auto")&&(w.slice(-2) != "em")&&(w.slice(-1) != "%")){
+ w = parseInt(w, 10)+"px";
+ }
+ return w;
+ };
+ // if(!props.store){ console.debug("no store!"); }
+ // if a structure isn't referenced, do we have enough
+ // data to try to build one automatically?
+ if( !props.structure &&
+ node.nodeName.toLowerCase() == "table"){
+
+ // try to discover a structure
+ props.structure = d.query("> colgroup", node).map(function(cg){
+ var sv = d.attr(cg, "span");
+ var v = {
+ noscroll: (d.attr(cg, "noscroll") == "true") ? true : false,
+ __span: (!!sv ? parseInt(sv, 10) : 1),
+ cells: []
+ };
+ if(d.hasAttr(cg, "width")){
+ v.width = widthFromAttr(cg);
+ }
+ return v; // for vendetta
+ });
+ if(!props.structure.length){
+ props.structure.push({
+ __span: Infinity,
+ cells: [] // catch-all view
+ });
+ }
+ // check to see if we're gonna have more than one view
+
+ // for each tr in our th, create a row of cells
+ d.query("thead > tr", node).forEach(function(tr, tr_idx){
+ var cellCount = 0;
+ var viewIdx = 0;
+ var lastViewIdx;
+ var cView = null;
+ d.query("> th", tr).map(function(th){
+ // what view will this cell go into?
+
+ // NOTE:
+ // to prevent extraneous iteration, we start counters over
+ // for each row, incrementing over the surface area of the
+ // structure that colgroup processing generates and
+ // creating cell objects for each <th> to place into those
+ // cell groups. There's a lot of state-keepking logic
+ // here, but it is what it has to be.
+ if(!cView){ // current view book keeping
+ lastViewIdx = 0;
+ cView = props.structure[0];
+ }else if(cellCount >= (lastViewIdx+cView.__span)){
+ viewIdx++;
+ // move to allocating things into the next view
+ lastViewIdx += cView.__span;
+ var lastView = cView;
+ cView = props.structure[viewIdx];
+ }
+
+ // actually define the cell from what markup hands us
+ var cell = {
+ name: d.trim(d.attr(th, "name")||th.innerHTML),
+ colSpan: parseInt(d.attr(th, "colspan")||1, 10),
+ type: d.trim(d.attr(th, "cellType")||""),
+ id: d.trim(d.attr(th,"id")||"")
+ };
+ cellCount += cell.colSpan;
+ var rowSpan = d.attr(th, "rowspan");
+ if(rowSpan){
+ cell.rowSpan = rowSpan;
+ }
+ if(d.hasAttr(th, "width")){
+ cell.width = widthFromAttr(th);
+ }
+ if(d.hasAttr(th, "relWidth")){
+ cell.relWidth = window.parseInt(dojo.attr(th, "relWidth"), 10);
+ }
+ if(d.hasAttr(th, "hidden")){
+ cell.hidden = (d.attr(th, "hidden") == "true" || d.attr(th, "hidden") === true/*always boolean true in Chrome*/);
+ }
+
+ if(cellFunc){
+ cellFunc(th, cell);
+ }
+
+ cell.type = cell.type ? dojo.getObject(cell.type) : dojox.grid.cells.Cell;
+
+ if(cell.type && cell.type.markupFactory){
+ cell.type.markupFactory(th, cell);
+ }
+
+ if(!cView.cells[tr_idx]){
+ cView.cells[tr_idx] = [];
+ }
+ cView.cells[tr_idx].push(cell);
+ });
+ });
+ }
+
+ return new ctor(props, node);
+ };
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid.DataSelection"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.DataSelection"] = true;
+dojo.provide("dojox.grid.DataSelection");
+
+
+dojo.declare("dojox.grid.DataSelection", dojox.grid.Selection, {
+ getFirstSelected: function(){
+ var idx = dojox.grid.Selection.prototype.getFirstSelected.call(this);
+
+ if(idx == -1){ return null; }
+ return this.grid.getItem(idx);
+ },
+
+ getNextSelected: function(inPrev){
+ var old_idx = this.grid.getItemIndex(inPrev);
+ var idx = dojox.grid.Selection.prototype.getNextSelected.call(this, old_idx);
+
+ if(idx == -1){ return null; }
+ return this.grid.getItem(idx);
+ },
+
+ getSelected: function(){
+ var result = [];
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ result.push(this.grid.getItem(i));
+ }
+ }
+ return result;
+ },
+
+ addToSelection: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ dojox.grid.Selection.prototype.addToSelection.call(this, idx);
+ },
+
+ deselect: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ dojox.grid.Selection.prototype.deselect.call(this, idx);
+ },
+
+ deselectAll: function(inItemOrIndex){
+ var idx = null;
+ if(inItemOrIndex || typeof inItemOrIndex == "number"){
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ dojox.grid.Selection.prototype.deselectAll.call(this, idx);
+ }else{
+ this.inherited(arguments);
+ }
+ }
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid.DataGrid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.DataGrid"] = true;
+dojo.provide("dojox.grid.DataGrid");
+
+
+
+
+/*=====
+dojo.declare("dojox.grid.__DataCellDef", dojox.grid.__CellDef, {
+ constructor: function(){
+ // field: String?
+ // The attribute to read from the dojo.data item for the row.
+ // fields: String[]?
+ // An array of fields to grab the values of and pass as an array to the grid
+ // get: Function?
+ // function(rowIndex, item?){} rowIndex is of type Integer, item is of type
+ // Object. This function will be called when a cell requests data. Returns
+ // the unformatted data for the cell.
+ }
+});
+=====*/
+
+/*=====
+dojo.declare("dojox.grid.__DataViewDef", dojox.grid.__ViewDef, {
+ constructor: function(){
+ // cells: dojox.grid.__DataCellDef[]|Array[dojox.grid.__DataCellDef[]]?
+ // The structure of the cells within this grid.
+ // defaultCell: dojox.grid.__DataCellDef?
+ // A cell definition with default values for all cells in this view. If
+ // a property is defined in a cell definition in the "cells" array and
+ // this property, the cell definition's property will override this
+ // property's property.
+ }
+});
+=====*/
+
+dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
+ store: null,
+ query: null,
+ queryOptions: null,
+ fetchText: '...',
+ sortFields: null,
+
+ // updateDelay: int
+ // Time, in milliseconds, to delay updates automatically so that multiple
+ // calls to onSet/onNew/onDelete don't keep rerendering the grid. Set
+ // to 0 to immediately cause updates. A higher value will result in
+ // better performance at the expense of responsiveness of the grid.
+ updateDelay: 1,
+
+/*=====
+ // structure: dojox.grid.__DataViewDef|dojox.grid.__DataViewDef[]|dojox.grid.__DataCellDef[]|Array[dojox.grid.__DataCellDef[]]
+ // View layout defintion.
+ structure: '',
+=====*/
+
+ // You can specify items instead of a query, if you like. They do not need
+ // to be loaded - but the must be items in the store
+ items: null,
+
+ _store_connects: null,
+ _by_idty: null,
+ _by_idx: null,
+ _cache: null,
+ _pages: null,
+ _pending_requests: null,
+ _bop: -1,
+ _eop: -1,
+ _requests: 0,
+ rowCount: 0,
+
+ _isLoaded: false,
+ _isLoading: false,
+
+ postCreate: function(){
+ this._pages = [];
+ this._store_connects = [];
+ this._by_idty = {};
+ this._by_idx = [];
+ this._cache = [];
+ this._pending_requests = {};
+
+ this._setStore(this.store);
+ this.inherited(arguments);
+ },
+
+ createSelection: function(){
+ this.selection = new dojox.grid.DataSelection(this);
+ },
+
+ get: function(inRowIndex, inItem){
+ // summary: Default data getter.
+ // description:
+ // Provides data to display in a grid cell. Called in grid cell context.
+ // So this.cell.index is the column index.
+ // inRowIndex: Integer
+ // Row for which to provide data
+ // returns:
+ // Data to display for a given grid cell.
+
+ if(inItem && this.field == "_item" && !this.fields){
+ return inItem;
+ }else if(inItem && this.fields){
+ var ret = [];
+ var s = this.grid.store;
+ dojo.forEach(this.fields, function(f){
+ ret = ret.concat(s.getValues(inItem, f));
+ });
+ return ret;
+ }else if(!inItem && typeof inRowIndex === "string"){
+ return this.inherited(arguments);
+ }
+ return (!inItem ? this.defaultValue : (!this.field ? this.value : (this.field == "_item" ? inItem : this.grid.store.getValue(inItem, this.field))));
+ },
+
+ _checkUpdateStatus: function(){
+ if(this.updateDelay > 0){
+ var iStarted = false;
+ if(this._endUpdateDelay){
+ clearTimeout(this._endUpdateDelay);
+ delete this._endUpdateDelay;
+ iStarted = true;
+ }
+ if(!this.updating){
+ this.beginUpdate();
+ iStarted = true;
+ }
+ if(iStarted){
+ var _this = this;
+ this._endUpdateDelay = setTimeout(function(){
+ delete _this._endUpdateDelay;
+ _this.endUpdate();
+ }, this.updateDelay);
+ }
+ }
+ },
+
+ _onSet: function(item, attribute, oldValue, newValue){
+ this._checkUpdateStatus();
+ var idx = this.getItemIndex(item);
+ if(idx>-1){
+ this.updateRow(idx);
+ }
+ },
+
+ _createItem: function(item, index){
+ var idty = this._hasIdentity ? this.store.getIdentity(item) : dojo.toJson(this.query) + ":idx:" + index + ":sort:" + dojo.toJson(this.getSortProps());
+ var o = this._by_idty[idty] = { idty: idty, item: item };
+ return o;
+ },
+
+ _addItem: function(item, index, noUpdate){
+ this._by_idx[index] = this._createItem(item, index);
+ if(!noUpdate){
+ this.updateRow(index);
+ }
+ },
+
+ _onNew: function(item, parentInfo){
+ this._checkUpdateStatus();
+ var rowCount = this.get('rowCount');
+ this._addingItem = true;
+ this.updateRowCount(rowCount+1);
+ this._addingItem = false;
+ this._addItem(item, rowCount);
+ this.showMessage();
+ },
+
+ _onDelete: function(item){
+ this._checkUpdateStatus();
+ var idx = this._getItemIndex(item, true);
+
+ if(idx >= 0){
+ // When a row is deleted, all rest rows are shifted down,
+ // and migrate from page to page. If some page is not
+ // loaded yet empty rows can migrate to initialized pages
+ // without refreshing. It causes empty rows in some pages, see:
+ // http://bugs.dojotoolkit.org/ticket/6818
+ // this code fix this problem by reseting loaded page info
+ this._pages = [];
+ this._bop = -1;
+ this._eop = -1;
+
+ var o = this._by_idx[idx];
+ this._by_idx.splice(idx, 1);
+ delete this._by_idty[o.idty];
+ this.updateRowCount(this.get('rowCount')-1);
+ if(this.get('rowCount') === 0){
+ this.showMessage(this.noDataMessage);
+ }
+ }
+ },
+
+ _onRevert: function(){
+ this._refresh();
+ },
+
+ setStore: function(store, query, queryOptions){
+ this._setQuery(query, queryOptions);
+ this._setStore(store);
+ this._refresh(true);
+ },
+
+ setQuery: function(query, queryOptions){
+ this._setQuery(query, queryOptions);
+ this._refresh(true);
+ },
+
+ setItems: function(items){
+ this.items = items;
+ this._setStore(this.store);
+ this._refresh(true);
+ },
+
+ _setQuery: function(query, queryOptions){
+ this.query = query;
+ this.queryOptions = queryOptions || this.queryOptions;
+ },
+
+ _setStore: function(store){
+ if(this.store && this._store_connects){
+ dojo.forEach(this._store_connects, this.disconnect, this);
+ }
+ this.store = store;
+
+ if(this.store){
+ var f = this.store.getFeatures();
+ var h = [];
+
+ this._canEdit = !!f["dojo.data.api.Write"] && !!f["dojo.data.api.Identity"];
+ this._hasIdentity = !!f["dojo.data.api.Identity"];
+
+ if(!!f["dojo.data.api.Notification"] && !this.items){
+ h.push(this.connect(this.store, "onSet", "_onSet"));
+ h.push(this.connect(this.store, "onNew", "_onNew"));
+ h.push(this.connect(this.store, "onDelete", "_onDelete"));
+ }
+ if(this._canEdit){
+ h.push(this.connect(this.store, "revert", "_onRevert"));
+ }
+
+ this._store_connects = h;
+ }
+ },
+
+ _onFetchBegin: function(size, req){
+ if(!this.scroller){ return; }
+ if(this.rowCount != size){
+ if(req.isRender){
+ this.scroller.init(size, this.keepRows, this.rowsPerPage);
+ this.rowCount = size;
+ this._setAutoHeightAttr(this.autoHeight, true);
+ this._skipRowRenormalize = true;
+ this.prerender();
+ this._skipRowRenormalize = false;
+ }else{
+ this.updateRowCount(size);
+ }
+ }
+ if(!size){
+ this.views.render();
+ this._resize();
+ this.showMessage(this.noDataMessage);
+ this.focus.initFocusView();
+ }else{
+ this.showMessage();
+ }
+ },
+
+ _onFetchComplete: function(items, req){
+ if(!this.scroller){ return; }
+ if(items && items.length > 0){
+ //console.log(items);
+ dojo.forEach(items, function(item, idx){
+ this._addItem(item, req.start+idx, true);
+ }, this);
+ this.updateRows(req.start, items.length);
+ if(req.isRender){
+ this.setScrollTop(0);
+ this.postrender();
+ }else if(this._lastScrollTop){
+ this.setScrollTop(this._lastScrollTop);
+ }
+ }
+ delete this._lastScrollTop;
+ if(!this._isLoaded){
+ this._isLoading = false;
+ this._isLoaded = true;
+ }
+ this._pending_requests[req.start] = false;
+ },
+
+ _onFetchError: function(err, req){
+ console.log(err);
+ delete this._lastScrollTop;
+ if(!this._isLoaded){
+ this._isLoading = false;
+ this._isLoaded = true;
+ this.showMessage(this.errorMessage);
+ }
+ this._pending_requests[req.start] = false;
+ this.onFetchError(err, req);
+ },
+
+ onFetchError: function(err, req){
+ },
+
+ _fetch: function(start, isRender){
+ start = start || 0;
+ if(this.store && !this._pending_requests[start]){
+ if(!this._isLoaded && !this._isLoading){
+ this._isLoading = true;
+ this.showMessage(this.loadingMessage);
+ }
+ this._pending_requests[start] = true;
+ //console.log("fetch: ", start);
+ try{
+ if(this.items){
+ var items = this.items;
+ var store = this.store;
+ this.rowsPerPage = items.length;
+ var req = {
+ start: start,
+ count: this.rowsPerPage,
+ isRender: isRender
+ };
+ this._onFetchBegin(items.length, req);
+
+ // Load them if we need to
+ var waitCount = 0;
+ dojo.forEach(items, function(i){
+ if(!store.isItemLoaded(i)){ waitCount++; }
+ });
+ if(waitCount === 0){
+ this._onFetchComplete(items, req);
+ }else{
+ var onItem = function(item){
+ waitCount--;
+ if(waitCount === 0){
+ this._onFetchComplete(items, req);
+ }
+ };
+ dojo.forEach(items, function(i){
+ if(!store.isItemLoaded(i)){
+ store.loadItem({item: i, onItem: onItem, scope: this});
+ }
+ }, this);
+ }
+ }else{
+ this.store.fetch({
+ start: start,
+ count: this.rowsPerPage,
+ query: this.query,
+ sort: this.getSortProps(),
+ queryOptions: this.queryOptions,
+ isRender: isRender,
+ onBegin: dojo.hitch(this, "_onFetchBegin"),
+ onComplete: dojo.hitch(this, "_onFetchComplete"),
+ onError: dojo.hitch(this, "_onFetchError")
+ });
+ }
+ }catch(e){
+ this._onFetchError(e, {start: start, count: this.rowsPerPage});
+ }
+ }
+ },
+
+ _clearData: function(){
+ this.updateRowCount(0);
+ this._by_idty = {};
+ this._by_idx = [];
+ this._pages = [];
+ this._bop = this._eop = -1;
+ this._isLoaded = false;
+ this._isLoading = false;
+ },
+
+ getItem: function(idx){
+ var data = this._by_idx[idx];
+ if(!data||(data&&!data.item)){
+ this._preparePage(idx);
+ return null;
+ }
+ return data.item;
+ },
+
+ getItemIndex: function(item){
+ return this._getItemIndex(item, false);
+ },
+
+ _getItemIndex: function(item, isDeleted){
+ if(!isDeleted && !this.store.isItem(item)){
+ return -1;
+ }
+
+ var idty = this._hasIdentity ? this.store.getIdentity(item) : null;
+
+ for(var i=0, l=this._by_idx.length; i<l; i++){
+ var d = this._by_idx[i];
+ if(d && ((idty && d.idty == idty) || (d.item === item))){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ filter: function(query, reRender){
+ this.query = query;
+ if(reRender){
+ this._clearData();
+ }
+ this._fetch();
+ },
+
+ _getItemAttr: function(idx, attr){
+ var item = this.getItem(idx);
+ return (!item ? this.fetchText : this.store.getValue(item, attr));
+ },
+
+ // rendering
+ _render: function(){
+ if(this.domNode.parentNode){
+ this.scroller.init(this.get('rowCount'), this.keepRows, this.rowsPerPage);
+ this.prerender();
+ this._fetch(0, true);
+ }
+ },
+
+ // paging
+ _requestsPending: function(inRowIndex){
+ return this._pending_requests[inRowIndex];
+ },
+
+ _rowToPage: function(inRowIndex){
+ return (this.rowsPerPage ? Math.floor(inRowIndex / this.rowsPerPage) : inRowIndex);
+ },
+
+ _pageToRow: function(inPageIndex){
+ return (this.rowsPerPage ? this.rowsPerPage * inPageIndex : inPageIndex);
+ },
+
+ _preparePage: function(inRowIndex){
+ if((inRowIndex < this._bop || inRowIndex >= this._eop) && !this._addingItem){
+ var pageIndex = this._rowToPage(inRowIndex);
+ this._needPage(pageIndex);
+ this._bop = pageIndex * this.rowsPerPage;
+ this._eop = this._bop + (this.rowsPerPage || this.get('rowCount'));
+ }
+ },
+
+ _needPage: function(inPageIndex){
+ if(!this._pages[inPageIndex]){
+ this._pages[inPageIndex] = true;
+ this._requestPage(inPageIndex);
+ }
+ },
+
+ _requestPage: function(inPageIndex){
+ var row = this._pageToRow(inPageIndex);
+ var count = Math.min(this.rowsPerPage, this.get('rowCount') - row);
+ if(count > 0){
+ this._requests++;
+ if(!this._requestsPending(row)){
+ setTimeout(dojo.hitch(this, "_fetch", row, false), 1);
+ //this.requestRows(row, count);
+ }
+ }
+ },
+
+ getCellName: function(inCell){
+ return inCell.field;
+ //console.log(inCell);
+ },
+
+ _refresh: function(isRender){
+ this._clearData();
+ this._fetch(0, isRender);
+ },
+
+ sort: function(){
+ this.edit.apply();
+ this._lastScrollTop = this.scrollTop;
+ this._refresh();
+ },
+
+ canSort: function(){
+ return (!this._isLoading);
+ },
+
+ getSortProps: function(){
+ var c = this.getCell(this.getSortIndex());
+ if(!c){
+ if(this.sortFields){
+ return this.sortFields;
+ }
+ return null;
+ }else{
+ var desc = c["sortDesc"];
+ var si = !(this.sortInfo>0);
+ if(typeof desc == "undefined"){
+ desc = si;
+ }else{
+ desc = si ? !desc : desc;
+ }
+ return [{ attribute: c.field, descending: desc }];
+ }
+ },
+
+ styleRowState: function(inRow){
+ // summary: Perform row styling
+ if(this.store && this.store.getState){
+ var states=this.store.getState(inRow.index), c='';
+ for(var i=0, ss=["inflight", "error", "inserting"], s; s=ss[i]; i++){
+ if(states[s]){
+ c = ' dojoxGridRow-' + s;
+ break;
+ }
+ }
+ inRow.customClasses += c;
+ }
+ },
+
+ onStyleRow: function(inRow){
+ this.styleRowState(inRow);
+ this.inherited(arguments);
+ },
+
+ // editing
+ canEdit: function(inCell, inRowIndex){
+ return this._canEdit;
+ },
+
+ _copyAttr: function(idx, attr){
+ var row = {};
+ var backstop = {};
+ var src = this.getItem(idx);
+ return this.store.getValue(src, attr);
+ },
+
+ doStartEdit: function(inCell, inRowIndex){
+ if(!this._cache[inRowIndex]){
+ this._cache[inRowIndex] = this._copyAttr(inRowIndex, inCell.field);
+ }
+ this.onStartEdit(inCell, inRowIndex);
+ },
+
+ doApplyCellEdit: function(inValue, inRowIndex, inAttrName){
+ this.store.fetchItemByIdentity({
+ identity: this._by_idx[inRowIndex].idty,
+ onItem: dojo.hitch(this, function(item){
+ var oldValue = this.store.getValue(item, inAttrName);
+ if(typeof oldValue == 'number'){
+ inValue = isNaN(inValue) ? inValue : parseFloat(inValue);
+ }else if(typeof oldValue == 'boolean'){
+ inValue = inValue == 'true' ? true : inValue == 'false' ? false : inValue;
+ }else if(oldValue instanceof Date){
+ var asDate = new Date(inValue);
+ inValue = isNaN(asDate.getTime()) ? inValue : asDate;
+ }
+ this.store.setValue(item, inAttrName, inValue);
+ this.onApplyCellEdit(inValue, inRowIndex, inAttrName);
+ })
+ });
+ },
+
+ doCancelEdit: function(inRowIndex){
+ var cache = this._cache[inRowIndex];
+ if(cache){
+ this.updateRow(inRowIndex);
+ delete this._cache[inRowIndex];
+ }
+ this.onCancelEdit.apply(this, arguments);
+ },
+
+ doApplyEdit: function(inRowIndex, inDataAttr){
+ var cache = this._cache[inRowIndex];
+ /*if(cache){
+ var data = this.getItem(inRowIndex);
+ if(this.store.getValue(data, inDataAttr) != cache){
+ this.update(cache, data, inRowIndex);
+ }
+ delete this._cache[inRowIndex];
+ }*/
+ this.onApplyEdit(inRowIndex);
+ },
+
+ removeSelectedRows: function(){
+ // summary:
+ // Remove the selected rows from the grid.
+ if(this._canEdit){
+ this.edit.apply();
+ var fx = dojo.hitch(this, function(items){
+ if(items.length){
+ dojo.forEach(items, this.store.deleteItem, this.store);
+ this.selection.clear();
+ }
+ });
+ if(this.allItemsSelected){
+ this.store.fetch({
+ query: this.query,
+ queryOptions: this.queryOptions,
+ onComplete: fx});
+ }else{
+ fx(this.selection.getSelected());
+ }
+ }
+ }
+});
+
+dojox.grid.DataGrid.cell_markupFactory = function(cellFunc, node, cellDef){
+ var field = dojo.trim(dojo.attr(node, "field")||"");
+ if(field){
+ cellDef.field = field;
+ }
+ cellDef.field = cellDef.field||cellDef.name;
+ var fields = dojo.trim(dojo.attr(node, "fields")||"");
+ if(fields){
+ cellDef.fields = fields.split(",");
+ }
+ if(cellFunc){
+ cellFunc(node, cellDef);
+ }
+};
+
+dojox.grid.DataGrid.markupFactory = function(props, node, ctor, cellFunc){
+ return dojox.grid._Grid.markupFactory(props, node, ctor,
+ dojo.partial(dojox.grid.DataGrid.cell_markupFactory, cellFunc));
+};
+
+}
+
+
+;
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/DataSelection.js b/js/dojo-1.6/dojox/grid/DataSelection.js
new file mode 100644
index 0000000..7715613
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/DataSelection.js
@@ -0,0 +1,76 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.DataSelection"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.DataSelection"] = true;
+dojo.provide("dojox.grid.DataSelection");
+dojo.require("dojox.grid.Selection");
+
+dojo.declare("dojox.grid.DataSelection", dojox.grid.Selection, {
+ getFirstSelected: function(){
+ var idx = dojox.grid.Selection.prototype.getFirstSelected.call(this);
+
+ if(idx == -1){ return null; }
+ return this.grid.getItem(idx);
+ },
+
+ getNextSelected: function(inPrev){
+ var old_idx = this.grid.getItemIndex(inPrev);
+ var idx = dojox.grid.Selection.prototype.getNextSelected.call(this, old_idx);
+
+ if(idx == -1){ return null; }
+ return this.grid.getItem(idx);
+ },
+
+ getSelected: function(){
+ var result = [];
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ result.push(this.grid.getItem(i));
+ }
+ }
+ return result;
+ },
+
+ addToSelection: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ dojox.grid.Selection.prototype.addToSelection.call(this, idx);
+ },
+
+ deselect: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ dojox.grid.Selection.prototype.deselect.call(this, idx);
+ },
+
+ deselectAll: function(inItemOrIndex){
+ var idx = null;
+ if(inItemOrIndex || typeof inItemOrIndex == "number"){
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ dojox.grid.Selection.prototype.deselectAll.call(this, idx);
+ }else{
+ this.inherited(arguments);
+ }
+ }
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/DataSelection.xd.js b/js/dojo-1.6/dojox/grid/DataSelection.xd.js
new file mode 100644
index 0000000..d82dac5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/DataSelection.xd.js
@@ -0,0 +1,81 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.DataSelection"],
+["require", "dojox.grid.Selection"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.DataSelection"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.DataSelection"] = true;
+dojo.provide("dojox.grid.DataSelection");
+dojo.require("dojox.grid.Selection");
+
+dojo.declare("dojox.grid.DataSelection", dojox.grid.Selection, {
+ getFirstSelected: function(){
+ var idx = dojox.grid.Selection.prototype.getFirstSelected.call(this);
+
+ if(idx == -1){ return null; }
+ return this.grid.getItem(idx);
+ },
+
+ getNextSelected: function(inPrev){
+ var old_idx = this.grid.getItemIndex(inPrev);
+ var idx = dojox.grid.Selection.prototype.getNextSelected.call(this, old_idx);
+
+ if(idx == -1){ return null; }
+ return this.grid.getItem(idx);
+ },
+
+ getSelected: function(){
+ var result = [];
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ result.push(this.grid.getItem(i));
+ }
+ }
+ return result;
+ },
+
+ addToSelection: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ dojox.grid.Selection.prototype.addToSelection.call(this, idx);
+ },
+
+ deselect: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ dojox.grid.Selection.prototype.deselect.call(this, idx);
+ },
+
+ deselectAll: function(inItemOrIndex){
+ var idx = null;
+ if(inItemOrIndex || typeof inItemOrIndex == "number"){
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ dojox.grid.Selection.prototype.deselectAll.call(this, idx);
+ }else{
+ this.inherited(arguments);
+ }
+ }
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/EnhancedGrid.js
new file mode 100644
index 0000000..b361935
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/EnhancedGrid.js
@@ -0,0 +1,265 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.EnhancedGrid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.EnhancedGrid"] = true;
+dojo.provide("dojox.grid.EnhancedGrid");
+
+dojo.require("dojox.grid.DataGrid");
+dojo.require("dojox.grid.enhanced._PluginManager");
+dojo.requireLocalization("dojox.grid.enhanced", "EnhancedGrid", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
+
+dojo.experimental("dojox.grid.EnhancedGrid");
+
+dojo.declare("dojox.grid.EnhancedGrid", dojox.grid.DataGrid, {
+ // summary:
+ // Provides enhanced features based on DataGrid
+ //
+ // description:
+ // EnhancedGrid features are implemented as plugins that could be loaded on demand.
+ // Explicit dojo.require() is needed to use these feature plugins.
+ //
+ // example:
+ // A quick sample to use EnhancedGrid features:
+ //
+ // Step 1. Load EnhancedGrid and required features
+ // | <script type="text/javascript">
+ // | dojo.require("dojox.grid.EnhancedGrid");
+ // | dojo.require("dojox.grid.enhanced.plugins.DnD");
+ // | dojo.require("dojox.grid.enhanced.plugins.Menu");
+ // | dojo.require("dojox.grid.enhanced.plugins.NestedSorting");
+ // | dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
+ // | </script>
+ //
+ // Step 2. Use EnhancedGrid
+ // - Via HTML markup
+ // | <div dojoType="dojox.grid.EnhancedGrid" ...
+ // | plugins="{nestedSorting: true, dnd: true, indirectSelection: true,
+ // | menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",
+ // | selectedRegionMenu:"selectedRegionMenuId"}}">
+ // | ...
+ // | </div>
+ //
+ // - Or via JavaScript
+ // | <script type="text/javascript">
+ // | var grid = new dojox.grid.EnhancedGrid({plugins : {nestedSorting: true, dnd: true, indirectSelection: true,
+ // | menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",selectedRegionMenu:"selectedRegionMenuId"}},
+ // | ... }, dojo.byId('gridDiv'));
+ // | grid.startup();
+ // | </script>
+ //
+ //
+ // Plugin Support
+ // [Note: Plugin support is still experimental]
+ //
+ // You can either customize the default plugins or add new ones, more details please see
+ // - dojox.grid.enhanced._PluginManager
+ // - dojox.grid.enhanced._Plugin
+ // - dojox.grid.enhanced.plugins.*
+
+ //plugins: Object
+ // Plugin properties, e.g. {nestedSorting: true, dnd: true, ...}
+ plugins: null,
+
+ //pluginMgr: Object
+ // Singleton plugin manager
+ pluginMgr: null,
+
+ //keepSelection: Boolean
+ // Whether keep selection after sort, filter, pagination etc.
+ keepSelection: false,
+
+ //_pluginMgrClass: Object
+ // Default plugin manager class
+ _pluginMgrClass: dojox.grid.enhanced._PluginManager,
+
+ postMixInProperties: function(){
+ //load nls bundle
+ this._nls = dojo.i18n.getLocalization("dojox.grid.enhanced", "EnhancedGrid", this.lang);
+ this.inherited(arguments);
+ },
+ postCreate: function(){
+ //create plugin manager
+ this.pluginMgr = new this._pluginMgrClass(this);
+ this.pluginMgr.preInit();
+ this.inherited(arguments);
+ this.pluginMgr.postInit();
+ },
+ plugin: function(/*String*/name){
+ // summary:
+ // An easier way for getting a plugin, e.g. grid.plugin('dnd')
+ return this.pluginMgr.getPlugin(name);
+ },
+ startup: function(){
+ this.inherited(arguments);
+ this.pluginMgr.startup();
+ },
+ createSelection: function(){
+ this.selection = new dojox.grid.enhanced.DataSelection(this);
+ },
+ canSort: function(colIndex, field){
+ // summary:
+ // Overwritten
+ return true;
+ },
+ doKeyEvent: function(e){
+ // summary:
+ // Overwritten, see _Grid.doKeyEvent()
+ var view = this.focus.focusView;
+ view.content.decorateEvent(e);
+ if(!e.cell){ view.header.decorateEvent(e); }
+ this.inherited(arguments);
+ },
+ doApplyCellEdit: function(inValue, inRowIndex, inAttrName){
+ // summary:
+ // Overwritten, see DataGrid.doApplyCellEdit()
+ if(!inAttrName){
+ this.invalidated[inRowIndex] = true;
+ return;
+ }
+ this.inherited(arguments);
+ },
+ mixin: function(target, source){
+ var props = {};
+ for(var p in source){
+ if(p == '_inherited' || p == 'declaredClass' || p == 'constructor' ||
+ source['privates'] && source['privates'][p]){
+ continue;
+ }
+ props[p] = source[p];
+ }
+ dojo.mixin(target, props);
+ },
+ _copyAttr: function(idx, attr){
+ // summary:
+ // Overwritten, see DataGrid._copyAttr()
+ // Fix cell TAB navigation for single click editing
+ if(!attr){ return; }
+ return this.inherited(arguments);
+ },
+ _getHeaderHeight: function(){
+ // summary:
+ // Overwritten, see _Grid._getHeaderHeight()
+ // Should include borders/margins of this.viewsHeaderNode
+ this.inherited(arguments);
+ return dojo.marginBox(this.viewsHeaderNode).h;
+ },
+ _fetch: function(start, isRender){
+ // summary:
+ // Overwritten, see DataGrid._fetch()
+ if(this.items){
+ return this.inherited(arguments);
+ }
+ start = start || 0;
+ if(this.store && !this._pending_requests[start]){
+ if(!this._isLoaded && !this._isLoading){
+ this._isLoading = true;
+ this.showMessage(this.loadingMessage);
+ }
+ this._pending_requests[start] = true;
+ try{
+ var req = {
+ start: start,
+ count: this.rowsPerPage,
+ query: this.query,
+ sort: this.getSortProps(),
+ queryOptions: this.queryOptions,
+ isRender: isRender,
+ onBegin: dojo.hitch(this, "_onFetchBegin"),
+ onComplete: dojo.hitch(this, "_onFetchComplete"),
+ onError: dojo.hitch(this, "_onFetchError")
+ };
+ this._storeLayerFetch(req);
+ }catch(e){
+ this._onFetchError(e, {start: start, count: this.rowsPerPage});
+ }
+ }
+ return 0;
+ },
+ _storeLayerFetch: function(req){
+ // summary:
+ // Extracted fetch specifically for store layer use
+ this.store.fetch(req);
+ },
+ getCellByField: function(field){
+ return dojo.filter(this.layout.cells, function(cell){
+ return cell.field == field;
+ })[0];
+ },
+ onMouseUp: function(e){ },
+ createView: function(){
+ // summary
+ // Overwrite: rewrite getCellX of view.header
+ var view = this.inherited(arguments);
+ if(dojo.isMoz){
+ var ascendDom = function(inNode, inWhile){
+ for(var n = inNode; n && inWhile(n); n = n.parentNode){}
+ return n;
+ };//copied from dojox.grid._Builder
+ var makeNotTagName = function(inTagName){
+ var name = inTagName.toUpperCase();
+ return function(node){ return node.tagName != name; };
+ };//copied from dojox.grid._Builder
+
+ var func = view.header.getCellX;
+ view.header.getCellX = function(e){
+ var x = func.call(view.header, e);
+ var n = ascendDom(e.target, makeNotTagName("th"));
+ if(n && n !== e.target && dojo.isDescendant(e.target, n)){ x += n.firstChild.offsetLeft; }
+ return x;
+ };
+ }
+ return view;
+ },
+ destroy: function(){
+ // summary:
+ // Destroy all resources
+ delete this._nls;
+ this.selection.destroy();
+ this.pluginMgr.destroy();
+ this.inherited(arguments);
+ }
+});
+
+dojo.provide("dojox.grid.enhanced.DataSelection");
+dojo.require("dojox.grid.enhanced.plugins._SelectionPreserver");//default loaded plugin
+
+dojo.declare("dojox.grid.enhanced.DataSelection", dojox.grid.DataSelection, {
+ constructor: function(grid){
+ if(grid.keepSelection){
+ this.preserver = new dojox.grid.enhanced.plugins._SelectionPreserver(this);
+ }
+ },
+ _range: function(inFrom, inTo){
+ this.grid._selectingRange = true;
+ this.inherited(arguments);
+ this.grid._selectingRange = false;
+ this.onChanged();
+ },
+ deselectAll: function(inItemOrIndex){
+ this.grid._selectingRange = true;
+ this.inherited(arguments);
+ this.grid._selectingRange = false;
+ this.onChanged();
+ },
+ destroy: function(){
+ if(this.preserver){
+ this.preserver.destroy();
+ }
+ }
+});
+
+dojox.grid.EnhancedGrid.markupFactory = function(props, node, ctor, cellFunc){
+ return dojox.grid._Grid.markupFactory(props, node, ctor,
+ dojo.partial(dojox.grid.DataGrid.cell_markupFactory, cellFunc));
+};
+
+dojox.grid.EnhancedGrid.registerPlugin = function(clazz, props){
+ dojox.grid.enhanced._PluginManager.registerPlugin(clazz, props);
+};
+
+}
diff --git a/js/dojo-1.6/dojox/grid/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/EnhancedGrid.xd.js
new file mode 100644
index 0000000..7171d73
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/EnhancedGrid.xd.js
@@ -0,0 +1,274 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.EnhancedGrid"],
+["require", "dojox.grid.DataGrid"],
+["require", "dojox.grid.enhanced._PluginManager"],
+["requireLocalization", "dojox.grid.enhanced", "EnhancedGrid", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw", "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw"],
+["provide", "dojox.grid.enhanced.DataSelection"],
+["require", "dojox.grid.enhanced.plugins._SelectionPreserver"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.EnhancedGrid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.EnhancedGrid"] = true;
+dojo.provide("dojox.grid.EnhancedGrid");
+
+dojo.require("dojox.grid.DataGrid");
+dojo.require("dojox.grid.enhanced._PluginManager");
+;
+
+dojo.experimental("dojox.grid.EnhancedGrid");
+
+dojo.declare("dojox.grid.EnhancedGrid", dojox.grid.DataGrid, {
+ // summary:
+ // Provides enhanced features based on DataGrid
+ //
+ // description:
+ // EnhancedGrid features are implemented as plugins that could be loaded on demand.
+ // Explicit dojo.require() is needed to use these feature plugins.
+ //
+ // example:
+ // A quick sample to use EnhancedGrid features:
+ //
+ // Step 1. Load EnhancedGrid and required features
+ // | <script type="text/javascript">
+ // | dojo.require("dojox.grid.EnhancedGrid");
+ // | dojo.require("dojox.grid.enhanced.plugins.DnD");
+ // | dojo.require("dojox.grid.enhanced.plugins.Menu");
+ // | dojo.require("dojox.grid.enhanced.plugins.NestedSorting");
+ // | dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
+ // | </script>
+ //
+ // Step 2. Use EnhancedGrid
+ // - Via HTML markup
+ // | <div dojoType="dojox.grid.EnhancedGrid" ...
+ // | plugins="{nestedSorting: true, dnd: true, indirectSelection: true,
+ // | menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",
+ // | selectedRegionMenu:"selectedRegionMenuId"}}">
+ // | ...
+ // | </div>
+ //
+ // - Or via JavaScript
+ // | <script type="text/javascript">
+ // | var grid = new dojox.grid.EnhancedGrid({plugins : {nestedSorting: true, dnd: true, indirectSelection: true,
+ // | menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",selectedRegionMenu:"selectedRegionMenuId"}},
+ // | ... }, dojo.byId('gridDiv'));
+ // | grid.startup();
+ // | </script>
+ //
+ //
+ // Plugin Support
+ // [Note: Plugin support is still experimental]
+ //
+ // You can either customize the default plugins or add new ones, more details please see
+ // - dojox.grid.enhanced._PluginManager
+ // - dojox.grid.enhanced._Plugin
+ // - dojox.grid.enhanced.plugins.*
+
+ //plugins: Object
+ // Plugin properties, e.g. {nestedSorting: true, dnd: true, ...}
+ plugins: null,
+
+ //pluginMgr: Object
+ // Singleton plugin manager
+ pluginMgr: null,
+
+ //keepSelection: Boolean
+ // Whether keep selection after sort, filter, pagination etc.
+ keepSelection: false,
+
+ //_pluginMgrClass: Object
+ // Default plugin manager class
+ _pluginMgrClass: dojox.grid.enhanced._PluginManager,
+
+ postMixInProperties: function(){
+ //load nls bundle
+ this._nls = dojo.i18n.getLocalization("dojox.grid.enhanced", "EnhancedGrid", this.lang);
+ this.inherited(arguments);
+ },
+ postCreate: function(){
+ //create plugin manager
+ this.pluginMgr = new this._pluginMgrClass(this);
+ this.pluginMgr.preInit();
+ this.inherited(arguments);
+ this.pluginMgr.postInit();
+ },
+ plugin: function(/*String*/name){
+ // summary:
+ // An easier way for getting a plugin, e.g. grid.plugin('dnd')
+ return this.pluginMgr.getPlugin(name);
+ },
+ startup: function(){
+ this.inherited(arguments);
+ this.pluginMgr.startup();
+ },
+ createSelection: function(){
+ this.selection = new dojox.grid.enhanced.DataSelection(this);
+ },
+ canSort: function(colIndex, field){
+ // summary:
+ // Overwritten
+ return true;
+ },
+ doKeyEvent: function(e){
+ // summary:
+ // Overwritten, see _Grid.doKeyEvent()
+ var view = this.focus.focusView;
+ view.content.decorateEvent(e);
+ if(!e.cell){ view.header.decorateEvent(e); }
+ this.inherited(arguments);
+ },
+ doApplyCellEdit: function(inValue, inRowIndex, inAttrName){
+ // summary:
+ // Overwritten, see DataGrid.doApplyCellEdit()
+ if(!inAttrName){
+ this.invalidated[inRowIndex] = true;
+ return;
+ }
+ this.inherited(arguments);
+ },
+ mixin: function(target, source){
+ var props = {};
+ for(var p in source){
+ if(p == '_inherited' || p == 'declaredClass' || p == 'constructor' ||
+ source['privates'] && source['privates'][p]){
+ continue;
+ }
+ props[p] = source[p];
+ }
+ dojo.mixin(target, props);
+ },
+ _copyAttr: function(idx, attr){
+ // summary:
+ // Overwritten, see DataGrid._copyAttr()
+ // Fix cell TAB navigation for single click editing
+ if(!attr){ return; }
+ return this.inherited(arguments);
+ },
+ _getHeaderHeight: function(){
+ // summary:
+ // Overwritten, see _Grid._getHeaderHeight()
+ // Should include borders/margins of this.viewsHeaderNode
+ this.inherited(arguments);
+ return dojo.marginBox(this.viewsHeaderNode).h;
+ },
+ _fetch: function(start, isRender){
+ // summary:
+ // Overwritten, see DataGrid._fetch()
+ if(this.items){
+ return this.inherited(arguments);
+ }
+ start = start || 0;
+ if(this.store && !this._pending_requests[start]){
+ if(!this._isLoaded && !this._isLoading){
+ this._isLoading = true;
+ this.showMessage(this.loadingMessage);
+ }
+ this._pending_requests[start] = true;
+ try{
+ var req = {
+ start: start,
+ count: this.rowsPerPage,
+ query: this.query,
+ sort: this.getSortProps(),
+ queryOptions: this.queryOptions,
+ isRender: isRender,
+ onBegin: dojo.hitch(this, "_onFetchBegin"),
+ onComplete: dojo.hitch(this, "_onFetchComplete"),
+ onError: dojo.hitch(this, "_onFetchError")
+ };
+ this._storeLayerFetch(req);
+ }catch(e){
+ this._onFetchError(e, {start: start, count: this.rowsPerPage});
+ }
+ }
+ return 0;
+ },
+ _storeLayerFetch: function(req){
+ // summary:
+ // Extracted fetch specifically for store layer use
+ this.store.fetch(req);
+ },
+ getCellByField: function(field){
+ return dojo.filter(this.layout.cells, function(cell){
+ return cell.field == field;
+ })[0];
+ },
+ onMouseUp: function(e){ },
+ createView: function(){
+ // summary
+ // Overwrite: rewrite getCellX of view.header
+ var view = this.inherited(arguments);
+ if(dojo.isMoz){
+ var ascendDom = function(inNode, inWhile){
+ for(var n = inNode; n && inWhile(n); n = n.parentNode){}
+ return n;
+ };//copied from dojox.grid._Builder
+ var makeNotTagName = function(inTagName){
+ var name = inTagName.toUpperCase();
+ return function(node){ return node.tagName != name; };
+ };//copied from dojox.grid._Builder
+
+ var func = view.header.getCellX;
+ view.header.getCellX = function(e){
+ var x = func.call(view.header, e);
+ var n = ascendDom(e.target, makeNotTagName("th"));
+ if(n && n !== e.target && dojo.isDescendant(e.target, n)){ x += n.firstChild.offsetLeft; }
+ return x;
+ };
+ }
+ return view;
+ },
+ destroy: function(){
+ // summary:
+ // Destroy all resources
+ delete this._nls;
+ this.selection.destroy();
+ this.pluginMgr.destroy();
+ this.inherited(arguments);
+ }
+});
+
+dojo.provide("dojox.grid.enhanced.DataSelection");
+dojo.require("dojox.grid.enhanced.plugins._SelectionPreserver");//default loaded plugin
+
+dojo.declare("dojox.grid.enhanced.DataSelection", dojox.grid.DataSelection, {
+ constructor: function(grid){
+ if(grid.keepSelection){
+ this.preserver = new dojox.grid.enhanced.plugins._SelectionPreserver(this);
+ }
+ },
+ _range: function(inFrom, inTo){
+ this.grid._selectingRange = true;
+ this.inherited(arguments);
+ this.grid._selectingRange = false;
+ this.onChanged();
+ },
+ deselectAll: function(inItemOrIndex){
+ this.grid._selectingRange = true;
+ this.inherited(arguments);
+ this.grid._selectingRange = false;
+ this.onChanged();
+ },
+ destroy: function(){
+ if(this.preserver){
+ this.preserver.destroy();
+ }
+ }
+});
+
+dojox.grid.EnhancedGrid.markupFactory = function(props, node, ctor, cellFunc){
+ return dojox.grid._Grid.markupFactory(props, node, ctor,
+ dojo.partial(dojox.grid.DataGrid.cell_markupFactory, cellFunc));
+};
+
+dojox.grid.EnhancedGrid.registerPlugin = function(clazz, props){
+ dojox.grid.enhanced._PluginManager.registerPlugin(clazz, props);
+};
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/LazyTreeGrid.js b/js/dojo-1.6/dojox/grid/LazyTreeGrid.js
new file mode 100644
index 0000000..da4316d
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/LazyTreeGrid.js
@@ -0,0 +1,823 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.LazyTreeGrid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.LazyTreeGrid"] = true;
+dojo.provide("dojox.grid.LazyTreeGrid");
+
+dojo.require("dojox.grid._View");
+dojo.require("dojox.grid.TreeGrid");
+dojo.require("dojox.grid.cells.tree");
+dojo.require("dojox.grid.LazyTreeGridStoreModel");
+
+dojo.declare("dojox.grid._LazyExpando", [dijit._Widget, dijit._Templated], {
+ itemId: "",
+ cellIdx: -1,
+ view: null,
+ rowIdx: -1,
+ expandoCell: null,
+ level: 0,
+ open: false,
+ templateString:"<div class=\"dojoxGridExpando\"\r\n\t><div class=\"dojoxGridExpandoNode\" dojoAttachEvent=\"onclick:onToggle\"\r\n\t\t><div class=\"dojoxGridExpandoNodeInner\" dojoAttachPoint=\"expandoInner\"></div\r\n\t></div\r\n></div>\r\n",
+
+ onToggle: function(event){
+ // Summary
+ // Function for expand/collapse row
+ this.setOpen(!this.view.grid.cache.getExpandoStatusByRowIndex(this.rowIdx));
+ try{
+ dojo.stopEvent(event);
+ }catch(e){}
+ },
+
+ setOpen: function(open){
+ var g = this.view.grid,
+ item = g.cache.getItemByRowIndex(this.rowIdx);
+ if(!g.treeModel.mayHaveChildren(item)){
+ g.stateChangeNode = null;
+ return;
+ }
+ if(item){
+ g.stateChangeNode = this.domNode;
+ g.cache.updateCache(this.rowIdx, {"expandoStatus": open});
+ g.expandoFetch(this.rowIdx, open);
+ this.open = open;
+ }
+ this._updateOpenState(item);
+ },
+
+ _updateOpenState: function(item){
+ // Summary
+ // Update the expando icon
+ var grid = this.view.grid;
+ if(item && grid.treeModel.mayHaveChildren(item)){
+ var state = grid.cache.getExpandoStatusByRowIndex(this.rowIdx);
+ this.expandoInner.innerHTML = state ? "-" : "+";
+ dojo.toggleClass(this.domNode, "dojoxGridExpandoOpened", state);
+ }
+ },
+
+ setRowNode: function(rowIdx, rowNode, view){
+ if(this.cellIdx < 0 || !this.itemId){ return false; }
+ this._initialized = false;
+ this.view = view;
+ this.rowIdx = rowIdx;
+ this.expandoCell = view.structure.cells[0][this.cellIdx];
+ var d = this.domNode;
+ if(d && d.parentNode && d.parentNode.parentNode){
+ this._tableRow = d.parentNode.parentNode;
+ }
+ dojo.style(this.domNode , "marginLeft" , (this.level * 1.125) + "em");
+ this._updateOpenState(view.grid.cache.getItemByRowIndex(this.rowIdx));
+ return true;
+ }
+});
+
+dojo.declare("dojox.grid._TreeGridContentBuilder", dojox.grid._ContentBuilder, {
+ // summary:
+ // Could create row content innerHTML by different appoarch for different data structure
+ generateHtml: function(inDataIndex, inRowIndex){
+ // summary:
+ // create row innterHTML for flat data structure
+ var html = this.getTableArray(),
+ grid = this.grid,
+ v = this.view,
+ cells = v.structure.cells,
+ item = grid.getItem(inRowIndex),
+ level = 0,
+ treePath = grid.cache.getTreePathByRowIndex(inRowIndex),
+ rowStack = [],
+ toggleClasses = [];
+
+ dojox.grid.util.fire(this.view, "onBeforeRow", [inRowIndex, cells]);
+
+ if(item !== null && treePath !== null){
+ rowStack = treePath.split("/");
+ level = rowStack.length - 1;
+ toggleClasses[0] = "dojoxGridRowToggle-" + rowStack.join("-");
+ if(!grid.treeModel.mayHaveChildren(item)){
+ toggleClasses.push("dojoxGridNoChildren");
+ }
+ }
+
+ for(var j = 0, row; (row = cells[j]); j++){
+ if(row.hidden || row.header){
+ continue;
+ }
+ var tr = '<tr style="" class="' + toggleClasses.join(' ') + '" dojoxTreeGridPath="' + rowStack.join('/') + '" dojoxTreeGridBaseClasses="' + toggleClasses.join(' ') + '">';
+ html.push(tr);
+ var k = 0, mergedCells = this._getColSpans(level);
+ var totalWidth = 0, totalWidthes = [];
+ if(mergedCells){
+ dojo.forEach(mergedCells, function(c){
+ for(var i = 0, cell;(cell = row[i]); i++){
+ if(i >= c.start && i <= c.end){
+ totalWidth += this._getCellWidth(row, i);
+ }
+ }
+ totalWidthes.push(totalWidth);
+ totalWidth = 0;
+ }, this);
+ }
+ for(var i = 0, cell, m, cc, cs; (cell = row[i]); i++){
+ m = cell.markup;
+ cc = cell.customClasses = [];
+ cs = cell.customStyles = [];
+ if(mergedCells && mergedCells[k] && (i >= mergedCells[k].start && i <= mergedCells[k].end)){
+ var primaryIdx = mergedCells[k].primary ? mergedCells[k].primary : mergedCells[k].start;
+ if(i == primaryIdx){
+ m[5] = cell.formatAtLevel(rowStack, item, level, false, toggleClasses[0], cc, inRowIndex);
+ // classes
+ m[1] = cc.join(' ');
+ // styles
+ var pbm = dojo.marginBox(cell.getHeaderNode()).w - dojo.contentBox(cell.getHeaderNode()).w;
+ cs = cell.customStyles = ['width:' + (totalWidthes[k] - pbm) + "px"];
+ m[3] = cs.join(';');
+ html.push.apply(html, m);
+ }else if(i == mergedCells[k].end){
+ k++;
+ continue;
+ }else{
+ continue;
+ }
+ }else{
+ // content (format can fill in cc and cs as side-effects)
+ // m[5] = cell.format(inRowIndex, item);
+ m[5] = cell.formatAtLevel(rowStack, item, level, false, toggleClasses[0], cc, inRowIndex);
+ // classes
+ m[1] = cc.join(' ');
+ // styles
+ m[3] = cs.join(';');
+ // in-place concat
+ html.push.apply(html, m);
+ }
+
+ }
+ html.push('</tr>');
+ }
+ html.push('</table>');
+ return html.join(''); // String
+ },
+
+ _getColSpans: function(level){
+ // summary:
+ // handle the column span object
+ var colSpans = this.grid.colSpans;
+ if(colSpans && (colSpans[level])){
+ return colSpans[level];
+ }else{
+ return null;
+ }
+ },
+
+ _getCellWidth: function(cells, colIndex){
+ // summary:
+ // calculate column width by header cell's size
+ var node = cells[colIndex].getHeaderNode();
+ if(colIndex == cells.length - 1 || dojo.every(cells.slice(colIndex + 1), function(cell){
+ return cell.hidden;
+ })){
+ var headerNodePos = dojo.position(cells[colIndex].view.headerContentNode.firstChild);
+ return headerNodePos.x + headerNodePos.w - dojo.position(node).x;
+ }else{
+ var nextNode = cells[colIndex + 1].getHeaderNode();
+ return dojo.position(nextNode).x - dojo.position(node).x;
+ }
+ }
+});
+
+dojo.declare("dojox.grid._TreeGridView", [dojox.grid._View], {
+
+ _contentBuilderClass: dojox.grid._TreeGridContentBuilder,
+
+ postCreate: function(){
+ this.inherited(arguments);
+ this._expandos = {};
+ this.connect(this.grid, '_cleanupExpandoCache', '_cleanupExpandoCache');
+ },
+
+ _cleanupExpandoCache: function(index, identity, item){
+ if(index == -1){
+ return;
+ }
+ dojo.forEach(this.grid.layout.cells, function(cell){
+ if(cell.openStates && identity in cell.openStates){
+ delete cell.openStates[identity];
+ }
+ });
+ for(var i in this._expandos){
+ if(this._expandos[i]){
+ this._expandos[i].destroy();
+ }
+ }
+ this._expandos = {};
+ },
+
+ onAfterRow: function(inRowIndex, cells, inRowNode){
+ // summary:
+ // parse the expando of each row to a widget
+ dojo.query("span.dojoxGridExpando", inRowNode).forEach(function(n){
+ if(n && n.parentNode){
+ // Either create our expando or put the existing expando back
+ // into place
+ var idty, expando, _byIdx = this.grid._by_idx;
+ if(_byIdx && _byIdx[inRowIndex] && _byIdx[inRowIndex].idty){
+ idty = _byIdx[inRowIndex].idty;
+ expando = this._expandos[idty];
+ }
+ if(expando){
+ dojo.place(expando.domNode, n, "replace");
+ expando.itemId = n.getAttribute("itemId");
+ expando.cellIdx = parseInt(n.getAttribute("cellIdx"), 10);
+ if(isNaN(expando.cellIdx)){
+ expando.cellIdx = -1;
+ }
+ }else{
+ expando = dojo.parser.parse(n.parentNode)[0];
+ if(idty){
+ this._expandos[idty] = expando;
+ }
+ }
+ if(!expando.setRowNode(inRowIndex, inRowNode, this)){
+ expando.domNode.parentNode.removeChild(expando.domNode);
+ }
+ }
+ }, this);
+ this.inherited(arguments);
+ }
+
+});
+
+dojo.mixin(dojox.grid.cells.TreeCell, {
+ formatAtLevel: function(inRowIndexes, inItem, level, summaryRow, toggleClass, cellClasses, inRowIndex){
+ if(!inItem){
+ return this.formatIndexes(inRowIndex, inRowIndexes, inItem, level);
+ }
+ if(!dojo.isArray(inRowIndexes)){
+ inRowIndexes = [inRowIndexes];
+ }
+ var result = "";
+ var ret = "";
+ if(this.isCollapsable){
+ var store = this.grid.store, id = "";
+ if(inItem && store.isItem(inItem)){
+ id = store.getIdentity(inItem);
+ }
+ cellClasses.push("dojoxGridExpandoCell");
+ ret = '<span ' + dojo._scopeName + 'Type="dojox.grid._LazyExpando" level="' + level + '" class="dojoxGridExpando"' +
+ '" toggleClass="' + toggleClass + '" itemId="' + id + '" cellIdx="' + this.index + '"></span>';
+ }
+ result = ret + this.formatIndexes(inRowIndex, inRowIndexes, inItem, level);
+ if(this.grid.focus.cell && this.index == this.grid.focus.cell.index && inRowIndexes.join('/') == this.grid.focus.rowIndex){
+ cellClasses.push(this.grid.focus.focusClass);
+ }
+ return result;
+ },
+
+ formatIndexes: function(inRowIndex, inRowIndexes, inItem, level){
+ var info = this.grid.edit.info,
+ d = this.get ? this.get(inRowIndexes[0], inItem, inRowIndexes) : (this.value || this.defaultValue);
+ if(this.editable && (this.alwaysEditing || (info.rowIndex == inRowIndexes[0] && info.cell == this))){
+ return this.formatEditing(d, inRowIndex, inRowIndexes);
+ }else{
+ return this._defaultFormat(d, [d, inRowIndex, level, this]);
+ }
+ }
+});
+
+dojo.declare("dojox.grid._LazyTreeLayout", dojox.grid._Layout, {
+ // summary:
+ // Override the dojox.grid._TreeLayout to modify the _TreeGridView and cell formatter
+ setStructure: function(inStructure){
+ var s = inStructure;
+ var g = this.grid;
+ if(g && !dojo.every(s, function(i){
+ return ("cells" in i);
+ })){
+ s = arguments[0] = [{cells:[s]}];//intentionally change arguments[0]
+ }
+ if(s.length == 1 && s[0].cells.length == 1){
+ s[0].type = "dojox.grid._TreeGridView";
+ this._isCollapsable = true;
+ s[0].cells[0][this.grid.expandoCell].isCollapsable = true;
+ }
+ this.inherited(arguments);
+ },
+
+ addCellDef: function(inRowIndex, inCellIndex, inDef){
+ var obj = this.inherited(arguments);
+ return dojo.mixin(obj, dojox.grid.cells.TreeCell);
+ }
+});
+
+dojo.declare("dojox.grid.TreeGridItemCache", null, {
+
+ unInit: true,
+
+ items: null,
+
+ constructor: function(grid){
+ this.rowsPerPage = grid.rowsPerPage;
+ this._buildCache(grid.rowsPerPage);
+ },
+
+ _buildCache: function(size){
+ // Summary
+ // Build the cache only with the treepath using given size
+ this.items = [];
+ for(var i = 0; i < size; i++){
+ this.cacheItem(i, {item: null, treePath: i + "", expandoStatus: false});
+ }
+ },
+
+ cacheItem: function(/*integer*/rowIdx, cacheObj){
+ // Summary
+ // Add an item and its tree structure information to the cache.
+ this.items[rowIdx] = dojo.mixin({
+ item: null,
+ treePath: "",
+ expandoStatus: false
+ }, cacheObj);
+ },
+
+ insertItem: function(/*integer*/rowIdx, cacheObj){
+ this.items.splice(rowIdx, 0, dojo.mixin({
+ item: null,
+ treePath: "",
+ expandoStatus: false
+ }, cacheObj));
+ },
+
+ initCache: function(size){
+ if(!this.unInit){ return; }
+ this._buildCache(size);
+ this.unInit = false;
+ },
+
+ getItemByRowIndex: function(/*integer*/rowIdx){
+ return this.items[rowIdx] ? this.items[rowIdx].item : null;
+ },
+
+ getItemByTreePath: function(treePath){
+ for(var i = 0, len = this.items.length; i < len; i++){
+ if(this.items[i].treePath === treePath){
+ return this.items[i].item;
+ }
+ }
+ return null;
+ },
+
+ getTreePathByRowIndex: function(/*integer*/rowIdx){
+ return this.items[rowIdx] ? this.items[rowIdx].treePath : null;
+ },
+
+ getExpandoStatusByRowIndex: function(/*integer*/rowIdx){
+ return this.items[rowIdx] ? this.items[rowIdx].expandoStatus : null;
+ },
+
+ getInfoByItem: function(item){
+ for(var i = 0, len = this.items.length; i < len; i++){
+ if(this.items[i].item == item){
+ return dojo.mixin({rowIdx: i}, this.items[i]);
+ }
+ }
+ return null;
+ },
+
+ updateCache: function(/*integer*/rowIdx, cacheObj){
+ if(this.items[rowIdx]){
+ dojo.mixin(this.items[rowIdx], cacheObj);
+ }
+ },
+
+ deleteItem: function(rowIdx){
+ if(this.items[rowIdx]){
+ this.items.splice(rowIdx, 1);
+ }
+ },
+
+ cleanChildren: function(rowIdx){
+ var treePath = this.getTreePathByRowIndex(rowIdx);
+ for(var i = this.items.length - 1; i >= 0; i--){
+ if(this.items[i].treePath.indexOf(treePath) === 0 && this.items[i].treePath !== treePath){
+ this.items.splice(i, 1);
+ }
+ }
+ },
+
+ emptyCache: function(){
+ this.unInit = true;
+ this._buildCache(this.rowsPerPage);
+ },
+
+ cleanupCache: function(){
+ this.items = null;
+ }
+
+});
+
+dojo.declare("dojox.grid.LazyTreeGrid", dojox.grid.TreeGrid, {
+ // summary:
+ // An enhanced TreeGrid widget which supports lazy-loading nested-level items
+ //
+ // description:
+ // LazyTreeGrid inherits from dojo.grid.TreeGrid, and applies virtual scrolling mechanism
+ // to nested children rows so that it's possible to deal with large data set specifically
+ // in tree structure with large number of children rows. It's also compatible with dijit.tree.ForestStoreModel
+ //
+ // Most methods and properties pertaining to the dojox.grid.DataGrid
+ // and dojox.grid.TreeGrid also apply here
+ //
+ // LazyTreeGrid does not support summary row/items aggregate for the
+ // lazy-loading reason.
+
+ treeModel: null,
+
+ _layoutClass: dojox.grid._LazyTreeLayout,
+
+ // colSpans: Object
+ // a json object that defines column span of each level rows
+ // attributes:
+ // 0/1/..: which level need to colspan
+ // start: start column index of colspan
+ // end: end column index of colspan
+ // primary: index of column which content will be displayed (default is value of start).
+ // example:
+ // | colSpans = {
+ // | 0: [
+ // | {start: 0, end: 1, primary: 0},
+ // | {start: 2, end: 4, primary: 3}
+ // | ],
+ // | 1: [
+ // | {start: 0, end: 3, primary: 1}
+ // | ]
+ // | };
+ colSpans: null,
+
+ postCreate: function(){
+ this.inherited(arguments);
+ this.cache = new dojox.grid.TreeGridItemCache(this);
+ if(!this.treeModel || !(this.treeModel instanceof dijit.tree.ForestStoreModel)){
+ throw new Error("dojox.grid.LazyTreeGrid: must use a treeModel and treeModel must be an instance of dijit.tree.ForestStoreModel");
+ }
+ dojo.addClass(this.domNode, "dojoxGridTreeModel");
+ dojo.setSelectable(this.domNode, this.selectable);
+ },
+
+ createManagers: function(){
+ // summary:
+ // create grid managers for various tasks including rows, focus, selection, editing
+ this.rows = new dojox.grid._RowManager(this);
+ this.focus = new dojox.grid._FocusManager(this);
+ this.edit = new dojox.grid._EditManager(this);
+ },
+
+ createSelection: function(){
+ this.selection = new dojox.grid.DataSelection(this);
+ },
+
+ setModel: function(treeModel){
+ if(!treeModel){
+ return;
+ }
+ this._setModel(treeModel);
+ this._refresh(true);
+ },
+
+ setStore: function(store, query, queryOptions){
+ if(!store){
+ return;
+ }
+ this._setQuery(query, queryOptions);
+ this.treeModel.query = query;
+ this.treeModel.store = store;
+ this.treeModel.root.children = [];
+ this.setModel(this.treeModel);
+ },
+
+ _setQuery: function(query, queryOptions){
+ this.inherited(arguments);
+ this.treeModel.query = query;
+ },
+
+ destroy: function(){
+ this._cleanup();
+ this.inherited(arguments);
+ },
+
+ _cleanup: function(){
+ this.cache.emptyCache();
+ this._cleanupExpandoCache();
+ },
+
+ setSortIndex: function(inIndex, inAsc){
+ // Need to clean up the cache before sorting
+ this._cleanup();
+ this.inherited(arguments);
+ },
+
+ _refresh: function(isRender){
+ this._cleanup();
+ this.inherited(arguments);
+ },
+
+ render: function(){
+ this.inherited(arguments);
+ this.setScrollTop(this.scrollTop);
+ },
+
+ _onNew: function(item, parentInfo){
+ var isAddingChild = false;
+ var info;
+ if(parentInfo && this.store.isItem(parentInfo.item) && dojo.some(this.treeModel.childrenAttrs, function(c){
+ return c === parentInfo.attribute;
+ })){
+ isAddingChild = true;
+ info = this.cache.getInfoByItem(parentInfo.item);
+ }
+ if(!isAddingChild){
+ this.inherited(arguments);
+ var items = this.cache.items;
+ var treePath = (parseInt(items[items.length - 1].treePath.split("/")[0], 10) + 1) + "";
+ this.cache.insertItem(this.get('rowCount'), {item: item, treePath: treePath, expandoStatus: false});
+ }else if(info && info.expandoStatus && info.rowIdx >= 0){
+ this.expandoFetch(info.rowIdx, false);
+ this.expandoFetch(info.rowIdx, true);
+ }else if(info && info.rowIdx){
+ this.updateRow(info.rowIdx);
+ }
+ },
+
+ _onDelete: function(item){
+ this._pages = [];
+ this._bop = -1;
+ this._eop = -1;
+ this._refresh();
+ },
+
+ _cleanupExpandoCache: function(index, identity, item){},
+
+ _fetch: function(start, isRender){
+ // summary:
+ // Function for fetch data when initializing TreeGrid and
+ // scroll the TreeGrid
+ start = start || 0;
+ this.reqQueue = [];
+ this.showMessage(this.loadingMessage);
+ // Check cache, do not need to fetch data if there are required data in cache
+ var i = 0, fetchedItems = [];
+ var count = Math.min(this.rowsPerPage, this.cache.items.length - start);
+ for(i = start; i < count; i++){
+ if(this.cache.getItemByRowIndex(i)){
+ fetchedItems.push(this.cache.getItemByRowIndex(i));
+ }else{
+ break;
+ }
+ }
+ if(fetchedItems.length === count){// || !this.cache.getTreePathByRowIndex(start + fetchedItems.length)){
+ this._onFetchComplete(fetchedItems, {startRowIdx: start, count: count});
+ }else{
+ // In case there need different level data, we need to do multiple fetch.
+ // Do next fetch only when the last request complete.
+ this.reqQueueIndex = 0;
+ var level = "",
+ nextRowLevel = "",
+ startRowIdx = start,
+ startTreePath = this.cache.getTreePathByRowIndex(start);
+ count = 0;
+ // Create request queue
+ for(i = start + 1; i < start + this.rowsPerPage; i++){
+ if(!this.cache.getTreePathByRowIndex(i)){
+ break;
+ }
+ level = this.cache.getTreePathByRowIndex(i - 1).split("/").length - 1;
+ nextRowLevel = this.cache.getTreePathByRowIndex(i).split("/").length - 1;
+ if(level !== nextRowLevel){
+ this.reqQueue.push({
+ startTreePath: startTreePath,
+ startRowIdx: startRowIdx,
+ count: count + 1
+ });
+ count = 0;
+ startRowIdx = i;
+ startTreePath = this.cache.getTreePathByRowIndex(i);
+ }else{
+ count++;
+ }
+ }
+ this.reqQueue.push({
+ startTreePath: startTreePath,
+ startRowIdx: startRowIdx,
+ count: count + 1
+ });
+ var len = this.reqQueue.length;
+ for(i = 0; i < len; i++){
+ this._fetchItems(i, dojo.hitch(this, "_onFetchBegin"), dojo.hitch(this, "_onFetchComplete"), dojo.hitch(this, "_onFetchError"));
+ }
+ }
+ },
+
+ _fetchItems: function(idx, onBegin, onComplete, onError){
+ var level = this.reqQueue[idx].startTreePath.split("/").length - 1;
+ this._pending_requests[this.reqQueue[idx].startRowIdx] = true;
+ if(level === 0){
+ this.store.fetch({
+ start: parseInt(this.reqQueue[idx].startTreePath, 10),
+ startRowIdx: this.reqQueue[idx].startRowIdx,
+ count: this.reqQueue[idx].count,
+ query: this.query,
+ sort: this.getSortProps(),
+ queryOptions: this.queryOptions,
+ onBegin: onBegin,
+ onComplete: onComplete,
+ onError: onError
+ });
+ }else{
+ var startTreePath = this.reqQueue[idx].startTreePath;
+ var parentTreePath = startTreePath.substring(0, startTreePath.lastIndexOf("/"));
+ var startIdx = startTreePath.substring(startTreePath.lastIndexOf("/") + 1);
+ var parentItem = this.cache.getItemByTreePath(parentTreePath);
+ if(!parentItem){
+ throw new Error("Lazy loading TreeGrid on fetch error:");
+ }
+ var parentId = this.store.getIdentity(parentItem);
+ this.queryObj = {
+ start: parseInt(startIdx, 10),
+ startRowIdx: this.reqQueue[idx].startRowIdx,
+ count: this.reqQueue[idx].count,
+ parentId: parentId,
+ sort: this.getSortProps()
+ };
+ this.treeModel.getChildren(parentItem, onComplete, onError, this.queryObj);
+ }
+ },
+
+ _onFetchBegin: function(size, request){
+ this.cache.initCache(size);
+ size = this.cache.items.length;
+ this.inherited(arguments);
+ },
+
+ _onFetchComplete: function(items, request, size){
+ var treePath = "",
+ startRowIdx, count, start;
+
+ if(request){
+ startRowIdx = request.startRowIdx;
+ count = request.count;
+ start = 0;
+ }else{
+ startRowIdx = this.queryObj.startRowIdx;
+ count = this.queryObj.count;
+ start = this.queryObj.start;
+ }
+
+ for(var i = 0; i < count; i++){
+ treePath = this.cache.getTreePathByRowIndex(startRowIdx + i);
+ if(treePath){
+ if(!this.cache.getItemByRowIndex(startRowIdx + i)){
+ this.cache.cacheItem(startRowIdx + i, {
+ item: items[start + i],
+ treePath: treePath,
+ expandoStatus: false
+ });
+ }
+ }
+ }
+ this._pending_requests[startRowIdx] = false;
+ // Add items when all request complete
+ if(!this.scroller){
+ return;
+ }
+ var len = Math.min(count, items.length);
+ for(i = 0; i < len; i++){
+ this._addItem(items[start + i], startRowIdx + i, true);
+ }
+ this.updateRows(startRowIdx, len);
+ if(this._lastScrollTop){
+ this.setScrollTop(this._lastScrollTop);
+ }
+ if(!this.cache.items.length){
+ this.showMessage(this.noDataMessage);
+ }else{
+ this.showMessage();
+ }
+ },
+
+ expandoFetch: function(rowIndex, open){
+ // summary:
+ // Function for fetch children of a given row
+ this.toggleLoadingClass(true);
+ var item = this.cache.getItemByRowIndex(rowIndex);
+ this.expandoRowIndex = rowIndex;
+ this._pages = [];
+ if(open){
+ var parentId = this.store.getIdentity(item);
+ var queryObj = {
+ start: 0,
+ count: this.keepRows,
+ parentId: parentId,
+ sort: this.getSortProps()
+ };
+ this.treeModel.getChildren(item, dojo.hitch(this, "_onExpandoComplete"), dojo.hitch(this, "_onFetchError"), queryObj);
+ }else{
+ this.cache.cleanChildren(rowIndex);
+ for(var i = rowIndex + 1, len = this._by_idx.length; i < len; i++){
+ delete this._by_idx[i];
+ }
+ this.updateRowCount(this.cache.items.length);
+ if(this.cache.getTreePathByRowIndex(rowIndex + 1)){
+ this._fetch(rowIndex + 1);
+ }else{
+ this._fetch(rowIndex);
+ }
+ this.toggleLoadingClass(false);
+ }
+ },
+
+ _onExpandoComplete: function(childItems, request, size){
+ var parentTreePath = this.cache.getTreePathByRowIndex(this.expandoRowIndex);
+ if(size && !isNaN(parseInt(size, 10))){
+ size = parseInt(size, 10);
+ }else{
+ size = childItems.length;
+ }
+ var i, j = 0, len = this._by_idx.length;
+ for(i = this.expandoRowIndex + 1; j < size; i++, j++){
+ this.cache.insertItem(i, {
+ item: null,
+ treePath: parentTreePath + "/" + j,
+ expandoStatus: false
+ });
+ }
+ this.updateRowCount(this.cache.items.length);
+
+ for(i = this.expandoRowIndex + 1; i < len; i++){
+ delete this._by_idx[i];
+ }
+ this.cache.updateCache(this.expandoRowIndex, {childrenNum: size});
+ for(i = 0; i < size; i++){
+ this.cache.updateCache(this.expandoRowIndex + 1 + i, {item: childItems[i]});
+ }
+ for(i = 0; i < Math.min(size, this.keepRows); i++){
+ this._addItem(childItems[i], this.expandoRowIndex + 1 + i, false);
+ }
+
+ this.toggleLoadingClass(false);
+ this.stateChangeNode = null;
+ if(size < this.keepRows && this.cache.getTreePathByRowIndex(this.expandoRowIndex + 1 + size)){
+ this._fetch(this.expandoRowIndex + 1 + size);
+ }
+ },
+
+ toggleLoadingClass: function(flag){
+ // summary:
+ // set loading class when expanding/collapsing
+ if(this.stateChangeNode){
+ dojo.toggleClass(this.stateChangeNode, "dojoxGridExpandoLoading", flag);
+ }
+ },
+
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ this.rows.styleRowNode(inRowIndex, inRowNode);
+ }
+ },
+
+ onStyleRow: function(row){
+ if(!this.layout._isCollapsable){
+ this.inherited(arguments);
+ return;
+ }
+ var base = dojo.attr(row.node, 'dojoxTreeGridBaseClasses');
+ if(base){
+ row.customClasses = base;
+ }
+ var i = row;
+ i.customClasses += (i.odd ? " dojoxGridRowOdd" : "") + (i.selected ? " dojoxGridRowSelected" : "") + (i.over ? " dojoxGridRowOver" : "");
+ this.focus.styleRow(i);
+ this.edit.styleRow(i);
+ },
+
+ dokeydown: function(e){
+ if(e.altKey || e.metaKey){
+ return;
+ }
+ var dk = dojo.keys,
+ target = e.target,
+ expando = target && target.firstChild ? dijit.byId(target.firstChild.id) : null;
+ if(e.keyCode === dk.ENTER && expando instanceof dojox.grid._LazyExpando){
+ expando.onToggle();
+ }
+ this.onKeyDown(e);
+ }
+});
+
+dojox.grid.LazyTreeGrid.markupFactory = function(props, node, ctor, cellFunc){
+ return dojox.grid.TreeGrid.markupFactory(props, node, ctor, cellFunc);
+};
+
+}
diff --git a/js/dojo-1.6/dojox/grid/LazyTreeGrid.xd.js b/js/dojo-1.6/dojox/grid/LazyTreeGrid.xd.js
new file mode 100644
index 0000000..a205eba
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/LazyTreeGrid.xd.js
@@ -0,0 +1,831 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.LazyTreeGrid"],
+["require", "dojox.grid._View"],
+["require", "dojox.grid.TreeGrid"],
+["require", "dojox.grid.cells.tree"],
+["require", "dojox.grid.LazyTreeGridStoreModel"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.LazyTreeGrid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.LazyTreeGrid"] = true;
+dojo.provide("dojox.grid.LazyTreeGrid");
+
+dojo.require("dojox.grid._View");
+dojo.require("dojox.grid.TreeGrid");
+dojo.require("dojox.grid.cells.tree");
+dojo.require("dojox.grid.LazyTreeGridStoreModel");
+
+dojo.declare("dojox.grid._LazyExpando", [dijit._Widget, dijit._Templated], {
+ itemId: "",
+ cellIdx: -1,
+ view: null,
+ rowIdx: -1,
+ expandoCell: null,
+ level: 0,
+ open: false,
+ templateString:"<div class=\"dojoxGridExpando\"\r\n\t><div class=\"dojoxGridExpandoNode\" dojoAttachEvent=\"onclick:onToggle\"\r\n\t\t><div class=\"dojoxGridExpandoNodeInner\" dojoAttachPoint=\"expandoInner\"></div\r\n\t></div\r\n></div>\r\n",
+
+ onToggle: function(event){
+ // Summary
+ // Function for expand/collapse row
+ this.setOpen(!this.view.grid.cache.getExpandoStatusByRowIndex(this.rowIdx));
+ try{
+ dojo.stopEvent(event);
+ }catch(e){}
+ },
+
+ setOpen: function(open){
+ var g = this.view.grid,
+ item = g.cache.getItemByRowIndex(this.rowIdx);
+ if(!g.treeModel.mayHaveChildren(item)){
+ g.stateChangeNode = null;
+ return;
+ }
+ if(item){
+ g.stateChangeNode = this.domNode;
+ g.cache.updateCache(this.rowIdx, {"expandoStatus": open});
+ g.expandoFetch(this.rowIdx, open);
+ this.open = open;
+ }
+ this._updateOpenState(item);
+ },
+
+ _updateOpenState: function(item){
+ // Summary
+ // Update the expando icon
+ var grid = this.view.grid;
+ if(item && grid.treeModel.mayHaveChildren(item)){
+ var state = grid.cache.getExpandoStatusByRowIndex(this.rowIdx);
+ this.expandoInner.innerHTML = state ? "-" : "+";
+ dojo.toggleClass(this.domNode, "dojoxGridExpandoOpened", state);
+ }
+ },
+
+ setRowNode: function(rowIdx, rowNode, view){
+ if(this.cellIdx < 0 || !this.itemId){ return false; }
+ this._initialized = false;
+ this.view = view;
+ this.rowIdx = rowIdx;
+ this.expandoCell = view.structure.cells[0][this.cellIdx];
+ var d = this.domNode;
+ if(d && d.parentNode && d.parentNode.parentNode){
+ this._tableRow = d.parentNode.parentNode;
+ }
+ dojo.style(this.domNode , "marginLeft" , (this.level * 1.125) + "em");
+ this._updateOpenState(view.grid.cache.getItemByRowIndex(this.rowIdx));
+ return true;
+ }
+});
+
+dojo.declare("dojox.grid._TreeGridContentBuilder", dojox.grid._ContentBuilder, {
+ // summary:
+ // Could create row content innerHTML by different appoarch for different data structure
+ generateHtml: function(inDataIndex, inRowIndex){
+ // summary:
+ // create row innterHTML for flat data structure
+ var html = this.getTableArray(),
+ grid = this.grid,
+ v = this.view,
+ cells = v.structure.cells,
+ item = grid.getItem(inRowIndex),
+ level = 0,
+ treePath = grid.cache.getTreePathByRowIndex(inRowIndex),
+ rowStack = [],
+ toggleClasses = [];
+
+ dojox.grid.util.fire(this.view, "onBeforeRow", [inRowIndex, cells]);
+
+ if(item !== null && treePath !== null){
+ rowStack = treePath.split("/");
+ level = rowStack.length - 1;
+ toggleClasses[0] = "dojoxGridRowToggle-" + rowStack.join("-");
+ if(!grid.treeModel.mayHaveChildren(item)){
+ toggleClasses.push("dojoxGridNoChildren");
+ }
+ }
+
+ for(var j = 0, row; (row = cells[j]); j++){
+ if(row.hidden || row.header){
+ continue;
+ }
+ var tr = '<tr style="" class="' + toggleClasses.join(' ') + '" dojoxTreeGridPath="' + rowStack.join('/') + '" dojoxTreeGridBaseClasses="' + toggleClasses.join(' ') + '">';
+ html.push(tr);
+ var k = 0, mergedCells = this._getColSpans(level);
+ var totalWidth = 0, totalWidthes = [];
+ if(mergedCells){
+ dojo.forEach(mergedCells, function(c){
+ for(var i = 0, cell;(cell = row[i]); i++){
+ if(i >= c.start && i <= c.end){
+ totalWidth += this._getCellWidth(row, i);
+ }
+ }
+ totalWidthes.push(totalWidth);
+ totalWidth = 0;
+ }, this);
+ }
+ for(var i = 0, cell, m, cc, cs; (cell = row[i]); i++){
+ m = cell.markup;
+ cc = cell.customClasses = [];
+ cs = cell.customStyles = [];
+ if(mergedCells && mergedCells[k] && (i >= mergedCells[k].start && i <= mergedCells[k].end)){
+ var primaryIdx = mergedCells[k].primary ? mergedCells[k].primary : mergedCells[k].start;
+ if(i == primaryIdx){
+ m[5] = cell.formatAtLevel(rowStack, item, level, false, toggleClasses[0], cc, inRowIndex);
+ // classes
+ m[1] = cc.join(' ');
+ // styles
+ var pbm = dojo.marginBox(cell.getHeaderNode()).w - dojo.contentBox(cell.getHeaderNode()).w;
+ cs = cell.customStyles = ['width:' + (totalWidthes[k] - pbm) + "px"];
+ m[3] = cs.join(';');
+ html.push.apply(html, m);
+ }else if(i == mergedCells[k].end){
+ k++;
+ continue;
+ }else{
+ continue;
+ }
+ }else{
+ // content (format can fill in cc and cs as side-effects)
+ // m[5] = cell.format(inRowIndex, item);
+ m[5] = cell.formatAtLevel(rowStack, item, level, false, toggleClasses[0], cc, inRowIndex);
+ // classes
+ m[1] = cc.join(' ');
+ // styles
+ m[3] = cs.join(';');
+ // in-place concat
+ html.push.apply(html, m);
+ }
+
+ }
+ html.push('</tr>');
+ }
+ html.push('</table>');
+ return html.join(''); // String
+ },
+
+ _getColSpans: function(level){
+ // summary:
+ // handle the column span object
+ var colSpans = this.grid.colSpans;
+ if(colSpans && (colSpans[level])){
+ return colSpans[level];
+ }else{
+ return null;
+ }
+ },
+
+ _getCellWidth: function(cells, colIndex){
+ // summary:
+ // calculate column width by header cell's size
+ var node = cells[colIndex].getHeaderNode();
+ if(colIndex == cells.length - 1 || dojo.every(cells.slice(colIndex + 1), function(cell){
+ return cell.hidden;
+ })){
+ var headerNodePos = dojo.position(cells[colIndex].view.headerContentNode.firstChild);
+ return headerNodePos.x + headerNodePos.w - dojo.position(node).x;
+ }else{
+ var nextNode = cells[colIndex + 1].getHeaderNode();
+ return dojo.position(nextNode).x - dojo.position(node).x;
+ }
+ }
+});
+
+dojo.declare("dojox.grid._TreeGridView", [dojox.grid._View], {
+
+ _contentBuilderClass: dojox.grid._TreeGridContentBuilder,
+
+ postCreate: function(){
+ this.inherited(arguments);
+ this._expandos = {};
+ this.connect(this.grid, '_cleanupExpandoCache', '_cleanupExpandoCache');
+ },
+
+ _cleanupExpandoCache: function(index, identity, item){
+ if(index == -1){
+ return;
+ }
+ dojo.forEach(this.grid.layout.cells, function(cell){
+ if(cell.openStates && identity in cell.openStates){
+ delete cell.openStates[identity];
+ }
+ });
+ for(var i in this._expandos){
+ if(this._expandos[i]){
+ this._expandos[i].destroy();
+ }
+ }
+ this._expandos = {};
+ },
+
+ onAfterRow: function(inRowIndex, cells, inRowNode){
+ // summary:
+ // parse the expando of each row to a widget
+ dojo.query("span.dojoxGridExpando", inRowNode).forEach(function(n){
+ if(n && n.parentNode){
+ // Either create our expando or put the existing expando back
+ // into place
+ var idty, expando, _byIdx = this.grid._by_idx;
+ if(_byIdx && _byIdx[inRowIndex] && _byIdx[inRowIndex].idty){
+ idty = _byIdx[inRowIndex].idty;
+ expando = this._expandos[idty];
+ }
+ if(expando){
+ dojo.place(expando.domNode, n, "replace");
+ expando.itemId = n.getAttribute("itemId");
+ expando.cellIdx = parseInt(n.getAttribute("cellIdx"), 10);
+ if(isNaN(expando.cellIdx)){
+ expando.cellIdx = -1;
+ }
+ }else{
+ expando = dojo.parser.parse(n.parentNode)[0];
+ if(idty){
+ this._expandos[idty] = expando;
+ }
+ }
+ if(!expando.setRowNode(inRowIndex, inRowNode, this)){
+ expando.domNode.parentNode.removeChild(expando.domNode);
+ }
+ }
+ }, this);
+ this.inherited(arguments);
+ }
+
+});
+
+dojo.mixin(dojox.grid.cells.TreeCell, {
+ formatAtLevel: function(inRowIndexes, inItem, level, summaryRow, toggleClass, cellClasses, inRowIndex){
+ if(!inItem){
+ return this.formatIndexes(inRowIndex, inRowIndexes, inItem, level);
+ }
+ if(!dojo.isArray(inRowIndexes)){
+ inRowIndexes = [inRowIndexes];
+ }
+ var result = "";
+ var ret = "";
+ if(this.isCollapsable){
+ var store = this.grid.store, id = "";
+ if(inItem && store.isItem(inItem)){
+ id = store.getIdentity(inItem);
+ }
+ cellClasses.push("dojoxGridExpandoCell");
+ ret = '<span ' + dojo._scopeName + 'Type="dojox.grid._LazyExpando" level="' + level + '" class="dojoxGridExpando"' +
+ '" toggleClass="' + toggleClass + '" itemId="' + id + '" cellIdx="' + this.index + '"></span>';
+ }
+ result = ret + this.formatIndexes(inRowIndex, inRowIndexes, inItem, level);
+ if(this.grid.focus.cell && this.index == this.grid.focus.cell.index && inRowIndexes.join('/') == this.grid.focus.rowIndex){
+ cellClasses.push(this.grid.focus.focusClass);
+ }
+ return result;
+ },
+
+ formatIndexes: function(inRowIndex, inRowIndexes, inItem, level){
+ var info = this.grid.edit.info,
+ d = this.get ? this.get(inRowIndexes[0], inItem, inRowIndexes) : (this.value || this.defaultValue);
+ if(this.editable && (this.alwaysEditing || (info.rowIndex == inRowIndexes[0] && info.cell == this))){
+ return this.formatEditing(d, inRowIndex, inRowIndexes);
+ }else{
+ return this._defaultFormat(d, [d, inRowIndex, level, this]);
+ }
+ }
+});
+
+dojo.declare("dojox.grid._LazyTreeLayout", dojox.grid._Layout, {
+ // summary:
+ // Override the dojox.grid._TreeLayout to modify the _TreeGridView and cell formatter
+ setStructure: function(inStructure){
+ var s = inStructure;
+ var g = this.grid;
+ if(g && !dojo.every(s, function(i){
+ return ("cells" in i);
+ })){
+ s = arguments[0] = [{cells:[s]}];//intentionally change arguments[0]
+ }
+ if(s.length == 1 && s[0].cells.length == 1){
+ s[0].type = "dojox.grid._TreeGridView";
+ this._isCollapsable = true;
+ s[0].cells[0][this.grid.expandoCell].isCollapsable = true;
+ }
+ this.inherited(arguments);
+ },
+
+ addCellDef: function(inRowIndex, inCellIndex, inDef){
+ var obj = this.inherited(arguments);
+ return dojo.mixin(obj, dojox.grid.cells.TreeCell);
+ }
+});
+
+dojo.declare("dojox.grid.TreeGridItemCache", null, {
+
+ unInit: true,
+
+ items: null,
+
+ constructor: function(grid){
+ this.rowsPerPage = grid.rowsPerPage;
+ this._buildCache(grid.rowsPerPage);
+ },
+
+ _buildCache: function(size){
+ // Summary
+ // Build the cache only with the treepath using given size
+ this.items = [];
+ for(var i = 0; i < size; i++){
+ this.cacheItem(i, {item: null, treePath: i + "", expandoStatus: false});
+ }
+ },
+
+ cacheItem: function(/*integer*/rowIdx, cacheObj){
+ // Summary
+ // Add an item and its tree structure information to the cache.
+ this.items[rowIdx] = dojo.mixin({
+ item: null,
+ treePath: "",
+ expandoStatus: false
+ }, cacheObj);
+ },
+
+ insertItem: function(/*integer*/rowIdx, cacheObj){
+ this.items.splice(rowIdx, 0, dojo.mixin({
+ item: null,
+ treePath: "",
+ expandoStatus: false
+ }, cacheObj));
+ },
+
+ initCache: function(size){
+ if(!this.unInit){ return; }
+ this._buildCache(size);
+ this.unInit = false;
+ },
+
+ getItemByRowIndex: function(/*integer*/rowIdx){
+ return this.items[rowIdx] ? this.items[rowIdx].item : null;
+ },
+
+ getItemByTreePath: function(treePath){
+ for(var i = 0, len = this.items.length; i < len; i++){
+ if(this.items[i].treePath === treePath){
+ return this.items[i].item;
+ }
+ }
+ return null;
+ },
+
+ getTreePathByRowIndex: function(/*integer*/rowIdx){
+ return this.items[rowIdx] ? this.items[rowIdx].treePath : null;
+ },
+
+ getExpandoStatusByRowIndex: function(/*integer*/rowIdx){
+ return this.items[rowIdx] ? this.items[rowIdx].expandoStatus : null;
+ },
+
+ getInfoByItem: function(item){
+ for(var i = 0, len = this.items.length; i < len; i++){
+ if(this.items[i].item == item){
+ return dojo.mixin({rowIdx: i}, this.items[i]);
+ }
+ }
+ return null;
+ },
+
+ updateCache: function(/*integer*/rowIdx, cacheObj){
+ if(this.items[rowIdx]){
+ dojo.mixin(this.items[rowIdx], cacheObj);
+ }
+ },
+
+ deleteItem: function(rowIdx){
+ if(this.items[rowIdx]){
+ this.items.splice(rowIdx, 1);
+ }
+ },
+
+ cleanChildren: function(rowIdx){
+ var treePath = this.getTreePathByRowIndex(rowIdx);
+ for(var i = this.items.length - 1; i >= 0; i--){
+ if(this.items[i].treePath.indexOf(treePath) === 0 && this.items[i].treePath !== treePath){
+ this.items.splice(i, 1);
+ }
+ }
+ },
+
+ emptyCache: function(){
+ this.unInit = true;
+ this._buildCache(this.rowsPerPage);
+ },
+
+ cleanupCache: function(){
+ this.items = null;
+ }
+
+});
+
+dojo.declare("dojox.grid.LazyTreeGrid", dojox.grid.TreeGrid, {
+ // summary:
+ // An enhanced TreeGrid widget which supports lazy-loading nested-level items
+ //
+ // description:
+ // LazyTreeGrid inherits from dojo.grid.TreeGrid, and applies virtual scrolling mechanism
+ // to nested children rows so that it's possible to deal with large data set specifically
+ // in tree structure with large number of children rows. It's also compatible with dijit.tree.ForestStoreModel
+ //
+ // Most methods and properties pertaining to the dojox.grid.DataGrid
+ // and dojox.grid.TreeGrid also apply here
+ //
+ // LazyTreeGrid does not support summary row/items aggregate for the
+ // lazy-loading reason.
+
+ treeModel: null,
+
+ _layoutClass: dojox.grid._LazyTreeLayout,
+
+ // colSpans: Object
+ // a json object that defines column span of each level rows
+ // attributes:
+ // 0/1/..: which level need to colspan
+ // start: start column index of colspan
+ // end: end column index of colspan
+ // primary: index of column which content will be displayed (default is value of start).
+ // example:
+ // | colSpans = {
+ // | 0: [
+ // | {start: 0, end: 1, primary: 0},
+ // | {start: 2, end: 4, primary: 3}
+ // | ],
+ // | 1: [
+ // | {start: 0, end: 3, primary: 1}
+ // | ]
+ // | };
+ colSpans: null,
+
+ postCreate: function(){
+ this.inherited(arguments);
+ this.cache = new dojox.grid.TreeGridItemCache(this);
+ if(!this.treeModel || !(this.treeModel instanceof dijit.tree.ForestStoreModel)){
+ throw new Error("dojox.grid.LazyTreeGrid: must use a treeModel and treeModel must be an instance of dijit.tree.ForestStoreModel");
+ }
+ dojo.addClass(this.domNode, "dojoxGridTreeModel");
+ dojo.setSelectable(this.domNode, this.selectable);
+ },
+
+ createManagers: function(){
+ // summary:
+ // create grid managers for various tasks including rows, focus, selection, editing
+ this.rows = new dojox.grid._RowManager(this);
+ this.focus = new dojox.grid._FocusManager(this);
+ this.edit = new dojox.grid._EditManager(this);
+ },
+
+ createSelection: function(){
+ this.selection = new dojox.grid.DataSelection(this);
+ },
+
+ setModel: function(treeModel){
+ if(!treeModel){
+ return;
+ }
+ this._setModel(treeModel);
+ this._refresh(true);
+ },
+
+ setStore: function(store, query, queryOptions){
+ if(!store){
+ return;
+ }
+ this._setQuery(query, queryOptions);
+ this.treeModel.query = query;
+ this.treeModel.store = store;
+ this.treeModel.root.children = [];
+ this.setModel(this.treeModel);
+ },
+
+ _setQuery: function(query, queryOptions){
+ this.inherited(arguments);
+ this.treeModel.query = query;
+ },
+
+ destroy: function(){
+ this._cleanup();
+ this.inherited(arguments);
+ },
+
+ _cleanup: function(){
+ this.cache.emptyCache();
+ this._cleanupExpandoCache();
+ },
+
+ setSortIndex: function(inIndex, inAsc){
+ // Need to clean up the cache before sorting
+ this._cleanup();
+ this.inherited(arguments);
+ },
+
+ _refresh: function(isRender){
+ this._cleanup();
+ this.inherited(arguments);
+ },
+
+ render: function(){
+ this.inherited(arguments);
+ this.setScrollTop(this.scrollTop);
+ },
+
+ _onNew: function(item, parentInfo){
+ var isAddingChild = false;
+ var info;
+ if(parentInfo && this.store.isItem(parentInfo.item) && dojo.some(this.treeModel.childrenAttrs, function(c){
+ return c === parentInfo.attribute;
+ })){
+ isAddingChild = true;
+ info = this.cache.getInfoByItem(parentInfo.item);
+ }
+ if(!isAddingChild){
+ this.inherited(arguments);
+ var items = this.cache.items;
+ var treePath = (parseInt(items[items.length - 1].treePath.split("/")[0], 10) + 1) + "";
+ this.cache.insertItem(this.get('rowCount'), {item: item, treePath: treePath, expandoStatus: false});
+ }else if(info && info.expandoStatus && info.rowIdx >= 0){
+ this.expandoFetch(info.rowIdx, false);
+ this.expandoFetch(info.rowIdx, true);
+ }else if(info && info.rowIdx){
+ this.updateRow(info.rowIdx);
+ }
+ },
+
+ _onDelete: function(item){
+ this._pages = [];
+ this._bop = -1;
+ this._eop = -1;
+ this._refresh();
+ },
+
+ _cleanupExpandoCache: function(index, identity, item){},
+
+ _fetch: function(start, isRender){
+ // summary:
+ // Function for fetch data when initializing TreeGrid and
+ // scroll the TreeGrid
+ start = start || 0;
+ this.reqQueue = [];
+ this.showMessage(this.loadingMessage);
+ // Check cache, do not need to fetch data if there are required data in cache
+ var i = 0, fetchedItems = [];
+ var count = Math.min(this.rowsPerPage, this.cache.items.length - start);
+ for(i = start; i < count; i++){
+ if(this.cache.getItemByRowIndex(i)){
+ fetchedItems.push(this.cache.getItemByRowIndex(i));
+ }else{
+ break;
+ }
+ }
+ if(fetchedItems.length === count){// || !this.cache.getTreePathByRowIndex(start + fetchedItems.length)){
+ this._onFetchComplete(fetchedItems, {startRowIdx: start, count: count});
+ }else{
+ // In case there need different level data, we need to do multiple fetch.
+ // Do next fetch only when the last request complete.
+ this.reqQueueIndex = 0;
+ var level = "",
+ nextRowLevel = "",
+ startRowIdx = start,
+ startTreePath = this.cache.getTreePathByRowIndex(start);
+ count = 0;
+ // Create request queue
+ for(i = start + 1; i < start + this.rowsPerPage; i++){
+ if(!this.cache.getTreePathByRowIndex(i)){
+ break;
+ }
+ level = this.cache.getTreePathByRowIndex(i - 1).split("/").length - 1;
+ nextRowLevel = this.cache.getTreePathByRowIndex(i).split("/").length - 1;
+ if(level !== nextRowLevel){
+ this.reqQueue.push({
+ startTreePath: startTreePath,
+ startRowIdx: startRowIdx,
+ count: count + 1
+ });
+ count = 0;
+ startRowIdx = i;
+ startTreePath = this.cache.getTreePathByRowIndex(i);
+ }else{
+ count++;
+ }
+ }
+ this.reqQueue.push({
+ startTreePath: startTreePath,
+ startRowIdx: startRowIdx,
+ count: count + 1
+ });
+ var len = this.reqQueue.length;
+ for(i = 0; i < len; i++){
+ this._fetchItems(i, dojo.hitch(this, "_onFetchBegin"), dojo.hitch(this, "_onFetchComplete"), dojo.hitch(this, "_onFetchError"));
+ }
+ }
+ },
+
+ _fetchItems: function(idx, onBegin, onComplete, onError){
+ var level = this.reqQueue[idx].startTreePath.split("/").length - 1;
+ this._pending_requests[this.reqQueue[idx].startRowIdx] = true;
+ if(level === 0){
+ this.store.fetch({
+ start: parseInt(this.reqQueue[idx].startTreePath, 10),
+ startRowIdx: this.reqQueue[idx].startRowIdx,
+ count: this.reqQueue[idx].count,
+ query: this.query,
+ sort: this.getSortProps(),
+ queryOptions: this.queryOptions,
+ onBegin: onBegin,
+ onComplete: onComplete,
+ onError: onError
+ });
+ }else{
+ var startTreePath = this.reqQueue[idx].startTreePath;
+ var parentTreePath = startTreePath.substring(0, startTreePath.lastIndexOf("/"));
+ var startIdx = startTreePath.substring(startTreePath.lastIndexOf("/") + 1);
+ var parentItem = this.cache.getItemByTreePath(parentTreePath);
+ if(!parentItem){
+ throw new Error("Lazy loading TreeGrid on fetch error:");
+ }
+ var parentId = this.store.getIdentity(parentItem);
+ this.queryObj = {
+ start: parseInt(startIdx, 10),
+ startRowIdx: this.reqQueue[idx].startRowIdx,
+ count: this.reqQueue[idx].count,
+ parentId: parentId,
+ sort: this.getSortProps()
+ };
+ this.treeModel.getChildren(parentItem, onComplete, onError, this.queryObj);
+ }
+ },
+
+ _onFetchBegin: function(size, request){
+ this.cache.initCache(size);
+ size = this.cache.items.length;
+ this.inherited(arguments);
+ },
+
+ _onFetchComplete: function(items, request, size){
+ var treePath = "",
+ startRowIdx, count, start;
+
+ if(request){
+ startRowIdx = request.startRowIdx;
+ count = request.count;
+ start = 0;
+ }else{
+ startRowIdx = this.queryObj.startRowIdx;
+ count = this.queryObj.count;
+ start = this.queryObj.start;
+ }
+
+ for(var i = 0; i < count; i++){
+ treePath = this.cache.getTreePathByRowIndex(startRowIdx + i);
+ if(treePath){
+ if(!this.cache.getItemByRowIndex(startRowIdx + i)){
+ this.cache.cacheItem(startRowIdx + i, {
+ item: items[start + i],
+ treePath: treePath,
+ expandoStatus: false
+ });
+ }
+ }
+ }
+ this._pending_requests[startRowIdx] = false;
+ // Add items when all request complete
+ if(!this.scroller){
+ return;
+ }
+ var len = Math.min(count, items.length);
+ for(i = 0; i < len; i++){
+ this._addItem(items[start + i], startRowIdx + i, true);
+ }
+ this.updateRows(startRowIdx, len);
+ if(this._lastScrollTop){
+ this.setScrollTop(this._lastScrollTop);
+ }
+ if(!this.cache.items.length){
+ this.showMessage(this.noDataMessage);
+ }else{
+ this.showMessage();
+ }
+ },
+
+ expandoFetch: function(rowIndex, open){
+ // summary:
+ // Function for fetch children of a given row
+ this.toggleLoadingClass(true);
+ var item = this.cache.getItemByRowIndex(rowIndex);
+ this.expandoRowIndex = rowIndex;
+ this._pages = [];
+ if(open){
+ var parentId = this.store.getIdentity(item);
+ var queryObj = {
+ start: 0,
+ count: this.keepRows,
+ parentId: parentId,
+ sort: this.getSortProps()
+ };
+ this.treeModel.getChildren(item, dojo.hitch(this, "_onExpandoComplete"), dojo.hitch(this, "_onFetchError"), queryObj);
+ }else{
+ this.cache.cleanChildren(rowIndex);
+ for(var i = rowIndex + 1, len = this._by_idx.length; i < len; i++){
+ delete this._by_idx[i];
+ }
+ this.updateRowCount(this.cache.items.length);
+ if(this.cache.getTreePathByRowIndex(rowIndex + 1)){
+ this._fetch(rowIndex + 1);
+ }else{
+ this._fetch(rowIndex);
+ }
+ this.toggleLoadingClass(false);
+ }
+ },
+
+ _onExpandoComplete: function(childItems, request, size){
+ var parentTreePath = this.cache.getTreePathByRowIndex(this.expandoRowIndex);
+ if(size && !isNaN(parseInt(size, 10))){
+ size = parseInt(size, 10);
+ }else{
+ size = childItems.length;
+ }
+ var i, j = 0, len = this._by_idx.length;
+ for(i = this.expandoRowIndex + 1; j < size; i++, j++){
+ this.cache.insertItem(i, {
+ item: null,
+ treePath: parentTreePath + "/" + j,
+ expandoStatus: false
+ });
+ }
+ this.updateRowCount(this.cache.items.length);
+
+ for(i = this.expandoRowIndex + 1; i < len; i++){
+ delete this._by_idx[i];
+ }
+ this.cache.updateCache(this.expandoRowIndex, {childrenNum: size});
+ for(i = 0; i < size; i++){
+ this.cache.updateCache(this.expandoRowIndex + 1 + i, {item: childItems[i]});
+ }
+ for(i = 0; i < Math.min(size, this.keepRows); i++){
+ this._addItem(childItems[i], this.expandoRowIndex + 1 + i, false);
+ }
+
+ this.toggleLoadingClass(false);
+ this.stateChangeNode = null;
+ if(size < this.keepRows && this.cache.getTreePathByRowIndex(this.expandoRowIndex + 1 + size)){
+ this._fetch(this.expandoRowIndex + 1 + size);
+ }
+ },
+
+ toggleLoadingClass: function(flag){
+ // summary:
+ // set loading class when expanding/collapsing
+ if(this.stateChangeNode){
+ dojo.toggleClass(this.stateChangeNode, "dojoxGridExpandoLoading", flag);
+ }
+ },
+
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ this.rows.styleRowNode(inRowIndex, inRowNode);
+ }
+ },
+
+ onStyleRow: function(row){
+ if(!this.layout._isCollapsable){
+ this.inherited(arguments);
+ return;
+ }
+ var base = dojo.attr(row.node, 'dojoxTreeGridBaseClasses');
+ if(base){
+ row.customClasses = base;
+ }
+ var i = row;
+ i.customClasses += (i.odd ? " dojoxGridRowOdd" : "") + (i.selected ? " dojoxGridRowSelected" : "") + (i.over ? " dojoxGridRowOver" : "");
+ this.focus.styleRow(i);
+ this.edit.styleRow(i);
+ },
+
+ dokeydown: function(e){
+ if(e.altKey || e.metaKey){
+ return;
+ }
+ var dk = dojo.keys,
+ target = e.target,
+ expando = target && target.firstChild ? dijit.byId(target.firstChild.id) : null;
+ if(e.keyCode === dk.ENTER && expando instanceof dojox.grid._LazyExpando){
+ expando.onToggle();
+ }
+ this.onKeyDown(e);
+ }
+});
+
+dojox.grid.LazyTreeGrid.markupFactory = function(props, node, ctor, cellFunc){
+ return dojox.grid.TreeGrid.markupFactory(props, node, ctor, cellFunc);
+};
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/LazyTreeGridStoreModel.js b/js/dojo-1.6/dojox/grid/LazyTreeGridStoreModel.js
new file mode 100644
index 0000000..b9c954f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/LazyTreeGridStoreModel.js
@@ -0,0 +1,116 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.LazyTreeGridStoreModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.LazyTreeGridStoreModel"] = true;
+dojo.provide("dojox.grid.LazyTreeGridStoreModel");
+
+dojo.require("dijit.tree.ForestStoreModel");
+
+dojo.declare("dojox.grid.LazyTreeGridStoreModel", dijit.tree.ForestStoreModel, {
+
+ // There are different approaches to get children for client-side
+ // DataStore (e.g. dojo.data.ItemFileReadStore) or server-side DataStore
+ // (e.g. dojox.data.QueryReadStore), so we need to be sure what kind of
+ // DataStore is being used
+ serverStore: false, // server side store
+
+ constructor: function(/* Object */ args){
+ this.serverStore = args.serverStore === true ? true : false;
+ },
+
+ mayHaveChildren: function(/*dojo.data.Item*/ item){
+ var children = null;
+ return dojo.some(this.childrenAttrs, function(attr){
+ children = this.store.getValue(item, attr);
+ if(dojo.isString(children)){
+ return parseInt(children, 10) > 0 || children.toLowerCase() === "true" ? true : false;
+ }else if(typeof children == "number"){
+ return children > 0;
+ }else if(typeof children == "boolean"){
+ return children;
+ }else if(this.store.isItem(children)){
+ children = this.store.getValues(item, attr);
+ return dojo.isArray(children) ? children.length > 0 : false;
+ }else{
+ return false;
+ }
+ }, this);
+ },
+
+ getChildren: function(/*dojo.data.Item*/parentItem, /*function(items, size)*/onComplete, /*function*/ onError, /*object*/queryObj){
+ if(queryObj){
+ var start = queryObj.start || 0,
+ count = queryObj.count,
+ parentId = queryObj.parentId,
+ sort = queryObj.sort;
+ if(parentItem === this.root){
+ this.root.size = 0;
+ this.store.fetch({
+ start: start,
+ count: count,
+ sort: sort,
+ query: this.query,
+ onBegin: dojo.hitch(this, function(size){
+ this.root.size = size;
+ }),
+ onComplete: dojo.hitch(this, function(items){
+ onComplete(items, queryObj, this.root.size);
+ }),
+ onError: onError
+ });
+ }else{
+ var store = this.store;
+ if(!store.isItemLoaded(parentItem)){
+ var getChildren = dojo.hitch(this, arguments.callee);
+ store.loadItem({
+ item: parentItem,
+ onItem: function(parentItem){
+ getChildren(parentItem, onComplete, onError, queryObj);
+ },
+ onError: onError
+ });
+ return;
+ }
+ if(this.serverStore && !this._isChildrenLoaded(parentItem)){
+ this.childrenSize = 0;
+ this.store.fetch({
+ start: start,
+ count: count,
+ sort: sort,
+ query: dojo.mixin({parentId: parentId}, this.query || {}),
+ onBegin: dojo.hitch(this, function(size){
+ this.childrenSize = size;
+ }),
+ onComplete: dojo.hitch(this, function(items){
+ onComplete(items, queryObj, this.childrenSize);
+ }),
+ onError: onError
+ });
+ }else{
+ this.inherited(arguments);
+ }
+ }
+ }else{
+ this.inherited(arguments);
+ }
+ },
+
+ _isChildrenLoaded: function(parentItem){
+ // summary:
+ // Check if all children of the given item have been loaded
+ var children = null;
+ return dojo.every(this.childrenAttrs, function(attr){
+ children = this.store.getValues(parentItem, attr);
+ return dojo.every(children, function(c){
+ return this.store.isItemLoaded(c);
+ }, this);
+ }, this);
+ }
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/LazyTreeGridStoreModel.xd.js b/js/dojo-1.6/dojox/grid/LazyTreeGridStoreModel.xd.js
new file mode 100644
index 0000000..bb2931a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/LazyTreeGridStoreModel.xd.js
@@ -0,0 +1,121 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.LazyTreeGridStoreModel"],
+["require", "dijit.tree.ForestStoreModel"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.LazyTreeGridStoreModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.LazyTreeGridStoreModel"] = true;
+dojo.provide("dojox.grid.LazyTreeGridStoreModel");
+
+dojo.require("dijit.tree.ForestStoreModel");
+
+dojo.declare("dojox.grid.LazyTreeGridStoreModel", dijit.tree.ForestStoreModel, {
+
+ // There are different approaches to get children for client-side
+ // DataStore (e.g. dojo.data.ItemFileReadStore) or server-side DataStore
+ // (e.g. dojox.data.QueryReadStore), so we need to be sure what kind of
+ // DataStore is being used
+ serverStore: false, // server side store
+
+ constructor: function(/* Object */ args){
+ this.serverStore = args.serverStore === true ? true : false;
+ },
+
+ mayHaveChildren: function(/*dojo.data.Item*/ item){
+ var children = null;
+ return dojo.some(this.childrenAttrs, function(attr){
+ children = this.store.getValue(item, attr);
+ if(dojo.isString(children)){
+ return parseInt(children, 10) > 0 || children.toLowerCase() === "true" ? true : false;
+ }else if(typeof children == "number"){
+ return children > 0;
+ }else if(typeof children == "boolean"){
+ return children;
+ }else if(this.store.isItem(children)){
+ children = this.store.getValues(item, attr);
+ return dojo.isArray(children) ? children.length > 0 : false;
+ }else{
+ return false;
+ }
+ }, this);
+ },
+
+ getChildren: function(/*dojo.data.Item*/parentItem, /*function(items, size)*/onComplete, /*function*/ onError, /*object*/queryObj){
+ if(queryObj){
+ var start = queryObj.start || 0,
+ count = queryObj.count,
+ parentId = queryObj.parentId,
+ sort = queryObj.sort;
+ if(parentItem === this.root){
+ this.root.size = 0;
+ this.store.fetch({
+ start: start,
+ count: count,
+ sort: sort,
+ query: this.query,
+ onBegin: dojo.hitch(this, function(size){
+ this.root.size = size;
+ }),
+ onComplete: dojo.hitch(this, function(items){
+ onComplete(items, queryObj, this.root.size);
+ }),
+ onError: onError
+ });
+ }else{
+ var store = this.store;
+ if(!store.isItemLoaded(parentItem)){
+ var getChildren = dojo.hitch(this, arguments.callee);
+ store.loadItem({
+ item: parentItem,
+ onItem: function(parentItem){
+ getChildren(parentItem, onComplete, onError, queryObj);
+ },
+ onError: onError
+ });
+ return;
+ }
+ if(this.serverStore && !this._isChildrenLoaded(parentItem)){
+ this.childrenSize = 0;
+ this.store.fetch({
+ start: start,
+ count: count,
+ sort: sort,
+ query: dojo.mixin({parentId: parentId}, this.query || {}),
+ onBegin: dojo.hitch(this, function(size){
+ this.childrenSize = size;
+ }),
+ onComplete: dojo.hitch(this, function(items){
+ onComplete(items, queryObj, this.childrenSize);
+ }),
+ onError: onError
+ });
+ }else{
+ this.inherited(arguments);
+ }
+ }
+ }else{
+ this.inherited(arguments);
+ }
+ },
+
+ _isChildrenLoaded: function(parentItem){
+ // summary:
+ // Check if all children of the given item have been loaded
+ var children = null;
+ return dojo.every(this.childrenAttrs, function(attr){
+ children = this.store.getValues(parentItem, attr);
+ return dojo.every(children, function(c){
+ return this.store.isItemLoaded(c);
+ }, this);
+ }, this);
+ }
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/README b/js/dojo-1.6/dojox/grid/README
new file mode 100644
index 0000000..6d3dc3c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/README
@@ -0,0 +1,148 @@
+-------------------------------------------------------------------------------
+dojox.grid
+-------------------------------------------------------------------------------
+Version 1.00
+Release date: 10/04/2007
+-------------------------------------------------------------------------------
+Project state:
+beta
+-------------------------------------------------------------------------------
+Credits
+ Scott J. Miles (sjmiles@activegrid.com)
+ Steve Orvell (sorvell@activegrid.com)
+ Bryan Forbes (bryan AT reigndropsfall.net)
+ Nathan Toone (toonetown AT dojotoolkit.org)
+-------------------------------------------------------------------------------
+Project description
+
+TurboGrid has been made available in Dojo and is now the dojox.grid!
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core
+Dojo Base (dnd)
+Dijit Templated Widget
+dojox.html (metrics)
+-------------------------------------------------------------------------------
+Documentation
+
+None available for this version yet.
+
+See http://www.turboajax.com/products/turbogrid/ for legacy documentation.
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/grid/*
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/html/*
+
+Install into the following directory structure:
+/dojox/grid/
+/dojox/html/
+
+...which should be at the same level as your Dojo checkout.
+
+If you wish us use the old (compat / 1.2) grid, you can untar the
+compatGrid.tar.gz archive. This version of the grid is no longer maintained
+or updated - but should work with any newer version of the dojo library.
+-------------------------------------------------------------------------------
+
+
+
+-------------------------------------------------------------------------------
+Sub-projects:
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+1. dojox.grid.EnhancedGrid
+-------------------------------------------------------------------------------
+Version 0.9
+Release date: 12/11/2009
+-------------------------------------------------------------------------------
+Project state
+
+alpha
+-------------------------------------------------------------------------------
+Credits
+ David Schwartz (drschwar@us.ibm.com, IBM, CCLA) - Author, UX design
+ Wei Huang (evan@dojotoolkit.org) - Author, IndirectSelection, Menus
+ Xiao Wen Zhu (xwzhu@cn.ibm.com, IBM, CCLA)
+ - Filter, Exporter, Printer, Selector, DnD, CellMerge, Cookie, Search
+ Qiang Wang (wangqsh@cn.ibm.com, IBM, CCLA) - Pagination
+ Pei Wang (wpei@cn.ibm.com, IBM, CCLA) - NestedSorting
+-------------------------------------------------------------------------------
+Project description
+
+Enhanced Grid inherits base DataGrid and provides the following enhanced features:
+ 1. Nested Sorting
+ 2. Built-in declarative Indirect Selection (radio buttons and check boxes)
+ 3. Context menu for header, row, column and selected region
+ 4. Advanced Selector: support selecting rows/columns/cells via swipe
+ 5. Drag-n-drop: columns,rows - MOVE, cells - MOVE/COPY
+ 6. Filter: filter grid content in various data types
+ 7. Exporter: export grid content to various formats
+ 8. Printer: provide convenient ways for printing grid
+ 9. Pagination: an alternative to deal with huge data set besides the default virtual scrolling way
+ 10.CellMerge: merge adjacent cells within a row
+ 11.Cookie: persist grid preferences including column width, column order, sorting order etc.
+ 12.Search: a handy way for searching grid content by regular expressions
+-------------------------------------------------------------------------------
+Dependencies
+
+Dojo Core, dojox.grid.DataGrid
+-------------------------------------------------------------------------------
+Documentation
+
+http://docs.dojocampus.org/dojox/grid/EnhancedGrid
+-------------------------------------------------------------------------------
+Installation instructions
+
+Same as dojox.grid, for detail sample usages, please refer to /dojox/grid/tests/enhanced/*.html
+-------------------------------------------------------------------------------
+Known issues
+
+ - 'Claro' is the major supported theme for EnhancedGrid features
+ - EnhancedGrid features are not fully compatible with complicated layouts (e.g. multiple rows in column header) and TreeGrid(SubGrid).
+ - Indirect Selection is not fully compatible with Advanced Selector(for selecting row/column/cells) and DnD
+ - RTL support is still in progress for Nested Sorting
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+2. dojox.grid.LazyTreeGrid
+-------------------------------------------------------------------------------
+Version 0.9
+Release date:
+-------------------------------------------------------------------------------
+Project state
+
+alpha
+-------------------------------------------------------------------------------
+Credits
+ Qiang Wang (wangqsh@cn.ibm.com, IBM, CCLA)
+ Wei Huang (evan@dojotoolkit.org)
+-------------------------------------------------------------------------------
+Project description
+
+LazyTreeGrid applies virtual scrolling mechanism to nested children rows so that it's possible to
+deal with large data set specifically in tree structure with large number of children rows.
+It's also compatible with dijit.tree.ForestStoreModel
+-------------------------------------------------------------------------------
+Dependencies
+
+Dojo Core, dojox.grid.TreeGrid
+-------------------------------------------------------------------------------
+Documentation
+
+http://docs.dojocampus.org/dojox/grid/LazyTreeGrid
+-------------------------------------------------------------------------------
+Installation instructions
+
+Same as dojox.grid, for detail sample usages, please refer to /dojox/grid/tests/test_treegrid_lazyloading.html
+-------------------------------------------------------------------------------
+Known issues
+
+LazyTreeGrid is not compatible with:
+ - Most Enhanced Grid features
+ - Complicated layouts (e.g. multiple rows in column header)
+------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/Selection.js b/js/dojo-1.6/dojox/grid/Selection.js
new file mode 100644
index 0000000..c19e4f8
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/Selection.js
@@ -0,0 +1,271 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource['dojox.grid.Selection']){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource['dojox.grid.Selection'] = true;
+dojo.provide('dojox.grid.Selection');
+
+dojo.declare("dojox.grid.Selection", null, {
+ // summary:
+ // Manages row selection for grid. Owned by grid and used internally
+ // for selection. Override to implement custom selection.
+
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ this.selected = [];
+
+ this.setMode(inGrid.selectionMode);
+ },
+
+ mode: 'extended',
+
+ selected: null,
+ updating: 0,
+ selectedIndex: -1,
+
+ setMode: function(mode){
+ if(this.selected.length){
+ this.deselectAll();
+ }
+ if(mode != 'extended' && mode != 'multiple' && mode != 'single' && mode != 'none'){
+ this.mode = 'extended';
+ }else{
+ this.mode = mode;
+ }
+ },
+
+ onCanSelect: function(inIndex){
+ return this.grid.onCanSelect(inIndex);
+ },
+
+ onCanDeselect: function(inIndex){
+ return this.grid.onCanDeselect(inIndex);
+ },
+
+ onSelected: function(inIndex){
+ },
+
+ onDeselected: function(inIndex){
+ },
+
+ //onSetSelected: function(inIndex, inSelect) { };
+ onChanging: function(){
+ },
+
+ onChanged: function(){
+ },
+
+ isSelected: function(inIndex){
+ if(this.mode == 'none'){
+ return false;
+ }
+ return this.selected[inIndex];
+ },
+
+ getFirstSelected: function(){
+ if(!this.selected.length||this.mode == 'none'){ return -1; }
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ getNextSelected: function(inPrev){
+ if(this.mode == 'none'){ return -1; }
+ for(var i=inPrev+1, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ getSelected: function(){
+ var result = [];
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ result.push(i);
+ }
+ }
+ return result;
+ },
+
+ getSelectedCount: function(){
+ var c = 0;
+ for(var i=0; i<this.selected.length; i++){
+ if(this.selected[i]){
+ c++;
+ }
+ }
+ return c;
+ },
+
+ _beginUpdate: function(){
+ if(this.updating === 0){
+ this.onChanging();
+ }
+ this.updating++;
+ },
+
+ _endUpdate: function(){
+ this.updating--;
+ if(this.updating === 0){
+ this.onChanged();
+ }
+ },
+
+ select: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(this.mode != 'multiple'){
+ this.deselectAll(inIndex);
+ this.addToSelection(inIndex);
+ }else{
+ this.toggleSelect(inIndex);
+ }
+ },
+
+ addToSelection: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(dojo.isArray(inIndex)){
+ dojo.forEach(inIndex, this.addToSelection, this);
+ return;
+ }
+ inIndex = Number(inIndex);
+ if(this.selected[inIndex]){
+ this.selectedIndex = inIndex;
+ }else{
+ if(this.onCanSelect(inIndex) !== false){
+ this.selectedIndex = inIndex;
+ var rowNode = this.grid.getRowNode(inIndex);
+ if(rowNode){
+ dojo.attr(rowNode,"aria-selected","true");
+ }
+ this._beginUpdate();
+ this.selected[inIndex] = true;
+ //this.grid.onSelected(inIndex);
+ this.onSelected(inIndex);
+ //this.onSetSelected(inIndex, true);
+ this._endUpdate();
+ }
+ }
+ },
+
+ deselect: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(dojo.isArray(inIndex)){
+ dojo.forEach(inIndex, this.deselect, this);
+ return;
+ }
+ inIndex = Number(inIndex);
+ if(this.selectedIndex == inIndex){
+ this.selectedIndex = -1;
+ }
+ if(this.selected[inIndex]){
+ if(this.onCanDeselect(inIndex) === false){
+ return;
+ }
+ var rowNode = this.grid.getRowNode(inIndex);
+ if(rowNode){
+ dojo.attr(rowNode,"aria-selected","false");
+ }
+ this._beginUpdate();
+ delete this.selected[inIndex];
+ //this.grid.onDeselected(inIndex);
+ this.onDeselected(inIndex);
+ //this.onSetSelected(inIndex, false);
+ this._endUpdate();
+ }
+ },
+
+ setSelected: function(inIndex, inSelect){
+ this[(inSelect ? 'addToSelection' : 'deselect')](inIndex);
+ },
+
+ toggleSelect: function(inIndex){
+ if(dojo.isArray(inIndex)){
+ dojo.forEach(inIndex, this.toggleSelect, this);
+ return;
+ }
+ this.setSelected(inIndex, !this.selected[inIndex]);
+ },
+
+ _range: function(inFrom, inTo, func){
+ var s = (inFrom >= 0 ? inFrom : inTo), e = inTo;
+ if(s > e){
+ e = s;
+ s = inTo;
+ }
+ for(var i=s; i<=e; i++){
+ func(i);
+ }
+ },
+
+ selectRange: function(inFrom, inTo){
+ this._range(inFrom, inTo, dojo.hitch(this, "addToSelection"));
+ },
+
+ deselectRange: function(inFrom, inTo){
+ this._range(inFrom, inTo, dojo.hitch(this, "deselect"));
+ },
+
+ insert: function(inIndex){
+ this.selected.splice(inIndex, 0, false);
+ if(this.selectedIndex >= inIndex){
+ this.selectedIndex++;
+ }
+ },
+
+ remove: function(inIndex){
+ this.selected.splice(inIndex, 1);
+ if(this.selectedIndex >= inIndex){
+ this.selectedIndex--;
+ }
+ },
+
+ deselectAll: function(inExcept){
+ for(var i in this.selected){
+ if((i!=inExcept)&&(this.selected[i]===true)){
+ this.deselect(i);
+ }
+ }
+ },
+
+ clickSelect: function(inIndex, inCtrlKey, inShiftKey){
+ if(this.mode == 'none'){ return; }
+ this._beginUpdate();
+ if(this.mode != 'extended'){
+ this.select(inIndex);
+ }else{
+ var lastSelected = this.selectedIndex;
+ if(!inCtrlKey){
+ this.deselectAll(inIndex);
+ }
+ if(inShiftKey){
+ this.selectRange(lastSelected, inIndex);
+ }else if(inCtrlKey){
+ this.toggleSelect(inIndex);
+ }else{
+ this.addToSelection(inIndex);
+ }
+ }
+ this._endUpdate();
+ },
+
+ clickSelectEvent: function(e){
+ this.clickSelect(e.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ },
+
+ clear: function(){
+ this._beginUpdate();
+ this.deselectAll();
+ this._endUpdate();
+ }
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/Selection.xd.js b/js/dojo-1.6/dojox/grid/Selection.xd.js
new file mode 100644
index 0000000..1e42787
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/Selection.xd.js
@@ -0,0 +1,275 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", 'dojox.grid.Selection']],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource['dojox.grid.Selection']){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource['dojox.grid.Selection'] = true;
+dojo.provide('dojox.grid.Selection');
+
+dojo.declare("dojox.grid.Selection", null, {
+ // summary:
+ // Manages row selection for grid. Owned by grid and used internally
+ // for selection. Override to implement custom selection.
+
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ this.selected = [];
+
+ this.setMode(inGrid.selectionMode);
+ },
+
+ mode: 'extended',
+
+ selected: null,
+ updating: 0,
+ selectedIndex: -1,
+
+ setMode: function(mode){
+ if(this.selected.length){
+ this.deselectAll();
+ }
+ if(mode != 'extended' && mode != 'multiple' && mode != 'single' && mode != 'none'){
+ this.mode = 'extended';
+ }else{
+ this.mode = mode;
+ }
+ },
+
+ onCanSelect: function(inIndex){
+ return this.grid.onCanSelect(inIndex);
+ },
+
+ onCanDeselect: function(inIndex){
+ return this.grid.onCanDeselect(inIndex);
+ },
+
+ onSelected: function(inIndex){
+ },
+
+ onDeselected: function(inIndex){
+ },
+
+ //onSetSelected: function(inIndex, inSelect) { };
+ onChanging: function(){
+ },
+
+ onChanged: function(){
+ },
+
+ isSelected: function(inIndex){
+ if(this.mode == 'none'){
+ return false;
+ }
+ return this.selected[inIndex];
+ },
+
+ getFirstSelected: function(){
+ if(!this.selected.length||this.mode == 'none'){ return -1; }
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ getNextSelected: function(inPrev){
+ if(this.mode == 'none'){ return -1; }
+ for(var i=inPrev+1, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ getSelected: function(){
+ var result = [];
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ result.push(i);
+ }
+ }
+ return result;
+ },
+
+ getSelectedCount: function(){
+ var c = 0;
+ for(var i=0; i<this.selected.length; i++){
+ if(this.selected[i]){
+ c++;
+ }
+ }
+ return c;
+ },
+
+ _beginUpdate: function(){
+ if(this.updating === 0){
+ this.onChanging();
+ }
+ this.updating++;
+ },
+
+ _endUpdate: function(){
+ this.updating--;
+ if(this.updating === 0){
+ this.onChanged();
+ }
+ },
+
+ select: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(this.mode != 'multiple'){
+ this.deselectAll(inIndex);
+ this.addToSelection(inIndex);
+ }else{
+ this.toggleSelect(inIndex);
+ }
+ },
+
+ addToSelection: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(dojo.isArray(inIndex)){
+ dojo.forEach(inIndex, this.addToSelection, this);
+ return;
+ }
+ inIndex = Number(inIndex);
+ if(this.selected[inIndex]){
+ this.selectedIndex = inIndex;
+ }else{
+ if(this.onCanSelect(inIndex) !== false){
+ this.selectedIndex = inIndex;
+ var rowNode = this.grid.getRowNode(inIndex);
+ if(rowNode){
+ dojo.attr(rowNode,"aria-selected","true");
+ }
+ this._beginUpdate();
+ this.selected[inIndex] = true;
+ //this.grid.onSelected(inIndex);
+ this.onSelected(inIndex);
+ //this.onSetSelected(inIndex, true);
+ this._endUpdate();
+ }
+ }
+ },
+
+ deselect: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(dojo.isArray(inIndex)){
+ dojo.forEach(inIndex, this.deselect, this);
+ return;
+ }
+ inIndex = Number(inIndex);
+ if(this.selectedIndex == inIndex){
+ this.selectedIndex = -1;
+ }
+ if(this.selected[inIndex]){
+ if(this.onCanDeselect(inIndex) === false){
+ return;
+ }
+ var rowNode = this.grid.getRowNode(inIndex);
+ if(rowNode){
+ dojo.attr(rowNode,"aria-selected","false");
+ }
+ this._beginUpdate();
+ delete this.selected[inIndex];
+ //this.grid.onDeselected(inIndex);
+ this.onDeselected(inIndex);
+ //this.onSetSelected(inIndex, false);
+ this._endUpdate();
+ }
+ },
+
+ setSelected: function(inIndex, inSelect){
+ this[(inSelect ? 'addToSelection' : 'deselect')](inIndex);
+ },
+
+ toggleSelect: function(inIndex){
+ if(dojo.isArray(inIndex)){
+ dojo.forEach(inIndex, this.toggleSelect, this);
+ return;
+ }
+ this.setSelected(inIndex, !this.selected[inIndex]);
+ },
+
+ _range: function(inFrom, inTo, func){
+ var s = (inFrom >= 0 ? inFrom : inTo), e = inTo;
+ if(s > e){
+ e = s;
+ s = inTo;
+ }
+ for(var i=s; i<=e; i++){
+ func(i);
+ }
+ },
+
+ selectRange: function(inFrom, inTo){
+ this._range(inFrom, inTo, dojo.hitch(this, "addToSelection"));
+ },
+
+ deselectRange: function(inFrom, inTo){
+ this._range(inFrom, inTo, dojo.hitch(this, "deselect"));
+ },
+
+ insert: function(inIndex){
+ this.selected.splice(inIndex, 0, false);
+ if(this.selectedIndex >= inIndex){
+ this.selectedIndex++;
+ }
+ },
+
+ remove: function(inIndex){
+ this.selected.splice(inIndex, 1);
+ if(this.selectedIndex >= inIndex){
+ this.selectedIndex--;
+ }
+ },
+
+ deselectAll: function(inExcept){
+ for(var i in this.selected){
+ if((i!=inExcept)&&(this.selected[i]===true)){
+ this.deselect(i);
+ }
+ }
+ },
+
+ clickSelect: function(inIndex, inCtrlKey, inShiftKey){
+ if(this.mode == 'none'){ return; }
+ this._beginUpdate();
+ if(this.mode != 'extended'){
+ this.select(inIndex);
+ }else{
+ var lastSelected = this.selectedIndex;
+ if(!inCtrlKey){
+ this.deselectAll(inIndex);
+ }
+ if(inShiftKey){
+ this.selectRange(lastSelected, inIndex);
+ }else if(inCtrlKey){
+ this.toggleSelect(inIndex);
+ }else{
+ this.addToSelection(inIndex);
+ }
+ }
+ this._endUpdate();
+ },
+
+ clickSelectEvent: function(e){
+ this.clickSelect(e.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ },
+
+ clear: function(){
+ this._beginUpdate();
+ this.deselectAll();
+ this._endUpdate();
+ }
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/TreeGrid.js b/js/dojo-1.6/dojox/grid/TreeGrid.js
new file mode 100644
index 0000000..3d85d08
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/TreeGrid.js
@@ -0,0 +1,962 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.TreeGrid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.TreeGrid"] = true;
+dojo.experimental("dojox.grid.TreeGrid");
+
+dojo.provide("dojox.grid.TreeGrid");
+
+dojo.require("dojox.grid.DataGrid");
+dojo.require("dojox.grid._TreeView");
+dojo.require("dojox.grid.cells.tree");
+dojo.require("dojox.grid.TreeSelection");
+
+dojo.declare("dojox.grid._TreeAggregator", null, {
+ cells: [],
+ grid: null,
+ childFields: [],
+
+ constructor: function(kwArgs){
+ this.cells = kwArgs.cells || [];
+ this.childFields = kwArgs.childFields || [];
+ this.grid = kwArgs.grid;
+ this.store = this.grid.store;
+ },
+ _cacheValue: function(cache, id, value){
+ cache[id] = value;
+ return value;
+ },
+ clearSubtotalCache: function(){
+ // summary:
+ // Clears the subtotal cache so that we are forced to recalc it
+ // (or reread it) again. This is needed, for example, when
+ // column order is changed.
+ if(this.store){
+ delete this.store._cachedAggregates;
+ }
+ },
+
+ cnt: function(cell, level, item){
+ // summary:
+ // calculates the count of the children of item at the given level
+ var total = 0;
+ var store = this.store;
+ var childFields = this.childFields;
+ if(childFields[level]){
+ var children = store.getValues(item, childFields[level]);
+ if (cell.index <= level + 1){
+ total = children.length;
+ }else{
+ dojo.forEach(children, function(c){
+ total += this.getForCell(cell, level + 1, c, "cnt");
+ }, this);
+ }
+ }else{
+ total = 1;
+ }
+ return total;
+ },
+ sum: function(cell, level, item){
+ // summary:
+ // calculates the sum of the children of item at the given level
+ var total = 0;
+ var store = this.store;
+ var childFields = this.childFields;
+ if(childFields[level]){
+ dojo.forEach(store.getValues(item, childFields[level]), function(c){
+ total += this.getForCell(cell, level + 1, c, "sum");
+ }, this);
+ }else{
+ total += store.getValue(item, cell.field);
+ }
+ return total;
+ },
+ value: function(cell, level, item){
+ // summary:
+ // Empty function so that we can set "aggregate='value'" to
+ // force loading from the data - and bypass calculating
+ },
+ getForCell: function(cell, level, item, type){
+ // summary:
+ // Gets the value of the given cell at the given level and type.
+ // type can be one of "sum", "cnt", or "value". If itemAggregates
+ // is set and can be used, it is used instead. Values are also
+ // cached to prevent calculating them too often.
+ var store = this.store;
+ if(!store || !item || !store.isItem(item)){ return ""; }
+ var storeCache = store._cachedAggregates = store._cachedAggregates || {};
+ var id = store.getIdentity(item);
+ var itemCache = storeCache[id] = storeCache[id] || [];
+ if(!cell.getOpenState){
+ cell = this.grid.getCell(cell.layoutIndex + level + 1);
+ }
+ var idx = cell.index;
+ var idxCache = itemCache[idx] = itemCache[idx] || {};
+ type = (type || (cell.parentCell ? cell.parentCell.aggregate : "sum"))||"sum";
+ var attr = cell.field;
+ if(attr == store.getLabelAttributes()[0]){
+ // If our attribute is one of the label attributes, we should
+ // use cnt instead (since it makes no sense to do a sum of labels)
+ type = "cnt";
+ }
+ var typeCache = idxCache[type] = idxCache[type] || [];
+
+ // See if we have it in our cache immediately for easy returning
+ if(typeCache[level] != undefined){
+ return typeCache[level];
+ }
+
+ // See if they have specified a valid field
+ var field = ((cell.parentCell && cell.parentCell.itemAggregates) ?
+ cell.parentCell.itemAggregates[cell.idxInParent] : "")||"";
+ if(field && store.hasAttribute(item, field)){
+ return this._cacheValue(typeCache, level, store.getValue(item, field));
+ }else if(field){
+ return this._cacheValue(typeCache, level, 0);
+ }
+
+ // Calculate it
+ return this._cacheValue(typeCache, level, this[type](cell, level, item));
+ }
+});
+
+dojo.declare("dojox.grid._TreeLayout", dojox.grid._Layout, {
+ // Whether or not we are collapsable - this is calculated when we
+ // set our structure.
+ _isCollapsable: false,
+
+ _getInternalStructure: function(inStructure){
+ // Create a "Tree View" with 1 row containing references for
+ // each column (recursively)
+ var g = this.grid;
+
+ var s = inStructure;
+ var cells = s[0].cells[0];
+ var tree = {
+ type: "dojox.grid._TreeView",
+ cells: [[]]
+ };
+ var cFields = [];
+ var maxLevels = 0;
+ var getTreeCells = function(parentCell, level){
+ var children = parentCell.children;
+ var cloneTreeCell = function(originalCell, idx){
+ var k, n = {};
+ for(k in originalCell){
+ n[k] = originalCell[k];
+ }
+ n = dojo.mixin(n, {
+ level: level,
+ idxInParent: level > 0 ? idx : -1,
+ parentCell: level > 0 ? parentCell : null
+ });
+ return n;
+ };
+ var ret = [];
+ dojo.forEach(children, function(c, idx){
+ if("children" in c){
+ cFields.push(c.field);
+ var last = ret[ret.length - 1];
+ last.isCollapsable = true;
+ c.level = level;
+ ret = ret.concat(getTreeCells(c, level + 1));
+ }else{
+ ret.push(cloneTreeCell(c, idx));
+ }
+ });
+ maxLevels = Math.max(maxLevels, level);
+ return ret;
+ };
+ var tCell = {children: cells, itemAggregates: []};
+ tree.cells[0] = getTreeCells(tCell, 0);
+ g.aggregator = new dojox.grid._TreeAggregator({cells: tree.cells[0],
+ grid: g,
+ childFields: cFields});
+ if(g.scroller && g.defaultOpen){
+ g.scroller.defaultRowHeight = g.scroller._origDefaultRowHeight * (2 * maxLevels + 1);
+ }
+ return [ tree ];
+ },
+
+ setStructure: function(inStructure){
+ // Mangle the structure a bit and make it work as desired
+ var s = inStructure;
+ var g = this.grid;
+ // Only supporting single-view, single row or else we
+ // are not collapsable
+ if(g && g.treeModel && !dojo.every(s, function(i){
+ return ("cells" in i);
+ })){
+ s = arguments[0] = [{cells:[s]}];
+ }
+ if(s.length == 1 && s[0].cells.length == 1){
+ if(g && g.treeModel){
+ s[0].type = "dojox.grid._TreeView";
+ this._isCollapsable = true;
+ s[0].cells[0][(this.grid.treeModel?this.grid.expandoCell:0)].isCollapsable = true;
+ }else{
+ var childCells = dojo.filter(s[0].cells[0], function(c){
+ return ("children" in c);
+ });
+ if(childCells.length === 1){
+ this._isCollapsable = true;
+ }
+ }
+ }
+ if(this._isCollapsable && (!g || !g.treeModel)){
+ arguments[0] = this._getInternalStructure(s);
+ }
+ this.inherited(arguments);
+ },
+
+ addCellDef: function(inRowIndex, inCellIndex, inDef){
+ var obj = this.inherited(arguments);
+ return dojo.mixin(obj, dojox.grid.cells.TreeCell);
+ }
+});
+
+dojo.declare("dojox.grid.TreePath", null, {
+ level: 0,
+ _str: "",
+ _arr: null,
+ grid: null,
+ store: null,
+ cell: null,
+ item: null,
+
+ constructor: function(/*String|Integer[]|Integer|dojox.grid.TreePath*/ path, /*dojox.grid.TreeGrid*/ grid){
+ if(dojo.isString(path)){
+ this._str = path;
+ this._arr = dojo.map(path.split('/'), function(item){ return parseInt(item, 10); });
+ }else if(dojo.isArray(path)){
+ this._str = path.join('/');
+ this._arr = path.slice(0);
+ }else if(typeof path == "number"){
+ this._str = String(path);
+ this._arr = [path];
+ }else{
+ this._str = path._str;
+ this._arr = path._arr.slice(0);
+ }
+ this.level = this._arr.length-1;
+ this.grid = grid;
+ this.store = this.grid.store;
+ if(grid.treeModel){
+ this.cell = grid.layout.cells[grid.expandoCell];
+ }else{
+ this.cell = grid.layout.cells[this.level];
+ }
+ },
+ item: function(){
+ // summary:
+ // gets the dojo.data item associated with this path
+ if(!this._item){
+ this._item = this.grid.getItem(this._arr);
+ }
+ return this._item;
+ },
+ compare: function(path /*dojox.grid.TreePath|String|Array*/){
+ // summary:
+ // compares two paths
+ if(dojo.isString(path) || dojo.isArray(path)){
+ if(this._str == path){ return 0; }
+ if(path.join && this._str == path.join('/')){ return 0; }
+ path = new dojox.grid.TreePath(path, this.grid);
+ }else if(path instanceof dojox.grid.TreePath){
+ if(this._str == path._str){ return 0; }
+ }
+ for(var i=0, l=(this._arr.length < path._arr.length ? this._arr.length : path._arr.length); i<l; i++){
+ if(this._arr[i]<path._arr[i]){ return -1; }
+ if(this._arr[i]>path._arr[i]){ return 1; }
+ }
+ if(this._arr.length<path._arr.length){ return -1; }
+ if(this._arr.length>path._arr.length){ return 1; }
+ return 0;
+ },
+ isOpen: function(){
+ // summary:
+ // Returns the open state of this cell.
+ return this.cell.openStates && this.cell.getOpenState(this.item());
+ },
+ previous: function(){
+ // summary:
+ // Returns the path that is before this path in the
+ // grid. If no path is found, returns null.
+ var new_path = this._arr.slice(0);
+
+ if(this._str == "0"){
+ return null;
+ }
+
+ var last = new_path.length-1;
+
+ if(new_path[last] === 0){
+ new_path.pop();
+ return new dojox.grid.TreePath(new_path, this.grid);
+ }
+
+ new_path[last]--;
+ var path = new dojox.grid.TreePath(new_path, this.grid);
+ return path.lastChild(true);
+ },
+ next: function(){
+ // summary:
+ // Returns the next path in the grid. If no path
+ // is found, returns null.
+ var new_path = this._arr.slice(0);
+
+ if(this.isOpen()){
+ new_path.push(0);
+ }else{
+ new_path[new_path.length-1]++;
+ for(var i=this.level; i>=0; i--){
+ var item = this.grid.getItem(new_path.slice(0, i+1));
+ if(i>0){
+ if(!item){
+ new_path.pop();
+ new_path[i-1]++;
+ }
+ }else{
+ if(!item){
+ return null;
+ }
+ }
+ }
+ }
+
+ return new dojox.grid.TreePath(new_path, this.grid);
+ },
+ children: function(alwaysReturn){
+ // summary:
+ // Returns the child data items of this row. If this
+ // row isn't open and alwaysReturn is falsey, returns null.
+ if(!this.isOpen()&&!alwaysReturn){
+ return null;
+ }
+ var items = [];
+ var model = this.grid.treeModel;
+ if(model){
+ var item = this.item();
+ var store = model.store;
+ if(!model.mayHaveChildren(item)){
+ return null;
+ }
+ dojo.forEach(model.childrenAttrs, function(attr){
+ items = items.concat(store.getValues(item, attr));
+ });
+ }else{
+ items = this.store.getValues(this.item(), this.grid.layout.cells[this.cell.level+1].parentCell.field);
+ if(items.length>1&&this.grid.sortChildItems){
+ var sortProps = this.grid.getSortProps();
+ if(sortProps&&sortProps.length){
+ var attr = sortProps[0].attribute,
+ grid = this.grid;
+ if(attr&&items[0][attr]){
+ var desc = !!sortProps[0].descending;
+ items = items.slice(0); // don't touch the array in the store, make a copy
+ items.sort(function(a, b){
+ return grid._childItemSorter(a, b, attr, desc);
+ });
+ }
+ }
+ }
+ }
+ return items;
+ },
+ childPaths: function(){
+ var childItems = this.children();
+ if(!childItems){
+ return [];
+ }
+ return dojo.map(childItems, function(item, index){
+ return new dojox.grid.TreePath(this._str + '/' + index, this.grid);
+ }, this);
+ },
+ parent: function(){
+ // summary:
+ // Returns the parent path of this path. If this is a
+ // top-level row, returns null.
+ if(this.level === 0){
+ return null;
+ }
+ return new dojox.grid.TreePath(this._arr.slice(0, this.level), this.grid);
+ },
+ lastChild: function(/*Boolean?*/ traverse){
+ // summary:
+ // Returns the last child row below this path. If traverse
+ // is true, will traverse down to find the last child row
+ // of this branch. If there are no children, returns itself.
+ var children = this.children();
+ if(!children || !children.length){
+ return this;
+ }
+ var path = new dojox.grid.TreePath(this._str + "/" + String(children.length-1), this.grid);
+ if(!traverse){
+ return path;
+ }
+ return path.lastChild(true);
+ },
+ toString: function(){
+ return this._str;
+ }
+});
+
+dojo.declare("dojox.grid._TreeFocusManager", dojox.grid._FocusManager, {
+ setFocusCell: function(inCell, inRowIndex){
+ if(inCell && inCell.getNode(inRowIndex)){
+ this.inherited(arguments);
+ }
+ },
+ isLastFocusCell: function(){
+ if(this.cell && this.cell.index == this.grid.layout.cellCount-1){
+ var path = new dojox.grid.TreePath(this.grid.rowCount-1, this.grid);
+ path = path.lastChild(true);
+ return this.rowIndex == path._str;
+ }
+ return false;
+ },
+ next: function(){
+ // summary:
+ // focus next grid cell
+ if(this.cell){
+ var row=this.rowIndex, col=this.cell.index+1, cc=this.grid.layout.cellCount-1;
+ var path = new dojox.grid.TreePath(this.rowIndex, this.grid);
+ if(col > cc){
+ var new_path = path.next();
+ if(!new_path){
+ col--;
+ }else{
+ col = 0;
+ path = new_path;
+ }
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var nextCell = this.grid.getCell(col);
+ if (!this.isLastFocusCell() && !nextCell.editable){
+ this._focusifyCellNode(false);
+ this.cell=nextCell;
+ this.rowIndex=path._str;
+ this.next();
+ return;
+ }
+ }
+ this.setFocusIndex(path._str, col);
+ }
+ },
+ previous: function(){
+ // summary:
+ // focus previous grid cell
+ if(this.cell){
+ var row=(this.rowIndex || 0), col=(this.cell.index || 0) - 1;
+ var path = new dojox.grid.TreePath(row, this.grid);
+ if(col < 0){
+ var new_path = path.previous();
+ if(!new_path){
+ col = 0;
+ }else{
+ col = this.grid.layout.cellCount-1;
+ path = new_path;
+ }
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var prevCell = this.grid.getCell(col);
+ if (!this.isFirstFocusCell() && !prevCell.editable){
+ this._focusifyCellNode(false);
+ this.cell=prevCell;
+ this.rowIndex=path._str;
+ this.previous();
+ return;
+ }
+ }
+ this.setFocusIndex(path._str, col);
+ }
+ },
+ move: function(inRowDelta, inColDelta){
+ if(this.isNavHeader()){
+ this.inherited(arguments);
+ return;
+ }
+ if(!this.cell){ return; }
+ // Handle grid proper.
+ var sc = this.grid.scroller,
+ r = this.rowIndex,
+ rc = this.grid.rowCount-1,
+ path = new dojox.grid.TreePath(this.rowIndex, this.grid);
+ if(inRowDelta){
+ var row;
+ if(inRowDelta>0){
+ path = path.next();
+ row = path._arr[0];
+ if(row > sc.getLastPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r));
+ }
+ }else if(inRowDelta<0){
+ path = path.previous();
+ row = path._arr[0];
+ if(row <= sc.getPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row));
+ }
+ }
+ }
+ var cc = this.grid.layout.cellCount-1,
+ i = this.cell.index,
+ col = Math.min(cc, Math.max(0, i+inColDelta));
+ var cell = this.grid.getCell(col);
+ var colDir = inColDelta < 0 ? -1 : 1;
+ while(col>=0 && col < cc && cell && cell.hidden === true){
+ // skip hidden cells
+ col += colDir;
+ cell = this.grid.getCell(col);
+ }
+ if (!cell || cell.hidden === true){
+ // don't change col if would move to hidden
+ col = i;
+ }
+ if(inRowDelta){
+ this.grid.updateRow(r);
+ }
+ this.setFocusIndex(path._str, col);
+ }
+});
+
+dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
+ // summary:
+ // A grid that supports nesting rows - it provides an expando function
+ // similar to dijit.Tree. It also provides mechanisms for aggregating
+ // the values of subrows
+ //
+ // description:
+ // TreeGrid currently only works on "simple" structures. That is,
+ // single-view structures with a single row in them.
+ //
+ // The TreeGrid works using the concept of "levels" - level 0 are the
+ // top-level items.
+
+ // defaultOpen: Boolean
+ // Whether or not we default to open (all levels). This defaults to
+ // false for grids with a treeModel.
+ defaultOpen: true,
+
+ // sortChildItems: Boolean
+ // If true, child items will be returned sorted according to the sorting
+ // properties of the grid.
+ sortChildItems: false,
+
+ // openAtLevels: Array
+ // Which levels we are open at (overrides defaultOpen for the values
+ // that exist here). Its values can be a boolean (true/false) or an
+ // integer (for the # of children to be closed if there are more than
+ // that)
+ openAtLevels: [],
+
+ // treeModel: dijit.tree.ForestStoreModel
+ // A dijit.Tree model that will be used instead of using aggregates.
+ // Setting this value will make the TreeGrid behave like a columnar
+ // tree. When setting this value, defaultOpen will default to false,
+ // and openAtLevels will be ignored.
+ treeModel: null,
+
+ // expandoCell: Integer
+ // When used in conjunction with a treeModel (see above), this is a 0-based
+ // index of the cell in which to place the actual expando
+ expandoCell: 0,
+
+ // private values
+ // aggregator: Object
+ // The aggregator class - it will be populated automatically if we
+ // are a collapsable grid
+ aggregator: null,
+
+
+ // Override this to get our "magic" layout
+ _layoutClass: dojox.grid._TreeLayout,
+
+ createSelection: function(){
+ this.selection = new dojox.grid.TreeSelection(this);
+ },
+
+ _childItemSorter: function(a, b, attribute, descending){
+ var av = this.store.getValue(a, attribute);
+ var bv = this.store.getValue(b, attribute);
+ if(av != bv){
+ return av < bv == descending ? 1 : -1;
+ }
+ return 0;
+ },
+
+ _onNew: function(item, parentInfo){
+ if(!parentInfo || !parentInfo.item){
+ this.inherited(arguments);
+ }else{
+ var idx = this.getItemIndex(parentInfo.item);
+ if(typeof idx == "string"){
+ this.updateRow(idx.split('/')[0]);
+ }else if(idx > -1){
+ this.updateRow(idx);
+ }
+ }
+ },
+
+ _onSet: function(item, attribute, oldValue, newValue){
+ this._checkUpdateStatus();
+ if(this.aggregator){
+ this.aggregator.clearSubtotalCache();
+ }
+ var idx = this.getItemIndex(item);
+ if(typeof idx == "string"){
+ this.updateRow(idx.split('/')[0]);
+ }else if(idx > -1){
+ this.updateRow(idx);
+ }
+ },
+
+ _onDelete: function(item){
+ this._cleanupExpandoCache(this._getItemIndex(item, true), this.store.getIdentity(item), item);
+ this.inherited(arguments);
+ },
+
+ _cleanupExpandoCache: function(index, identity, item){},
+
+ _addItem: function(item, index, noUpdate, dontUpdateRoot){
+ // add our root items to the root of the model's children
+ // list since we don't query the model
+ if(!dontUpdateRoot && this.model && dojo.indexOf(this.model.root.children, item) == -1){
+ this.model.root.children[index] = item;
+ }
+ this.inherited(arguments);
+ },
+
+ getItem: function(/*integer|Array|String*/ idx){
+ // summary:
+ // overridden so that you can pass in a '/' delimited string of indexes to get the
+ // item based off its path...that is, passing in "1/3/2" will get the
+ // 3rd (0-based) child from the 4th child of the 2nd top-level item.
+ var isArray = dojo.isArray(idx);
+ if(dojo.isString(idx) && idx.indexOf('/')){
+ idx = idx.split('/');
+ isArray = true;
+ }
+ if(isArray && idx.length == 1){
+ idx = idx[0];
+ isArray = false;
+ }
+ if(!isArray){
+ return dojox.grid.DataGrid.prototype.getItem.call(this, idx);
+ }
+ var s = this.store;
+ var itm = dojox.grid.DataGrid.prototype.getItem.call(this, idx[0]);
+ var cf, i, j;
+ if(this.aggregator){
+ cf = this.aggregator.childFields||[];
+ if(cf){
+ for(i = 0; i < idx.length - 1 && itm; i++){
+ if(cf[i]){
+ itm = (s.getValues(itm, cf[i])||[])[idx[i + 1]];
+ }else{
+ itm = null;
+ }
+ }
+ }
+ }else if(this.treeModel){
+ cf = this.treeModel.childrenAttrs||[];
+ if(cf&&itm){
+ for(i=1, il=idx.length; (i<il) && itm; i++) {
+ for(j=0, jl=cf.length; j<jl; j++) {
+ if(cf[j]){
+ itm = (s.getValues(itm, cf[j])||[])[idx[i]];
+ }else{
+ itm = null;
+ }
+ if(itm){ break; }
+ }
+ }
+ }
+ }
+ return itm || null;
+ },
+
+ _getItemIndex: function(item, isDeleted){
+ if(!isDeleted && !this.store.isItem(item)){
+ return -1;
+ }
+ var idx = this.inherited(arguments);
+ if(idx == -1){
+ var idty = this.store.getIdentity(item);
+ return this._by_idty_paths[idty] || -1;
+ }
+ return idx;
+ },
+
+ postMixInProperties: function(){
+ if(this.treeModel && !("defaultOpen" in this.params)){
+ // Default open to false for tree models, true for other tree
+ // grids.
+ this.defaultOpen = false;
+ }
+ var def = this.defaultOpen;
+ this.openAtLevels = dojo.map(this.openAtLevels, function(l){
+ if(typeof l == "string"){
+ switch(l.toLowerCase()){
+ case "true":
+ return true;
+ break;
+ case "false":
+ return false;
+ break;
+ default:
+ var r = parseInt(l, 10);
+ if(isNaN(r)){
+ return def;
+ }
+ return r;
+ break;
+ }
+ }
+ return l;
+ });
+ this._by_idty_paths = {};
+ this.inherited(arguments);
+ },
+
+ postCreate: function(){
+ this.inherited(arguments);
+ if(this.treeModel){
+ this._setModel(this.treeModel);
+ }
+ },
+
+ setModel: function(treeModel){
+ this._setModel(treeModel);
+ this._refresh(true);
+ },
+
+ _setModel: function(treeModel){
+ if(treeModel && (!dijit.tree.ForestStoreModel || !(treeModel instanceof dijit.tree.ForestStoreModel))){
+ throw new Error("dojox.grid.TreeGrid: treeModel must be an instance of dijit.tree.ForestStoreModel");
+ }
+ this.treeModel = treeModel;
+ dojo.toggleClass(this.domNode, "dojoxGridTreeModel", this.treeModel ? true : false);
+ this._setQuery(treeModel ? treeModel.query : null);
+ this._setStore(treeModel ? treeModel.store : null);
+ },
+
+ createScroller: function(){
+ this.inherited(arguments);
+ this.scroller._origDefaultRowHeight = this.scroller.defaultRowHeight;
+ },
+
+ createManagers: function(){
+ // summary:
+ // create grid managers for various tasks including rows, focus, selection, editing
+
+ // row manager
+ this.rows = new dojox.grid._RowManager(this);
+ // focus manager
+ this.focus = new dojox.grid._TreeFocusManager(this);
+ // edit manager
+ this.edit = new dojox.grid._EditManager(this);
+ },
+
+ _setStore: function(store){
+ this.inherited(arguments);
+ if(this.treeModel&&!this.treeModel.root.children){
+ this.treeModel.root.children = [];
+ }
+ if(this.aggregator){
+ this.aggregator.store = store;
+ }
+ },
+
+ getDefaultOpenState: function(cellDef, item){
+ // summary:
+ // Returns the default open state for the given definition and item
+ // It reads from the openAtLevels and defaultOpen values of the
+ // grid to calculate if the given item should default to open or
+ // not.
+ var cf;
+ var store = this.store;
+ if(this.treeModel){ return this.defaultOpen; }
+ if(!cellDef || !store || !store.isItem(item) ||
+ !(cf = this.aggregator.childFields[cellDef.level])){
+ return this.defaultOpen;
+ }
+ if(this.openAtLevels.length > cellDef.level){
+ var dVal = this.openAtLevels[cellDef.level];
+ if(typeof dVal == "boolean"){
+ return dVal;
+ }else if(typeof dVal == "number"){
+ return (store.getValues(item, cf).length <= dVal);
+ }
+ }
+ return this.defaultOpen;
+ },
+ onStyleRow: function(row){
+ if(!this.layout._isCollapsable){
+ this.inherited(arguments);
+ return;
+ }
+ var base = dojo.attr(row.node, 'dojoxTreeGridBaseClasses');
+ if(base){
+ row.customClasses = base;
+ }
+ var i = row;
+ var tagName = i.node.tagName.toLowerCase();
+ i.customClasses += (i.odd?" dojoxGridRowOdd":"") +
+ (i.selected&&tagName=='tr'?" dojoxGridRowSelected":"") +
+ (i.over&&tagName=='tr'?" dojoxGridRowOver":"");
+ this.focus.styleRow(i);
+ this.edit.styleRow(i);
+ },
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ if(inRowNode.tagName.toLowerCase() == 'div' && this.aggregator){
+ dojo.query("tr[dojoxTreeGridPath]", inRowNode).forEach(function(rowNode){
+ this.rows.styleRowNode(dojo.attr(rowNode, 'dojoxTreeGridPath'), rowNode);
+ },this);
+ }
+ this.rows.styleRowNode(inRowIndex, inRowNode);
+ }
+ },
+ onCanSelect: function(inRowIndex){
+ var nodes = dojo.query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode);
+ if(nodes.length){
+ if(dojo.hasClass(nodes[0], 'dojoxGridSummaryRow')){
+ return false;
+ }
+ }
+ return this.inherited(arguments);
+ },
+ onKeyDown: function(e){
+ if(e.altKey || e.metaKey){
+ return;
+ }
+ var dk = dojo.keys;
+ switch(e.keyCode){
+ case dk.UP_ARROW:
+ if(!this.edit.isEditing() && this.focus.rowIndex != "0"){
+ dojo.stopEvent(e);
+ this.focus.move(-1, 0);
+ }
+ break;
+ case dk.DOWN_ARROW:
+ var currPath = new dojox.grid.TreePath(this.focus.rowIndex, this);
+ var lastPath = new dojox.grid.TreePath(this.rowCount-1, this);
+ lastPath = lastPath.lastChild(true);
+ if(!this.edit.isEditing() && currPath.toString() != lastPath.toString()){
+ dojo.stopEvent(e);
+ this.focus.move(1, 0);
+ }
+ break;
+ default:
+ this.inherited(arguments);
+ break;
+ }
+ },
+ canEdit: function(inCell, inRowIndex){
+ var node = inCell.getNode(inRowIndex);
+ return node && this._canEdit;
+ },
+ doApplyCellEdit: function(inValue, inRowIndex, inAttrName){
+ var item = this.getItem(inRowIndex);
+ var oldValue = this.store.getValue(item, inAttrName);
+ if(typeof oldValue == 'number'){
+ inValue = isNaN(inValue) ? inValue : parseFloat(inValue);
+ }else if(typeof oldValue == 'boolean'){
+ inValue = inValue == 'true' ? true : inValue == 'false' ? false : inValue;
+ }else if(oldValue instanceof Date){
+ var asDate = new Date(inValue);
+ inValue = isNaN(asDate.getTime()) ? inValue : asDate;
+ }
+ this.store.setValue(item, inAttrName, inValue);
+ this.onApplyCellEdit(inValue, inRowIndex, inAttrName);
+ }
+});
+dojox.grid.TreeGrid.markupFactory = function(props, node, ctor, cellFunc){
+ var d = dojo;
+ var widthFromAttr = function(n){
+ var w = d.attr(n, "width")||"auto";
+ if((w != "auto")&&(w.slice(-2) != "em")&&(w.slice(-1) != "%")){
+ w = parseInt(w, 10)+"px";
+ }
+ return w;
+ };
+
+ var cellsFromMarkup = function(table){
+ var rows;
+ // Don't support colgroup on our grid - single view, single row only
+ if(table.nodeName.toLowerCase() == "table" &&
+ d.query("> colgroup", table).length === 0 &&
+ (rows = d.query("> thead > tr", table)).length == 1){
+ var tr = rows[0];
+ return d.query("> th", rows[0]).map(function(th){
+ // Grab type and field (the only ones that are shared
+ var cell = {
+ type: d.trim(d.attr(th, "cellType")||""),
+ field: d.trim(d.attr(th, "field")||"")
+ };
+ if(cell.type){
+ cell.type = d.getObject(cell.type);
+ }
+
+ var subTable = d.query("> table", th)[0];
+ if(subTable){
+ // If we have a subtable, we are an aggregate and a summary cell
+ cell.name = "";
+ cell.children = cellsFromMarkup(subTable);
+ if(d.hasAttr(th, "itemAggregates")){
+ cell.itemAggregates = d.map(d.attr(th, "itemAggregates").split(","), function(v){
+ return d.trim(v);
+ });
+ }else{
+ cell.itemAggregates = [];
+ }
+ if(d.hasAttr(th, "aggregate")){
+ cell.aggregate = d.attr(th, "aggregate");
+ }
+ cell.type = cell.type || dojox.grid.cells.SubtableCell;
+ }else{
+ // Grab our other stuff we need (mostly what's in the normal
+ // Grid)
+ cell.name = d.trim(d.attr(th, "name")||th.innerHTML);
+ if(d.hasAttr(th, "width")){
+ cell.width = widthFromAttr(th);
+ }
+ if(d.hasAttr(th, "relWidth")){
+ cell.relWidth = window.parseInt(d.attr(th, "relWidth"), 10);
+ }
+ if(d.hasAttr(th, "hidden")){
+ cell.hidden = d.attr(th, "hidden") == "true";
+ }
+ cell.field = cell.field||cell.name;
+ dojox.grid.DataGrid.cell_markupFactory(cellFunc, th, cell);
+ cell.type = cell.type || dojox.grid.cells.Cell;
+ }
+ if(cell.type && cell.type.markupFactory){
+ cell.type.markupFactory(th, cell);
+ }
+ return cell;
+ });
+ }
+ return [];
+ };
+
+ var rows;
+ if( !props.structure ){
+ var row = cellsFromMarkup(node);
+ if(row.length){
+ // Set our structure here - so that we don't try and set it in the
+ // markup factory
+ props.structure = [{__span: Infinity, cells:[row]}];
+ }
+ }
+ return dojox.grid.DataGrid.markupFactory(props, node, ctor, cellFunc);
+};
+
+}
diff --git a/js/dojo-1.6/dojox/grid/TreeGrid.xd.js b/js/dojo-1.6/dojox/grid/TreeGrid.xd.js
new file mode 100644
index 0000000..c6169a5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/TreeGrid.xd.js
@@ -0,0 +1,970 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.TreeGrid"],
+["require", "dojox.grid.DataGrid"],
+["require", "dojox.grid._TreeView"],
+["require", "dojox.grid.cells.tree"],
+["require", "dojox.grid.TreeSelection"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.TreeGrid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.TreeGrid"] = true;
+dojo.experimental("dojox.grid.TreeGrid");
+
+dojo.provide("dojox.grid.TreeGrid");
+
+dojo.require("dojox.grid.DataGrid");
+dojo.require("dojox.grid._TreeView");
+dojo.require("dojox.grid.cells.tree");
+dojo.require("dojox.grid.TreeSelection");
+
+dojo.declare("dojox.grid._TreeAggregator", null, {
+ cells: [],
+ grid: null,
+ childFields: [],
+
+ constructor: function(kwArgs){
+ this.cells = kwArgs.cells || [];
+ this.childFields = kwArgs.childFields || [];
+ this.grid = kwArgs.grid;
+ this.store = this.grid.store;
+ },
+ _cacheValue: function(cache, id, value){
+ cache[id] = value;
+ return value;
+ },
+ clearSubtotalCache: function(){
+ // summary:
+ // Clears the subtotal cache so that we are forced to recalc it
+ // (or reread it) again. This is needed, for example, when
+ // column order is changed.
+ if(this.store){
+ delete this.store._cachedAggregates;
+ }
+ },
+
+ cnt: function(cell, level, item){
+ // summary:
+ // calculates the count of the children of item at the given level
+ var total = 0;
+ var store = this.store;
+ var childFields = this.childFields;
+ if(childFields[level]){
+ var children = store.getValues(item, childFields[level]);
+ if (cell.index <= level + 1){
+ total = children.length;
+ }else{
+ dojo.forEach(children, function(c){
+ total += this.getForCell(cell, level + 1, c, "cnt");
+ }, this);
+ }
+ }else{
+ total = 1;
+ }
+ return total;
+ },
+ sum: function(cell, level, item){
+ // summary:
+ // calculates the sum of the children of item at the given level
+ var total = 0;
+ var store = this.store;
+ var childFields = this.childFields;
+ if(childFields[level]){
+ dojo.forEach(store.getValues(item, childFields[level]), function(c){
+ total += this.getForCell(cell, level + 1, c, "sum");
+ }, this);
+ }else{
+ total += store.getValue(item, cell.field);
+ }
+ return total;
+ },
+ value: function(cell, level, item){
+ // summary:
+ // Empty function so that we can set "aggregate='value'" to
+ // force loading from the data - and bypass calculating
+ },
+ getForCell: function(cell, level, item, type){
+ // summary:
+ // Gets the value of the given cell at the given level and type.
+ // type can be one of "sum", "cnt", or "value". If itemAggregates
+ // is set and can be used, it is used instead. Values are also
+ // cached to prevent calculating them too often.
+ var store = this.store;
+ if(!store || !item || !store.isItem(item)){ return ""; }
+ var storeCache = store._cachedAggregates = store._cachedAggregates || {};
+ var id = store.getIdentity(item);
+ var itemCache = storeCache[id] = storeCache[id] || [];
+ if(!cell.getOpenState){
+ cell = this.grid.getCell(cell.layoutIndex + level + 1);
+ }
+ var idx = cell.index;
+ var idxCache = itemCache[idx] = itemCache[idx] || {};
+ type = (type || (cell.parentCell ? cell.parentCell.aggregate : "sum"))||"sum";
+ var attr = cell.field;
+ if(attr == store.getLabelAttributes()[0]){
+ // If our attribute is one of the label attributes, we should
+ // use cnt instead (since it makes no sense to do a sum of labels)
+ type = "cnt";
+ }
+ var typeCache = idxCache[type] = idxCache[type] || [];
+
+ // See if we have it in our cache immediately for easy returning
+ if(typeCache[level] != undefined){
+ return typeCache[level];
+ }
+
+ // See if they have specified a valid field
+ var field = ((cell.parentCell && cell.parentCell.itemAggregates) ?
+ cell.parentCell.itemAggregates[cell.idxInParent] : "")||"";
+ if(field && store.hasAttribute(item, field)){
+ return this._cacheValue(typeCache, level, store.getValue(item, field));
+ }else if(field){
+ return this._cacheValue(typeCache, level, 0);
+ }
+
+ // Calculate it
+ return this._cacheValue(typeCache, level, this[type](cell, level, item));
+ }
+});
+
+dojo.declare("dojox.grid._TreeLayout", dojox.grid._Layout, {
+ // Whether or not we are collapsable - this is calculated when we
+ // set our structure.
+ _isCollapsable: false,
+
+ _getInternalStructure: function(inStructure){
+ // Create a "Tree View" with 1 row containing references for
+ // each column (recursively)
+ var g = this.grid;
+
+ var s = inStructure;
+ var cells = s[0].cells[0];
+ var tree = {
+ type: "dojox.grid._TreeView",
+ cells: [[]]
+ };
+ var cFields = [];
+ var maxLevels = 0;
+ var getTreeCells = function(parentCell, level){
+ var children = parentCell.children;
+ var cloneTreeCell = function(originalCell, idx){
+ var k, n = {};
+ for(k in originalCell){
+ n[k] = originalCell[k];
+ }
+ n = dojo.mixin(n, {
+ level: level,
+ idxInParent: level > 0 ? idx : -1,
+ parentCell: level > 0 ? parentCell : null
+ });
+ return n;
+ };
+ var ret = [];
+ dojo.forEach(children, function(c, idx){
+ if("children" in c){
+ cFields.push(c.field);
+ var last = ret[ret.length - 1];
+ last.isCollapsable = true;
+ c.level = level;
+ ret = ret.concat(getTreeCells(c, level + 1));
+ }else{
+ ret.push(cloneTreeCell(c, idx));
+ }
+ });
+ maxLevels = Math.max(maxLevels, level);
+ return ret;
+ };
+ var tCell = {children: cells, itemAggregates: []};
+ tree.cells[0] = getTreeCells(tCell, 0);
+ g.aggregator = new dojox.grid._TreeAggregator({cells: tree.cells[0],
+ grid: g,
+ childFields: cFields});
+ if(g.scroller && g.defaultOpen){
+ g.scroller.defaultRowHeight = g.scroller._origDefaultRowHeight * (2 * maxLevels + 1);
+ }
+ return [ tree ];
+ },
+
+ setStructure: function(inStructure){
+ // Mangle the structure a bit and make it work as desired
+ var s = inStructure;
+ var g = this.grid;
+ // Only supporting single-view, single row or else we
+ // are not collapsable
+ if(g && g.treeModel && !dojo.every(s, function(i){
+ return ("cells" in i);
+ })){
+ s = arguments[0] = [{cells:[s]}];
+ }
+ if(s.length == 1 && s[0].cells.length == 1){
+ if(g && g.treeModel){
+ s[0].type = "dojox.grid._TreeView";
+ this._isCollapsable = true;
+ s[0].cells[0][(this.grid.treeModel?this.grid.expandoCell:0)].isCollapsable = true;
+ }else{
+ var childCells = dojo.filter(s[0].cells[0], function(c){
+ return ("children" in c);
+ });
+ if(childCells.length === 1){
+ this._isCollapsable = true;
+ }
+ }
+ }
+ if(this._isCollapsable && (!g || !g.treeModel)){
+ arguments[0] = this._getInternalStructure(s);
+ }
+ this.inherited(arguments);
+ },
+
+ addCellDef: function(inRowIndex, inCellIndex, inDef){
+ var obj = this.inherited(arguments);
+ return dojo.mixin(obj, dojox.grid.cells.TreeCell);
+ }
+});
+
+dojo.declare("dojox.grid.TreePath", null, {
+ level: 0,
+ _str: "",
+ _arr: null,
+ grid: null,
+ store: null,
+ cell: null,
+ item: null,
+
+ constructor: function(/*String|Integer[]|Integer|dojox.grid.TreePath*/ path, /*dojox.grid.TreeGrid*/ grid){
+ if(dojo.isString(path)){
+ this._str = path;
+ this._arr = dojo.map(path.split('/'), function(item){ return parseInt(item, 10); });
+ }else if(dojo.isArray(path)){
+ this._str = path.join('/');
+ this._arr = path.slice(0);
+ }else if(typeof path == "number"){
+ this._str = String(path);
+ this._arr = [path];
+ }else{
+ this._str = path._str;
+ this._arr = path._arr.slice(0);
+ }
+ this.level = this._arr.length-1;
+ this.grid = grid;
+ this.store = this.grid.store;
+ if(grid.treeModel){
+ this.cell = grid.layout.cells[grid.expandoCell];
+ }else{
+ this.cell = grid.layout.cells[this.level];
+ }
+ },
+ item: function(){
+ // summary:
+ // gets the dojo.data item associated with this path
+ if(!this._item){
+ this._item = this.grid.getItem(this._arr);
+ }
+ return this._item;
+ },
+ compare: function(path /*dojox.grid.TreePath|String|Array*/){
+ // summary:
+ // compares two paths
+ if(dojo.isString(path) || dojo.isArray(path)){
+ if(this._str == path){ return 0; }
+ if(path.join && this._str == path.join('/')){ return 0; }
+ path = new dojox.grid.TreePath(path, this.grid);
+ }else if(path instanceof dojox.grid.TreePath){
+ if(this._str == path._str){ return 0; }
+ }
+ for(var i=0, l=(this._arr.length < path._arr.length ? this._arr.length : path._arr.length); i<l; i++){
+ if(this._arr[i]<path._arr[i]){ return -1; }
+ if(this._arr[i]>path._arr[i]){ return 1; }
+ }
+ if(this._arr.length<path._arr.length){ return -1; }
+ if(this._arr.length>path._arr.length){ return 1; }
+ return 0;
+ },
+ isOpen: function(){
+ // summary:
+ // Returns the open state of this cell.
+ return this.cell.openStates && this.cell.getOpenState(this.item());
+ },
+ previous: function(){
+ // summary:
+ // Returns the path that is before this path in the
+ // grid. If no path is found, returns null.
+ var new_path = this._arr.slice(0);
+
+ if(this._str == "0"){
+ return null;
+ }
+
+ var last = new_path.length-1;
+
+ if(new_path[last] === 0){
+ new_path.pop();
+ return new dojox.grid.TreePath(new_path, this.grid);
+ }
+
+ new_path[last]--;
+ var path = new dojox.grid.TreePath(new_path, this.grid);
+ return path.lastChild(true);
+ },
+ next: function(){
+ // summary:
+ // Returns the next path in the grid. If no path
+ // is found, returns null.
+ var new_path = this._arr.slice(0);
+
+ if(this.isOpen()){
+ new_path.push(0);
+ }else{
+ new_path[new_path.length-1]++;
+ for(var i=this.level; i>=0; i--){
+ var item = this.grid.getItem(new_path.slice(0, i+1));
+ if(i>0){
+ if(!item){
+ new_path.pop();
+ new_path[i-1]++;
+ }
+ }else{
+ if(!item){
+ return null;
+ }
+ }
+ }
+ }
+
+ return new dojox.grid.TreePath(new_path, this.grid);
+ },
+ children: function(alwaysReturn){
+ // summary:
+ // Returns the child data items of this row. If this
+ // row isn't open and alwaysReturn is falsey, returns null.
+ if(!this.isOpen()&&!alwaysReturn){
+ return null;
+ }
+ var items = [];
+ var model = this.grid.treeModel;
+ if(model){
+ var item = this.item();
+ var store = model.store;
+ if(!model.mayHaveChildren(item)){
+ return null;
+ }
+ dojo.forEach(model.childrenAttrs, function(attr){
+ items = items.concat(store.getValues(item, attr));
+ });
+ }else{
+ items = this.store.getValues(this.item(), this.grid.layout.cells[this.cell.level+1].parentCell.field);
+ if(items.length>1&&this.grid.sortChildItems){
+ var sortProps = this.grid.getSortProps();
+ if(sortProps&&sortProps.length){
+ var attr = sortProps[0].attribute,
+ grid = this.grid;
+ if(attr&&items[0][attr]){
+ var desc = !!sortProps[0].descending;
+ items = items.slice(0); // don't touch the array in the store, make a copy
+ items.sort(function(a, b){
+ return grid._childItemSorter(a, b, attr, desc);
+ });
+ }
+ }
+ }
+ }
+ return items;
+ },
+ childPaths: function(){
+ var childItems = this.children();
+ if(!childItems){
+ return [];
+ }
+ return dojo.map(childItems, function(item, index){
+ return new dojox.grid.TreePath(this._str + '/' + index, this.grid);
+ }, this);
+ },
+ parent: function(){
+ // summary:
+ // Returns the parent path of this path. If this is a
+ // top-level row, returns null.
+ if(this.level === 0){
+ return null;
+ }
+ return new dojox.grid.TreePath(this._arr.slice(0, this.level), this.grid);
+ },
+ lastChild: function(/*Boolean?*/ traverse){
+ // summary:
+ // Returns the last child row below this path. If traverse
+ // is true, will traverse down to find the last child row
+ // of this branch. If there are no children, returns itself.
+ var children = this.children();
+ if(!children || !children.length){
+ return this;
+ }
+ var path = new dojox.grid.TreePath(this._str + "/" + String(children.length-1), this.grid);
+ if(!traverse){
+ return path;
+ }
+ return path.lastChild(true);
+ },
+ toString: function(){
+ return this._str;
+ }
+});
+
+dojo.declare("dojox.grid._TreeFocusManager", dojox.grid._FocusManager, {
+ setFocusCell: function(inCell, inRowIndex){
+ if(inCell && inCell.getNode(inRowIndex)){
+ this.inherited(arguments);
+ }
+ },
+ isLastFocusCell: function(){
+ if(this.cell && this.cell.index == this.grid.layout.cellCount-1){
+ var path = new dojox.grid.TreePath(this.grid.rowCount-1, this.grid);
+ path = path.lastChild(true);
+ return this.rowIndex == path._str;
+ }
+ return false;
+ },
+ next: function(){
+ // summary:
+ // focus next grid cell
+ if(this.cell){
+ var row=this.rowIndex, col=this.cell.index+1, cc=this.grid.layout.cellCount-1;
+ var path = new dojox.grid.TreePath(this.rowIndex, this.grid);
+ if(col > cc){
+ var new_path = path.next();
+ if(!new_path){
+ col--;
+ }else{
+ col = 0;
+ path = new_path;
+ }
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var nextCell = this.grid.getCell(col);
+ if (!this.isLastFocusCell() && !nextCell.editable){
+ this._focusifyCellNode(false);
+ this.cell=nextCell;
+ this.rowIndex=path._str;
+ this.next();
+ return;
+ }
+ }
+ this.setFocusIndex(path._str, col);
+ }
+ },
+ previous: function(){
+ // summary:
+ // focus previous grid cell
+ if(this.cell){
+ var row=(this.rowIndex || 0), col=(this.cell.index || 0) - 1;
+ var path = new dojox.grid.TreePath(row, this.grid);
+ if(col < 0){
+ var new_path = path.previous();
+ if(!new_path){
+ col = 0;
+ }else{
+ col = this.grid.layout.cellCount-1;
+ path = new_path;
+ }
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var prevCell = this.grid.getCell(col);
+ if (!this.isFirstFocusCell() && !prevCell.editable){
+ this._focusifyCellNode(false);
+ this.cell=prevCell;
+ this.rowIndex=path._str;
+ this.previous();
+ return;
+ }
+ }
+ this.setFocusIndex(path._str, col);
+ }
+ },
+ move: function(inRowDelta, inColDelta){
+ if(this.isNavHeader()){
+ this.inherited(arguments);
+ return;
+ }
+ if(!this.cell){ return; }
+ // Handle grid proper.
+ var sc = this.grid.scroller,
+ r = this.rowIndex,
+ rc = this.grid.rowCount-1,
+ path = new dojox.grid.TreePath(this.rowIndex, this.grid);
+ if(inRowDelta){
+ var row;
+ if(inRowDelta>0){
+ path = path.next();
+ row = path._arr[0];
+ if(row > sc.getLastPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r));
+ }
+ }else if(inRowDelta<0){
+ path = path.previous();
+ row = path._arr[0];
+ if(row <= sc.getPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row));
+ }
+ }
+ }
+ var cc = this.grid.layout.cellCount-1,
+ i = this.cell.index,
+ col = Math.min(cc, Math.max(0, i+inColDelta));
+ var cell = this.grid.getCell(col);
+ var colDir = inColDelta < 0 ? -1 : 1;
+ while(col>=0 && col < cc && cell && cell.hidden === true){
+ // skip hidden cells
+ col += colDir;
+ cell = this.grid.getCell(col);
+ }
+ if (!cell || cell.hidden === true){
+ // don't change col if would move to hidden
+ col = i;
+ }
+ if(inRowDelta){
+ this.grid.updateRow(r);
+ }
+ this.setFocusIndex(path._str, col);
+ }
+});
+
+dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
+ // summary:
+ // A grid that supports nesting rows - it provides an expando function
+ // similar to dijit.Tree. It also provides mechanisms for aggregating
+ // the values of subrows
+ //
+ // description:
+ // TreeGrid currently only works on "simple" structures. That is,
+ // single-view structures with a single row in them.
+ //
+ // The TreeGrid works using the concept of "levels" - level 0 are the
+ // top-level items.
+
+ // defaultOpen: Boolean
+ // Whether or not we default to open (all levels). This defaults to
+ // false for grids with a treeModel.
+ defaultOpen: true,
+
+ // sortChildItems: Boolean
+ // If true, child items will be returned sorted according to the sorting
+ // properties of the grid.
+ sortChildItems: false,
+
+ // openAtLevels: Array
+ // Which levels we are open at (overrides defaultOpen for the values
+ // that exist here). Its values can be a boolean (true/false) or an
+ // integer (for the # of children to be closed if there are more than
+ // that)
+ openAtLevels: [],
+
+ // treeModel: dijit.tree.ForestStoreModel
+ // A dijit.Tree model that will be used instead of using aggregates.
+ // Setting this value will make the TreeGrid behave like a columnar
+ // tree. When setting this value, defaultOpen will default to false,
+ // and openAtLevels will be ignored.
+ treeModel: null,
+
+ // expandoCell: Integer
+ // When used in conjunction with a treeModel (see above), this is a 0-based
+ // index of the cell in which to place the actual expando
+ expandoCell: 0,
+
+ // private values
+ // aggregator: Object
+ // The aggregator class - it will be populated automatically if we
+ // are a collapsable grid
+ aggregator: null,
+
+
+ // Override this to get our "magic" layout
+ _layoutClass: dojox.grid._TreeLayout,
+
+ createSelection: function(){
+ this.selection = new dojox.grid.TreeSelection(this);
+ },
+
+ _childItemSorter: function(a, b, attribute, descending){
+ var av = this.store.getValue(a, attribute);
+ var bv = this.store.getValue(b, attribute);
+ if(av != bv){
+ return av < bv == descending ? 1 : -1;
+ }
+ return 0;
+ },
+
+ _onNew: function(item, parentInfo){
+ if(!parentInfo || !parentInfo.item){
+ this.inherited(arguments);
+ }else{
+ var idx = this.getItemIndex(parentInfo.item);
+ if(typeof idx == "string"){
+ this.updateRow(idx.split('/')[0]);
+ }else if(idx > -1){
+ this.updateRow(idx);
+ }
+ }
+ },
+
+ _onSet: function(item, attribute, oldValue, newValue){
+ this._checkUpdateStatus();
+ if(this.aggregator){
+ this.aggregator.clearSubtotalCache();
+ }
+ var idx = this.getItemIndex(item);
+ if(typeof idx == "string"){
+ this.updateRow(idx.split('/')[0]);
+ }else if(idx > -1){
+ this.updateRow(idx);
+ }
+ },
+
+ _onDelete: function(item){
+ this._cleanupExpandoCache(this._getItemIndex(item, true), this.store.getIdentity(item), item);
+ this.inherited(arguments);
+ },
+
+ _cleanupExpandoCache: function(index, identity, item){},
+
+ _addItem: function(item, index, noUpdate, dontUpdateRoot){
+ // add our root items to the root of the model's children
+ // list since we don't query the model
+ if(!dontUpdateRoot && this.model && dojo.indexOf(this.model.root.children, item) == -1){
+ this.model.root.children[index] = item;
+ }
+ this.inherited(arguments);
+ },
+
+ getItem: function(/*integer|Array|String*/ idx){
+ // summary:
+ // overridden so that you can pass in a '/' delimited string of indexes to get the
+ // item based off its path...that is, passing in "1/3/2" will get the
+ // 3rd (0-based) child from the 4th child of the 2nd top-level item.
+ var isArray = dojo.isArray(idx);
+ if(dojo.isString(idx) && idx.indexOf('/')){
+ idx = idx.split('/');
+ isArray = true;
+ }
+ if(isArray && idx.length == 1){
+ idx = idx[0];
+ isArray = false;
+ }
+ if(!isArray){
+ return dojox.grid.DataGrid.prototype.getItem.call(this, idx);
+ }
+ var s = this.store;
+ var itm = dojox.grid.DataGrid.prototype.getItem.call(this, idx[0]);
+ var cf, i, j;
+ if(this.aggregator){
+ cf = this.aggregator.childFields||[];
+ if(cf){
+ for(i = 0; i < idx.length - 1 && itm; i++){
+ if(cf[i]){
+ itm = (s.getValues(itm, cf[i])||[])[idx[i + 1]];
+ }else{
+ itm = null;
+ }
+ }
+ }
+ }else if(this.treeModel){
+ cf = this.treeModel.childrenAttrs||[];
+ if(cf&&itm){
+ for(i=1, il=idx.length; (i<il) && itm; i++) {
+ for(j=0, jl=cf.length; j<jl; j++) {
+ if(cf[j]){
+ itm = (s.getValues(itm, cf[j])||[])[idx[i]];
+ }else{
+ itm = null;
+ }
+ if(itm){ break; }
+ }
+ }
+ }
+ }
+ return itm || null;
+ },
+
+ _getItemIndex: function(item, isDeleted){
+ if(!isDeleted && !this.store.isItem(item)){
+ return -1;
+ }
+ var idx = this.inherited(arguments);
+ if(idx == -1){
+ var idty = this.store.getIdentity(item);
+ return this._by_idty_paths[idty] || -1;
+ }
+ return idx;
+ },
+
+ postMixInProperties: function(){
+ if(this.treeModel && !("defaultOpen" in this.params)){
+ // Default open to false for tree models, true for other tree
+ // grids.
+ this.defaultOpen = false;
+ }
+ var def = this.defaultOpen;
+ this.openAtLevels = dojo.map(this.openAtLevels, function(l){
+ if(typeof l == "string"){
+ switch(l.toLowerCase()){
+ case "true":
+ return true;
+ break;
+ case "false":
+ return false;
+ break;
+ default:
+ var r = parseInt(l, 10);
+ if(isNaN(r)){
+ return def;
+ }
+ return r;
+ break;
+ }
+ }
+ return l;
+ });
+ this._by_idty_paths = {};
+ this.inherited(arguments);
+ },
+
+ postCreate: function(){
+ this.inherited(arguments);
+ if(this.treeModel){
+ this._setModel(this.treeModel);
+ }
+ },
+
+ setModel: function(treeModel){
+ this._setModel(treeModel);
+ this._refresh(true);
+ },
+
+ _setModel: function(treeModel){
+ if(treeModel && (!dijit.tree.ForestStoreModel || !(treeModel instanceof dijit.tree.ForestStoreModel))){
+ throw new Error("dojox.grid.TreeGrid: treeModel must be an instance of dijit.tree.ForestStoreModel");
+ }
+ this.treeModel = treeModel;
+ dojo.toggleClass(this.domNode, "dojoxGridTreeModel", this.treeModel ? true : false);
+ this._setQuery(treeModel ? treeModel.query : null);
+ this._setStore(treeModel ? treeModel.store : null);
+ },
+
+ createScroller: function(){
+ this.inherited(arguments);
+ this.scroller._origDefaultRowHeight = this.scroller.defaultRowHeight;
+ },
+
+ createManagers: function(){
+ // summary:
+ // create grid managers for various tasks including rows, focus, selection, editing
+
+ // row manager
+ this.rows = new dojox.grid._RowManager(this);
+ // focus manager
+ this.focus = new dojox.grid._TreeFocusManager(this);
+ // edit manager
+ this.edit = new dojox.grid._EditManager(this);
+ },
+
+ _setStore: function(store){
+ this.inherited(arguments);
+ if(this.treeModel&&!this.treeModel.root.children){
+ this.treeModel.root.children = [];
+ }
+ if(this.aggregator){
+ this.aggregator.store = store;
+ }
+ },
+
+ getDefaultOpenState: function(cellDef, item){
+ // summary:
+ // Returns the default open state for the given definition and item
+ // It reads from the openAtLevels and defaultOpen values of the
+ // grid to calculate if the given item should default to open or
+ // not.
+ var cf;
+ var store = this.store;
+ if(this.treeModel){ return this.defaultOpen; }
+ if(!cellDef || !store || !store.isItem(item) ||
+ !(cf = this.aggregator.childFields[cellDef.level])){
+ return this.defaultOpen;
+ }
+ if(this.openAtLevels.length > cellDef.level){
+ var dVal = this.openAtLevels[cellDef.level];
+ if(typeof dVal == "boolean"){
+ return dVal;
+ }else if(typeof dVal == "number"){
+ return (store.getValues(item, cf).length <= dVal);
+ }
+ }
+ return this.defaultOpen;
+ },
+ onStyleRow: function(row){
+ if(!this.layout._isCollapsable){
+ this.inherited(arguments);
+ return;
+ }
+ var base = dojo.attr(row.node, 'dojoxTreeGridBaseClasses');
+ if(base){
+ row.customClasses = base;
+ }
+ var i = row;
+ var tagName = i.node.tagName.toLowerCase();
+ i.customClasses += (i.odd?" dojoxGridRowOdd":"") +
+ (i.selected&&tagName=='tr'?" dojoxGridRowSelected":"") +
+ (i.over&&tagName=='tr'?" dojoxGridRowOver":"");
+ this.focus.styleRow(i);
+ this.edit.styleRow(i);
+ },
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ if(inRowNode.tagName.toLowerCase() == 'div' && this.aggregator){
+ dojo.query("tr[dojoxTreeGridPath]", inRowNode).forEach(function(rowNode){
+ this.rows.styleRowNode(dojo.attr(rowNode, 'dojoxTreeGridPath'), rowNode);
+ },this);
+ }
+ this.rows.styleRowNode(inRowIndex, inRowNode);
+ }
+ },
+ onCanSelect: function(inRowIndex){
+ var nodes = dojo.query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode);
+ if(nodes.length){
+ if(dojo.hasClass(nodes[0], 'dojoxGridSummaryRow')){
+ return false;
+ }
+ }
+ return this.inherited(arguments);
+ },
+ onKeyDown: function(e){
+ if(e.altKey || e.metaKey){
+ return;
+ }
+ var dk = dojo.keys;
+ switch(e.keyCode){
+ case dk.UP_ARROW:
+ if(!this.edit.isEditing() && this.focus.rowIndex != "0"){
+ dojo.stopEvent(e);
+ this.focus.move(-1, 0);
+ }
+ break;
+ case dk.DOWN_ARROW:
+ var currPath = new dojox.grid.TreePath(this.focus.rowIndex, this);
+ var lastPath = new dojox.grid.TreePath(this.rowCount-1, this);
+ lastPath = lastPath.lastChild(true);
+ if(!this.edit.isEditing() && currPath.toString() != lastPath.toString()){
+ dojo.stopEvent(e);
+ this.focus.move(1, 0);
+ }
+ break;
+ default:
+ this.inherited(arguments);
+ break;
+ }
+ },
+ canEdit: function(inCell, inRowIndex){
+ var node = inCell.getNode(inRowIndex);
+ return node && this._canEdit;
+ },
+ doApplyCellEdit: function(inValue, inRowIndex, inAttrName){
+ var item = this.getItem(inRowIndex);
+ var oldValue = this.store.getValue(item, inAttrName);
+ if(typeof oldValue == 'number'){
+ inValue = isNaN(inValue) ? inValue : parseFloat(inValue);
+ }else if(typeof oldValue == 'boolean'){
+ inValue = inValue == 'true' ? true : inValue == 'false' ? false : inValue;
+ }else if(oldValue instanceof Date){
+ var asDate = new Date(inValue);
+ inValue = isNaN(asDate.getTime()) ? inValue : asDate;
+ }
+ this.store.setValue(item, inAttrName, inValue);
+ this.onApplyCellEdit(inValue, inRowIndex, inAttrName);
+ }
+});
+dojox.grid.TreeGrid.markupFactory = function(props, node, ctor, cellFunc){
+ var d = dojo;
+ var widthFromAttr = function(n){
+ var w = d.attr(n, "width")||"auto";
+ if((w != "auto")&&(w.slice(-2) != "em")&&(w.slice(-1) != "%")){
+ w = parseInt(w, 10)+"px";
+ }
+ return w;
+ };
+
+ var cellsFromMarkup = function(table){
+ var rows;
+ // Don't support colgroup on our grid - single view, single row only
+ if(table.nodeName.toLowerCase() == "table" &&
+ d.query("> colgroup", table).length === 0 &&
+ (rows = d.query("> thead > tr", table)).length == 1){
+ var tr = rows[0];
+ return d.query("> th", rows[0]).map(function(th){
+ // Grab type and field (the only ones that are shared
+ var cell = {
+ type: d.trim(d.attr(th, "cellType")||""),
+ field: d.trim(d.attr(th, "field")||"")
+ };
+ if(cell.type){
+ cell.type = d.getObject(cell.type);
+ }
+
+ var subTable = d.query("> table", th)[0];
+ if(subTable){
+ // If we have a subtable, we are an aggregate and a summary cell
+ cell.name = "";
+ cell.children = cellsFromMarkup(subTable);
+ if(d.hasAttr(th, "itemAggregates")){
+ cell.itemAggregates = d.map(d.attr(th, "itemAggregates").split(","), function(v){
+ return d.trim(v);
+ });
+ }else{
+ cell.itemAggregates = [];
+ }
+ if(d.hasAttr(th, "aggregate")){
+ cell.aggregate = d.attr(th, "aggregate");
+ }
+ cell.type = cell.type || dojox.grid.cells.SubtableCell;
+ }else{
+ // Grab our other stuff we need (mostly what's in the normal
+ // Grid)
+ cell.name = d.trim(d.attr(th, "name")||th.innerHTML);
+ if(d.hasAttr(th, "width")){
+ cell.width = widthFromAttr(th);
+ }
+ if(d.hasAttr(th, "relWidth")){
+ cell.relWidth = window.parseInt(d.attr(th, "relWidth"), 10);
+ }
+ if(d.hasAttr(th, "hidden")){
+ cell.hidden = d.attr(th, "hidden") == "true";
+ }
+ cell.field = cell.field||cell.name;
+ dojox.grid.DataGrid.cell_markupFactory(cellFunc, th, cell);
+ cell.type = cell.type || dojox.grid.cells.Cell;
+ }
+ if(cell.type && cell.type.markupFactory){
+ cell.type.markupFactory(th, cell);
+ }
+ return cell;
+ });
+ }
+ return [];
+ };
+
+ var rows;
+ if( !props.structure ){
+ var row = cellsFromMarkup(node);
+ if(row.length){
+ // Set our structure here - so that we don't try and set it in the
+ // markup factory
+ props.structure = [{__span: Infinity, cells:[row]}];
+ }
+ }
+ return dojox.grid.DataGrid.markupFactory(props, node, ctor, cellFunc);
+};
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/TreeSelection.js b/js/dojo-1.6/dojox/grid/TreeSelection.js
new file mode 100644
index 0000000..79592e9
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/TreeSelection.js
@@ -0,0 +1,219 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.TreeSelection"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.TreeSelection"] = true;
+dojo.provide("dojox.grid.TreeSelection");
+
+dojo.require("dojox.grid.DataSelection");
+
+dojo.declare("dojox.grid.TreeSelection", dojox.grid.DataSelection, {
+ setMode: function(mode){
+ this.selected = {};
+ this.sorted_sel = [];
+ this.sorted_ltos = {};
+ this.sorted_stol = {};
+ dojox.grid.DataSelection.prototype.setMode.call(this, mode);
+ },
+ addToSelection: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ if(this.selected[idx]){
+ this.selectedIndex = idx;
+ }else{
+ if(this.onCanSelect(idx) !== false){
+ this.selectedIndex = idx;
+ var rowNodes = dojo.query("tr[dojoxTreeGridPath='" + idx + "']", this.grid.domNode);
+ if(rowNodes.length){
+ dojo.attr(rowNodes[0],"aria-selected","true");
+ }
+ this._beginUpdate();
+ this.selected[idx] = true;
+ this._insertSortedSelection(idx);
+ //this.grid.onSelected(idx);
+ this.onSelected(idx);
+ //this.onSetSelected(idx, true);
+ this._endUpdate();
+ }
+ }
+ },
+ deselect: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ if(this.selectedIndex == idx){
+ this.selectedIndex = -1;
+ }
+ if(this.selected[idx]){
+ if(this.onCanDeselect(idx) === false){
+ return;
+ }
+ var rowNodes = dojo.query("tr[dojoxTreeGridPath='" + idx + "']", this.grid.domNode);
+ if(rowNodes.length){
+ dojo.attr(rowNodes[0],"aria-selected","false");
+ }
+ this._beginUpdate();
+ delete this.selected[idx];
+ this._removeSortedSelection(idx);
+ //this.grid.onDeselected(idx);
+ this.onDeselected(idx);
+ //this.onSetSelected(idx, false);
+ this._endUpdate();
+ }
+ },
+ getSelected: function(){
+ var result = [];
+ for(var i in this.selected){
+ if(this.selected[i]){
+ result.push(this.grid.getItem(i));
+ }
+ }
+ return result;
+ },
+ getSelectedCount: function(){
+ var c = 0;
+ for(var i in this.selected){
+ if(this.selected[i]){
+ c++;
+ }
+ }
+ return c;
+ },
+ _bsearch: function(v){
+ var o = this.sorted_sel;
+ var h = o.length - 1, l = 0, m;
+ while(l<=h){
+ var cmp = this._comparePaths(o[m = (l + h) >> 1], v);
+ if(cmp < 0){ l = m + 1; continue; }
+ if(cmp > 0){ h = m - 1; continue; }
+ return m;
+ }
+ return cmp < 0 ? m - cmp : m;
+ },
+ _comparePaths: function(a, b){
+ for(var i=0, l=(a.length < b.length ? a.length : b.length); i<l; i++){
+ if(a[i]<b[i]){ return -1; }
+ if(a[i]>b[i]){ return 1; }
+ }
+ if(a.length<b.length){ return -1; }
+ if(a.length>b.length){ return 1; }
+ return 0;
+ },
+ _insertSortedSelection: function(index){
+ index = String(index);
+ var s = this.sorted_sel;
+ var sl = this.sorted_ltos;
+ var ss = this.sorted_stol;
+
+ var lpath = index.split('/');
+ lpath = dojo.map(lpath, function(item){ return parseInt(item, 10); });
+ sl[lpath] = index;
+ ss[index] = lpath;
+
+ if(s.length === 0){
+ s.push(lpath);
+ return;
+ }
+ if(s.length==1){
+ var cmp = this._comparePaths(s[0], lpath);
+ if(cmp==1){ s.unshift(lpath); }
+ else{ s.push(lpath); }
+ return;
+ }
+
+ var idx = this._bsearch(lpath);
+ this.sorted_sel.splice(idx, 0, lpath);
+ },
+ _removeSortedSelection: function(index){
+ index = String(index);
+ var s = this.sorted_sel;
+ var sl = this.sorted_ltos;
+ var ss = this.sorted_stol;
+
+ if(s.length === 0){
+ return;
+ }
+
+ var lpath = ss[index];
+ if(!lpath){ return; }
+
+ var idx = this._bsearch(lpath);
+ if(idx > -1){
+ delete sl[lpath];
+ delete ss[index];
+ s.splice(idx, 1);
+ }
+ },
+ getFirstSelected: function(){
+ if(!this.sorted_sel.length||this.mode == 'none'){ return -1; }
+ var fpath = this.sorted_sel[0];
+ if(!fpath){
+ return -1;
+ }
+ fpath = this.sorted_ltos[fpath];
+ if(!fpath){
+ return -1;
+ }
+ return fpath;
+ },
+ getNextSelected: function(inPrev){
+ if(!this.sorted_sel.length||this.mode == 'none'){ return -1; }
+ inPrev = String(inPrev);
+ var prevPath = this.sorted_stol[inPrev];
+ if(!prevPath){ return -1; }
+
+ var idx = this._bsearch(prevPath);
+ var lpath = this.sorted_sel[idx+1];
+ if(!lpath){
+ return -1;
+ }
+ return this.sorted_ltos[lpath];
+ },
+ _range: function(inFrom, inTo, func){
+ if(!dojo.isString(inFrom) && inFrom < 0){
+ inFrom = inTo;
+ }
+ var cells = this.grid.layout.cells,
+ store = this.grid.store,
+ grid = this.grid;
+ inFrom = new dojox.grid.TreePath(String(inFrom), grid);
+ inTo = new dojox.grid.TreePath(String(inTo), grid);
+
+ if(inFrom.compare(inTo) > 0){
+ var tmp = inFrom;
+ inFrom = inTo;
+ inTo = tmp;
+ }
+
+ var inFromStr = inFrom._str, inToStr = inTo._str;
+
+ // select/deselect the first
+ func(inFromStr);
+
+ var p = inFrom;
+ while((p = p.next())){
+ if(p._str == inToStr){
+ break;
+ }
+ func(p._str);
+ }
+
+ // select/deselect the last
+ func(inToStr);
+ }
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/TreeSelection.xd.js b/js/dojo-1.6/dojox/grid/TreeSelection.xd.js
new file mode 100644
index 0000000..e01531a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/TreeSelection.xd.js
@@ -0,0 +1,224 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.TreeSelection"],
+["require", "dojox.grid.DataSelection"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.TreeSelection"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.TreeSelection"] = true;
+dojo.provide("dojox.grid.TreeSelection");
+
+dojo.require("dojox.grid.DataSelection");
+
+dojo.declare("dojox.grid.TreeSelection", dojox.grid.DataSelection, {
+ setMode: function(mode){
+ this.selected = {};
+ this.sorted_sel = [];
+ this.sorted_ltos = {};
+ this.sorted_stol = {};
+ dojox.grid.DataSelection.prototype.setMode.call(this, mode);
+ },
+ addToSelection: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ if(this.selected[idx]){
+ this.selectedIndex = idx;
+ }else{
+ if(this.onCanSelect(idx) !== false){
+ this.selectedIndex = idx;
+ var rowNodes = dojo.query("tr[dojoxTreeGridPath='" + idx + "']", this.grid.domNode);
+ if(rowNodes.length){
+ dojo.attr(rowNodes[0],"aria-selected","true");
+ }
+ this._beginUpdate();
+ this.selected[idx] = true;
+ this._insertSortedSelection(idx);
+ //this.grid.onSelected(idx);
+ this.onSelected(idx);
+ //this.onSetSelected(idx, true);
+ this._endUpdate();
+ }
+ }
+ },
+ deselect: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ if(this.selectedIndex == idx){
+ this.selectedIndex = -1;
+ }
+ if(this.selected[idx]){
+ if(this.onCanDeselect(idx) === false){
+ return;
+ }
+ var rowNodes = dojo.query("tr[dojoxTreeGridPath='" + idx + "']", this.grid.domNode);
+ if(rowNodes.length){
+ dojo.attr(rowNodes[0],"aria-selected","false");
+ }
+ this._beginUpdate();
+ delete this.selected[idx];
+ this._removeSortedSelection(idx);
+ //this.grid.onDeselected(idx);
+ this.onDeselected(idx);
+ //this.onSetSelected(idx, false);
+ this._endUpdate();
+ }
+ },
+ getSelected: function(){
+ var result = [];
+ for(var i in this.selected){
+ if(this.selected[i]){
+ result.push(this.grid.getItem(i));
+ }
+ }
+ return result;
+ },
+ getSelectedCount: function(){
+ var c = 0;
+ for(var i in this.selected){
+ if(this.selected[i]){
+ c++;
+ }
+ }
+ return c;
+ },
+ _bsearch: function(v){
+ var o = this.sorted_sel;
+ var h = o.length - 1, l = 0, m;
+ while(l<=h){
+ var cmp = this._comparePaths(o[m = (l + h) >> 1], v);
+ if(cmp < 0){ l = m + 1; continue; }
+ if(cmp > 0){ h = m - 1; continue; }
+ return m;
+ }
+ return cmp < 0 ? m - cmp : m;
+ },
+ _comparePaths: function(a, b){
+ for(var i=0, l=(a.length < b.length ? a.length : b.length); i<l; i++){
+ if(a[i]<b[i]){ return -1; }
+ if(a[i]>b[i]){ return 1; }
+ }
+ if(a.length<b.length){ return -1; }
+ if(a.length>b.length){ return 1; }
+ return 0;
+ },
+ _insertSortedSelection: function(index){
+ index = String(index);
+ var s = this.sorted_sel;
+ var sl = this.sorted_ltos;
+ var ss = this.sorted_stol;
+
+ var lpath = index.split('/');
+ lpath = dojo.map(lpath, function(item){ return parseInt(item, 10); });
+ sl[lpath] = index;
+ ss[index] = lpath;
+
+ if(s.length === 0){
+ s.push(lpath);
+ return;
+ }
+ if(s.length==1){
+ var cmp = this._comparePaths(s[0], lpath);
+ if(cmp==1){ s.unshift(lpath); }
+ else{ s.push(lpath); }
+ return;
+ }
+
+ var idx = this._bsearch(lpath);
+ this.sorted_sel.splice(idx, 0, lpath);
+ },
+ _removeSortedSelection: function(index){
+ index = String(index);
+ var s = this.sorted_sel;
+ var sl = this.sorted_ltos;
+ var ss = this.sorted_stol;
+
+ if(s.length === 0){
+ return;
+ }
+
+ var lpath = ss[index];
+ if(!lpath){ return; }
+
+ var idx = this._bsearch(lpath);
+ if(idx > -1){
+ delete sl[lpath];
+ delete ss[index];
+ s.splice(idx, 1);
+ }
+ },
+ getFirstSelected: function(){
+ if(!this.sorted_sel.length||this.mode == 'none'){ return -1; }
+ var fpath = this.sorted_sel[0];
+ if(!fpath){
+ return -1;
+ }
+ fpath = this.sorted_ltos[fpath];
+ if(!fpath){
+ return -1;
+ }
+ return fpath;
+ },
+ getNextSelected: function(inPrev){
+ if(!this.sorted_sel.length||this.mode == 'none'){ return -1; }
+ inPrev = String(inPrev);
+ var prevPath = this.sorted_stol[inPrev];
+ if(!prevPath){ return -1; }
+
+ var idx = this._bsearch(prevPath);
+ var lpath = this.sorted_sel[idx+1];
+ if(!lpath){
+ return -1;
+ }
+ return this.sorted_ltos[lpath];
+ },
+ _range: function(inFrom, inTo, func){
+ if(!dojo.isString(inFrom) && inFrom < 0){
+ inFrom = inTo;
+ }
+ var cells = this.grid.layout.cells,
+ store = this.grid.store,
+ grid = this.grid;
+ inFrom = new dojox.grid.TreePath(String(inFrom), grid);
+ inTo = new dojox.grid.TreePath(String(inTo), grid);
+
+ if(inFrom.compare(inTo) > 0){
+ var tmp = inFrom;
+ inFrom = inTo;
+ inTo = tmp;
+ }
+
+ var inFromStr = inFrom._str, inToStr = inTo._str;
+
+ // select/deselect the first
+ func(inFromStr);
+
+ var p = inFrom;
+ while((p = p.next())){
+ if(p._str == inToStr){
+ break;
+ }
+ func(p._str);
+ }
+
+ // select/deselect the last
+ func(inToStr);
+ }
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/_Builder.js b/js/dojo-1.6/dojox/grid/_Builder.js
new file mode 100644
index 0000000..2a24db6
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_Builder.js
@@ -0,0 +1,753 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid._Builder"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Builder"] = true;
+dojo.provide("dojox.grid._Builder");
+
+dojo.require("dojox.grid.util");
+dojo.require("dojo.dnd.Moveable");
+
+(function(){
+ var dg = dojox.grid;
+
+ var getTdIndex = function(td){
+ return td.cellIndex >=0 ? td.cellIndex : dojo.indexOf(td.parentNode.cells, td);
+ };
+
+ var getTrIndex = function(tr){
+ return tr.rowIndex >=0 ? tr.rowIndex : dojo.indexOf(tr.parentNode.childNodes, tr);
+ };
+
+ var getTr = function(rowOwner, index){
+ return rowOwner && ((rowOwner.rows||0)[index] || rowOwner.childNodes[index]);
+ };
+
+ var findTable = function(node){
+ for(var n=node; n && n.tagName!='TABLE'; n=n.parentNode){}
+ return n;
+ };
+
+ var ascendDom = function(inNode, inWhile){
+ for(var n=inNode; n && inWhile(n); n=n.parentNode){}
+ return n;
+ };
+
+ var makeNotTagName = function(inTagName){
+ var name = inTagName.toUpperCase();
+ return function(node){ return node.tagName != name; };
+ };
+
+ var rowIndexTag = dojox.grid.util.rowIndexTag;
+ var gridViewTag = dojox.grid.util.gridViewTag;
+
+ // base class for generating markup for the views
+ dg._Builder = dojo.extend(function(view){
+ if(view){
+ this.view = view;
+ this.grid = view.grid;
+ }
+ },{
+ view: null,
+ // boilerplate HTML
+ _table: '<table class="dojoxGridRowTable" border="0" cellspacing="0" cellpadding="0" role="presentation"',
+
+ // Returns the table variable as an array - and with the view width, if specified
+ getTableArray: function(){
+ var html = [this._table];
+ if(this.view.viewWidth){
+ html.push([' style="width:', this.view.viewWidth, ';"'].join(''));
+ }
+ html.push('>');
+ return html;
+ },
+
+ // generate starting tags for a cell
+ generateCellMarkup: function(inCell, inMoreStyles, inMoreClasses, isHeader){
+ var result = [], html;
+ if(isHeader){
+ var sortInfo = inCell.index != inCell.grid.getSortIndex() ? "" : inCell.grid.sortInfo > 0 ? 'aria-sort="ascending"' : 'aria-sort="descending"';
+ if (!inCell.id){
+ inCell.id = this.grid.id + "Hdr" + inCell.index;
+ }
+ // column headers are not editable, mark as aria-readonly=true
+ html = ['<th tabIndex="-1" aria-readonly="true" role="columnheader"', sortInfo, 'id="', inCell.id, '"'];
+ }else{
+ // cells inherit grid aria-readonly property; default value for aria-readonly is false(grid is editable)
+ // if grid is editable (had any editable cells), mark non editable cells as aria-readonly=true
+ // if no editable cells, grid's aria-readonly value will have been set to true and cells will inherit
+ var editInfo = this.grid.editable && !inCell.editable ? 'aria-readonly="true"' : "";
+ html = ['<td tabIndex="-1" role="gridcell"', editInfo];
+ }
+ if(inCell.colSpan){
+ html.push(' colspan="', inCell.colSpan, '"');
+ }
+ if(inCell.rowSpan){
+ html.push(' rowspan="', inCell.rowSpan, '"');
+ }
+ html.push(' class="dojoxGridCell ');
+ if(inCell.classes){
+ html.push(inCell.classes, ' ');
+ }
+ if(inMoreClasses){
+ html.push(inMoreClasses, ' ');
+ }
+ // result[0] => td opener, style
+ result.push(html.join(''));
+ // SLOT: result[1] => td classes
+ result.push('');
+ html = ['" idx="', inCell.index, '" style="'];
+ if(inMoreStyles && inMoreStyles[inMoreStyles.length-1] != ';'){
+ inMoreStyles += ';';
+ }
+ html.push(inCell.styles, inMoreStyles||'', inCell.hidden?'display:none;':'');
+ if(inCell.unitWidth){
+ html.push('width:', inCell.unitWidth, ';');
+ }
+ // result[2] => markup
+ result.push(html.join(''));
+ // SLOT: result[3] => td style
+ result.push('');
+ html = [ '"' ];
+ if(inCell.attrs){
+ html.push(" ", inCell.attrs);
+ }
+ html.push('>');
+ // result[4] => td postfix
+ result.push(html.join(''));
+ // SLOT: result[5] => content
+ result.push('');
+ // result[6] => td closes
+ result.push(isHeader?'</th>':'</td>');
+ return result; // Array
+ },
+
+ // cell finding
+ isCellNode: function(inNode){
+ return Boolean(inNode && inNode!=dojo.doc && dojo.attr(inNode, "idx"));
+ },
+
+ getCellNodeIndex: function(inCellNode){
+ return inCellNode ? Number(dojo.attr(inCellNode, "idx")) : -1;
+ },
+
+ getCellNode: function(inRowNode, inCellIndex){
+ for(var i=0, row; (row=getTr(inRowNode.firstChild, i)); i++){
+ for(var j=0, cell; (cell=row.cells[j]); j++){
+ if(this.getCellNodeIndex(cell) == inCellIndex){
+ return cell;
+ }
+ }
+ }
+ return null;
+ },
+
+ findCellTarget: function(inSourceNode, inTopNode){
+ var n = inSourceNode;
+ while(n && (!this.isCellNode(n) || (n.offsetParent && gridViewTag in n.offsetParent.parentNode && n.offsetParent.parentNode[gridViewTag] != this.view.id)) && (n!=inTopNode)){
+ n = n.parentNode;
+ }
+ return n!=inTopNode ? n : null;
+ },
+
+ // event decoration
+ baseDecorateEvent: function(e){
+ e.dispatch = 'do' + e.type;
+ e.grid = this.grid;
+ e.sourceView = this.view;
+ e.cellNode = this.findCellTarget(e.target, e.rowNode);
+ e.cellIndex = this.getCellNodeIndex(e.cellNode);
+ e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null);
+ },
+
+ // event dispatch
+ findTarget: function(inSource, inTag){
+ var n = inSource;
+ while(n && (n!=this.domNode) && (!(inTag in n) || (gridViewTag in n && n[gridViewTag] != this.view.id))){
+ n = n.parentNode;
+ }
+ return (n != this.domNode) ? n : null;
+ },
+
+ findRowTarget: function(inSource){
+ return this.findTarget(inSource, rowIndexTag);
+ },
+
+ isIntraNodeEvent: function(e){
+ try{
+ return (e.cellNode && e.relatedTarget && dojo.isDescendant(e.relatedTarget, e.cellNode));
+ }catch(x){
+ // e.relatedTarget has permission problem in FF if it's an input: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+ return false;
+ }
+ },
+
+ isIntraRowEvent: function(e){
+ try{
+ var row = e.relatedTarget && this.findRowTarget(e.relatedTarget);
+ return !row && (e.rowIndex==-1) || row && (e.rowIndex==row.gridRowIndex);
+ }catch(x){
+ // e.relatedTarget on INPUT has permission problem in FF: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+ return false;
+ }
+ },
+
+ dispatchEvent: function(e){
+ if(e.dispatch in this){
+ return this[e.dispatch](e);
+ }
+ return false;
+ },
+
+ // dispatched event handlers
+ domouseover: function(e){
+ if(e.cellNode && (e.cellNode!=this.lastOverCellNode)){
+ this.lastOverCellNode = e.cellNode;
+ this.grid.onMouseOver(e);
+ }
+ this.grid.onMouseOverRow(e);
+ },
+
+ domouseout: function(e){
+ if(e.cellNode && (e.cellNode==this.lastOverCellNode) && !this.isIntraNodeEvent(e, this.lastOverCellNode)){
+ this.lastOverCellNode = null;
+ this.grid.onMouseOut(e);
+ if(!this.isIntraRowEvent(e)){
+ this.grid.onMouseOutRow(e);
+ }
+ }
+ },
+
+ domousedown: function(e){
+ if (e.cellNode)
+ this.grid.onMouseDown(e);
+ this.grid.onMouseDownRow(e);
+ }
+ });
+
+ // Produces html for grid data content. Owned by grid and used internally
+ // for rendering data. Override to implement custom rendering.
+ dg._ContentBuilder = dojo.extend(function(view){
+ dg._Builder.call(this, view);
+ },dg._Builder.prototype,{
+ update: function(){
+ this.prepareHtml();
+ },
+
+ // cache html for rendering data rows
+ prepareHtml: function(){
+ var defaultGet=this.grid.get, cells=this.view.structure.cells;
+ for(var j=0, row; (row=cells[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ cell.get = cell.get || (cell.value == undefined) && defaultGet;
+ cell.markup = this.generateCellMarkup(cell, cell.cellStyles, cell.cellClasses, false);
+ if (!this.grid.editable && cell.editable){
+ this.grid.editable = true;
+ }
+ }
+ }
+ },
+
+ // time critical: generate html using cache and data source
+ generateHtml: function(inDataIndex, inRowIndex){
+ var
+ html = this.getTableArray(),
+ v = this.view,
+ cells = v.structure.cells,
+ item = this.grid.getItem(inRowIndex);
+
+ dojox.grid.util.fire(this.view, "onBeforeRow", [inRowIndex, cells]);
+ for(var j=0, row; (row=cells[j]); j++){
+ if(row.hidden || row.header){
+ continue;
+ }
+ html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
+ for(var i=0, cell, m, cc, cs; (cell=row[i]); i++){
+ m = cell.markup; cc = cell.customClasses = []; cs = cell.customStyles = [];
+ // content (format can fill in cc and cs as side-effects)
+ m[5] = cell.format(inRowIndex, item);
+ // classes
+ m[1] = cc.join(' ');
+ // styles
+ m[3] = cs.join(';');
+ // in-place concat
+ html.push.apply(html, m);
+ }
+ html.push('</tr>');
+ }
+ html.push('</table>');
+ return html.join(''); // String
+ },
+
+ decorateEvent: function(e){
+ e.rowNode = this.findRowTarget(e.target);
+ if(!e.rowNode){return false;}
+ e.rowIndex = e.rowNode[rowIndexTag];
+ this.baseDecorateEvent(e);
+ e.cell = this.grid.getCell(e.cellIndex);
+ return true; // Boolean
+ }
+ });
+
+ // Produces html for grid header content. Owned by grid and used internally
+ // for rendering data. Override to implement custom rendering.
+ dg._HeaderBuilder = dojo.extend(function(view){
+ this.moveable = null;
+ dg._Builder.call(this, view);
+ },dg._Builder.prototype,{
+ _skipBogusClicks: false,
+ overResizeWidth: 4,
+ minColWidth: 1,
+
+ update: function(){
+ if(this.tableMap){
+ this.tableMap.mapRows(this.view.structure.cells);
+ }else{
+ this.tableMap = new dg._TableMap(this.view.structure.cells);
+ }
+ },
+
+ generateHtml: function(inGetValue, inValue){
+ var html = this.getTableArray(), cells = this.view.structure.cells;
+
+ dojox.grid.util.fire(this.view, "onBeforeRow", [-1, cells]);
+ for(var j=0, row; (row=cells[j]); j++){
+ if(row.hidden){
+ continue;
+ }
+ html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
+ for(var i=0, cell, markup; (cell=row[i]); i++){
+ cell.customClasses = [];
+ cell.customStyles = [];
+ if(this.view.simpleStructure){
+ if(cell.draggable){
+ if(cell.headerClasses){
+ if(cell.headerClasses.indexOf('dojoDndItem') == -1){
+ cell.headerClasses += ' dojoDndItem';
+ }
+ }else{
+ cell.headerClasses = 'dojoDndItem';
+ }
+ }
+ if(cell.attrs){
+ if(cell.attrs.indexOf("dndType='gridColumn_") == -1){
+ cell.attrs += " dndType='gridColumn_" + this.grid.id + "'";
+ }
+ }else{
+ cell.attrs = "dndType='gridColumn_" + this.grid.id + "'";
+ }
+ }
+ markup = this.generateCellMarkup(cell, cell.headerStyles, cell.headerClasses, true);
+ // content
+ markup[5] = (inValue != undefined ? inValue : inGetValue(cell));
+ // styles
+ markup[3] = cell.customStyles.join(';');
+ // classes
+ markup[1] = cell.customClasses.join(' '); //(cell.customClasses ? ' ' + cell.customClasses : '');
+ html.push(markup.join(''));
+ }
+ html.push('</tr>');
+ }
+ html.push('</table>');
+ return html.join('');
+ },
+
+ // event helpers
+ getCellX: function(e){
+ var n, x = e.layerX;
+ if(dojo.isMoz){
+ n = ascendDom(e.target, makeNotTagName("th"));
+ x -= (n && n.offsetLeft) || 0;
+ var t = e.sourceView.getScrollbarWidth();
+ if(!dojo._isBodyLtr()/*&& e.sourceView.headerNode.scrollLeft < t*/){
+ //fix #11253
+ table = ascendDom(n,makeNotTagName("table"));
+ x -= (table && table.offsetLeft) || 0;
+ }
+ //x -= getProp(ascendDom(e.target, mkNotTagName("td")), "offsetLeft") || 0;
+ }
+ n = ascendDom(e.target, function(){
+ if(!n || n == e.cellNode){
+ return false;
+ }
+ // Mozilla 1.8 (FF 1.5) has a bug that makes offsetLeft = -parent border width
+ // when parent has border, overflow: hidden, and is positioned
+ // handle this problem here ... not a general solution!
+ x += (n.offsetLeft < 0 ? 0 : n.offsetLeft);
+ return true;
+ });
+ return x;
+ },
+
+ // event decoration
+ decorateEvent: function(e){
+ this.baseDecorateEvent(e);
+ e.rowIndex = -1;
+ e.cellX = this.getCellX(e);
+ return true;
+ },
+
+ // event handlers
+ // resizing
+ prepareResize: function(e, mod){
+ do{
+ var i = getTdIndex(e.cellNode);
+ e.cellNode = (i ? e.cellNode.parentNode.cells[i+mod] : null);
+ e.cellIndex = (e.cellNode ? this.getCellNodeIndex(e.cellNode) : -1);
+ }while(e.cellNode && e.cellNode.style.display == "none");
+ return Boolean(e.cellNode);
+ },
+
+ canResize: function(e){
+ if(!e.cellNode || e.cellNode.colSpan > 1){
+ return false;
+ }
+ var cell = this.grid.getCell(e.cellIndex);
+ return !cell.noresize && cell.canResize();
+ },
+
+ overLeftResizeArea: function(e){
+ // We are never over a resize area if we are in the process of moving
+ if(dojo.hasClass(dojo.body(), "dojoDndMove")){
+ return false;
+ }
+ //Bugfix for crazy IE problem (#8807). IE returns position information for the icon and text arrow divs
+ //as if they were still on the left instead of returning the position they were 'float: right' to.
+ //So, the resize check ends up checking the wrong adjacent cell. This checks to see if the hover was over
+ //the image or text nodes, then just ignored them/treat them not in scale range.
+ if(dojo.isIE){
+ var tN = e.target;
+ if(dojo.hasClass(tN, "dojoxGridArrowButtonNode") ||
+ dojo.hasClass(tN, "dojoxGridArrowButtonChar")){
+ return false;
+ }
+ }
+
+ if(dojo._isBodyLtr()){
+ return (e.cellIndex>0) && (e.cellX > 0 && e.cellX < this.overResizeWidth) && this.prepareResize(e, -1);
+ }
+ var t = e.cellNode && (e.cellX > 0 && e.cellX < this.overResizeWidth);
+ return t;
+ },
+
+ overRightResizeArea: function(e){
+ // We are never over a resize area if we are in the process of moving
+ if(dojo.hasClass(dojo.body(), "dojoDndMove")){
+ return false;
+ }
+ //Bugfix for crazy IE problem (#8807). IE returns position information for the icon and text arrow divs
+ //as if they were still on the left instead of returning the position they were 'float: right' to.
+ //So, the resize check ends up checking the wrong adjacent cell. This checks to see if the hover was over
+ //the image or text nodes, then just ignored them/treat them not in scale range.
+ if(dojo.isIE){
+ var tN = e.target;
+ if(dojo.hasClass(tN, "dojoxGridArrowButtonNode") ||
+ dojo.hasClass(tN, "dojoxGridArrowButtonChar")){
+ return false;
+ }
+ }
+
+ if(dojo._isBodyLtr()){
+ return e.cellNode && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth);
+ }
+ return (e.cellIndex>0) && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth) && this.prepareResize(e, -1);
+ },
+
+ domousemove: function(e){
+ //console.log(e.cellIndex, e.cellX, e.cellNode.offsetWidth);
+ if(!this.moveable){
+ var c = (this.overRightResizeArea(e) ? 'dojoxGridColResize' : (this.overLeftResizeArea(e) ? 'dojoxGridColResize' : ''));
+ if(c && !this.canResize(e)){
+ c = 'dojoxGridColNoResize';
+ }
+ dojo.toggleClass(e.sourceView.headerNode, "dojoxGridColNoResize", (c == "dojoxGridColNoResize"));
+ dojo.toggleClass(e.sourceView.headerNode, "dojoxGridColResize", (c == "dojoxGridColResize"));
+ if(dojo.isIE){
+ var t = e.sourceView.headerNode.scrollLeft;
+ e.sourceView.headerNode.scrollLeft = t;
+ }
+ if(c){
+ dojo.stopEvent(e);
+ }
+ }
+ },
+
+ domousedown: function(e){
+ if(!this.moveable){
+ if((this.overRightResizeArea(e) || this.overLeftResizeArea(e)) && this.canResize(e)){
+ this.beginColumnResize(e);
+ }else{
+ this.grid.onMouseDown(e);
+ this.grid.onMouseOverRow(e);
+ }
+ //else{
+ // this.beginMoveColumn(e);
+ //}
+ }
+ },
+
+ doclick: function(e) {
+ if(this._skipBogusClicks){
+ dojo.stopEvent(e);
+ return true;
+ }
+ return false;
+ },
+
+ // column resizing
+ colResizeSetup: function(/*Event Object*/e, /*boolean*/ isMouse ){
+ //Set up the drag object for column resizing
+ // Called with mouse event in case of drag and drop,
+ // Also called from keyboard shift-arrow event when focus is on a header
+ var headContentBox = dojo.contentBox(e.sourceView.headerNode);
+
+ if(isMouse){ //IE draws line even with no mouse down so separate from keyboard
+ this.lineDiv = document.createElement('div');
+
+ // NOTE: this is for backwards compatibility with Dojo 1.3
+ var vw = (dojo.position||dojo._abs)(e.sourceView.headerNode, true);
+ var bodyContentBox = dojo.contentBox(e.sourceView.domNode);
+ //fix #11340
+ var l = e.pageX;
+ if(!dojo._isBodyLtr() && dojo.isIE < 8){
+ l -= dojox.html.metrics.getScrollbar().w;
+ }
+ dojo.style(this.lineDiv, {
+ top: vw.y + "px",
+ left: l + "px",
+ height: (bodyContentBox.h + headContentBox.h) + "px"
+ });
+ dojo.addClass(this.lineDiv, "dojoxGridResizeColLine");
+ this.lineDiv._origLeft = l;
+ dojo.body().appendChild(this.lineDiv);
+ }
+ var spanners = [], nodes = this.tableMap.findOverlappingNodes(e.cellNode);
+ for(var i=0, cell; (cell=nodes[i]); i++){
+ spanners.push({ node: cell, index: this.getCellNodeIndex(cell), width: cell.offsetWidth });
+ //console.log("spanner: " + this.getCellNodeIndex(cell));
+ }
+
+ var view = e.sourceView;
+ var adj = dojo._isBodyLtr() ? 1 : -1;
+ var views = e.grid.views.views;
+ var followers = [];
+ for(var j=view.idx+adj, cView; (cView=views[j]); j=j+adj){
+ followers.push({ node: cView.headerNode, left: window.parseInt(cView.headerNode.style.left) });
+ }
+ var table = view.headerContentNode.firstChild;
+ var drag = {
+ scrollLeft: e.sourceView.headerNode.scrollLeft,
+ view: view,
+ node: e.cellNode,
+ index: e.cellIndex,
+ w: dojo.contentBox(e.cellNode).w,
+ vw: headContentBox.w,
+ table: table,
+ tw: dojo.contentBox(table).w,
+ spanners: spanners,
+ followers: followers
+ };
+ return drag;
+ },
+ beginColumnResize: function(e){
+ this.moverDiv = document.createElement("div");
+ dojo.style(this.moverDiv,{position: "absolute", left:0}); // to make DnD work with dir=rtl
+ dojo.body().appendChild(this.moverDiv);
+ dojo.addClass(this.grid.domNode, "dojoxGridColumnResizing");
+ var m = (this.moveable = new dojo.dnd.Moveable(this.moverDiv));
+
+ var drag = this.colResizeSetup(e,true);
+
+ m.onMove = dojo.hitch(this, "doResizeColumn", drag);
+
+ dojo.connect(m, "onMoveStop", dojo.hitch(this, function(){
+ this.endResizeColumn(drag);
+ if(drag.node.releaseCapture){
+ drag.node.releaseCapture();
+ }
+ this.moveable.destroy();
+ delete this.moveable;
+ this.moveable = null;
+ dojo.removeClass(this.grid.domNode, "dojoxGridColumnResizing");
+ }));
+
+ if(e.cellNode.setCapture){
+ e.cellNode.setCapture();
+ }
+ m.onMouseDown(e);
+ },
+
+ doResizeColumn: function(inDrag, mover, leftTop){
+ var changeX = leftTop.l;
+ var data = {
+ deltaX: changeX,
+ w: inDrag.w + (dojo._isBodyLtr() ? changeX : -changeX),//fix #11341
+ vw: inDrag.vw + changeX,
+ tw: inDrag.tw + changeX
+ };
+
+ this.dragRecord = {inDrag: inDrag, mover: mover, leftTop:leftTop};
+
+ if(data.w >= this.minColWidth){
+ if (!mover) { // we are using keyboard do immediate resize
+ this.doResizeNow(inDrag, data);
+ }
+ else{
+ dojo.style(this.lineDiv, "left", (this.lineDiv._origLeft + data.deltaX) + "px");
+ }
+ }
+ },
+
+ endResizeColumn: function(inDrag){
+ if(this.dragRecord){
+ var leftTop = this.dragRecord.leftTop;
+ var changeX = dojo._isBodyLtr() ? leftTop.l : -leftTop.l;
+ // Make sure we are not under our minimum
+ // http://bugs.dojotoolkit.org/ticket/9390
+ changeX += Math.max(inDrag.w + changeX, this.minColWidth) - (inDrag.w + changeX);
+ if(dojo.isWebKit && inDrag.spanners.length){
+ // Webkit needs the pad border extents back in
+ changeX += dojo._getPadBorderExtents(inDrag.spanners[0].node).w;
+ }
+ var data = {
+ deltaX: changeX,
+ w: inDrag.w + changeX,
+ vw: inDrag.vw + changeX,
+ tw: inDrag.tw + changeX
+ };
+ // Only resize the columns when the drag has finished
+ this.doResizeNow(inDrag, data);
+ delete this.dragRecord;
+ }
+
+ dojo.destroy(this.lineDiv);
+ dojo.destroy(this.moverDiv);
+ dojo.destroy(this.moverDiv);
+ delete this.moverDiv;
+ this._skipBogusClicks = true;
+ inDrag.view.update();
+ this._skipBogusClicks = false;
+ this.grid.onResizeColumn(inDrag.index);
+ },
+ doResizeNow: function(inDrag, data){
+ inDrag.view.convertColPctToFixed();
+ if(inDrag.view.flexCells && !inDrag.view.testFlexCells()){
+ var t = findTable(inDrag.node);
+ if(t){
+ (t.style.width = '');
+ }
+ }
+ var i, s, sw, f, fl;
+ for(i=0; (s=inDrag.spanners[i]); i++){
+ sw = s.width + data.deltaX;
+ s.node.style.width = sw + 'px';
+ inDrag.view.setColWidth(s.index, sw);
+ }
+ if(dojo._isBodyLtr() || !dojo.isIE){//fix #11339
+ for(i=0; (f=inDrag.followers[i]); i++){
+ fl = f.left + data.deltaX;
+ f.node.style.left = fl + 'px';
+ }
+ }
+ inDrag.node.style.width = data.w + 'px';
+ inDrag.view.setColWidth(inDrag.index, data.w);
+ inDrag.view.headerNode.style.width = data.vw + 'px';
+ inDrag.view.setColumnsWidth(data.tw);
+ if(!dojo._isBodyLtr()){
+ inDrag.view.headerNode.scrollLeft = inDrag.scrollLeft + data.deltaX;
+ }
+ }
+ });
+
+ // Maps an html table into a structure parsable for information about cell row and col spanning.
+ // Used by HeaderBuilder.
+ dg._TableMap = dojo.extend(function(rows){
+ this.mapRows(rows);
+ },{
+ map: null,
+
+ mapRows: function(inRows){
+ // summary: Map table topography
+
+ //console.log('mapRows');
+ // # of rows
+ var rowCount = inRows.length;
+ if(!rowCount){
+ return;
+ }
+ // map which columns and rows fill which cells
+ this.map = [];
+ var row;
+ for(var k=0; (row=inRows[k]); k++){
+ this.map[k] = [];
+ }
+ for(var j=0; (row=inRows[j]); j++){
+ for(var i=0, x=0, cell, colSpan, rowSpan; (cell=row[i]); i++){
+ while(this.map[j][x]){x++;}
+ this.map[j][x] = { c: i, r: j };
+ rowSpan = cell.rowSpan || 1;
+ colSpan = cell.colSpan || 1;
+ for(var y=0; y<rowSpan; y++){
+ for(var s=0; s<colSpan; s++){
+ this.map[j+y][x+s] = this.map[j][x];
+ }
+ }
+ x += colSpan;
+ }
+ }
+ //this.dumMap();
+ },
+
+ dumpMap: function(){
+ for(var j=0, row, h=''; (row=this.map[j]); j++,h=''){
+ for(var i=0, cell; (cell=row[i]); i++){
+ h += cell.r + ',' + cell.c + ' ';
+ }
+ }
+ },
+
+ getMapCoords: function(inRow, inCol){
+ // summary: Find node's map coords by it's structure coords
+ for(var j=0, row; (row=this.map[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ if(cell.c==inCol && cell.r == inRow){
+ return { j: j, i: i };
+ }
+ //else{console.log(inRow, inCol, ' : ', i, j, " : ", cell.r, cell.c); };
+ }
+ }
+ return { j: -1, i: -1 };
+ },
+
+ getNode: function(inTable, inRow, inCol){
+ // summary: Find a node in inNode's table with the given structure coords
+ var row = inTable && inTable.rows[inRow];
+ return row && row.cells[inCol];
+ },
+
+ _findOverlappingNodes: function(inTable, inRow, inCol){
+ var nodes = [];
+ var m = this.getMapCoords(inRow, inCol);
+ //console.log("node j: %d, i: %d", m.j, m.i);
+ for(var j=0, row; (row=this.map[j]); j++){
+ if(j == m.j){ continue; }
+ var rw = row[m.i];
+ //console.log("overlaps: r: %d, c: %d", rw.r, rw.c);
+ var n = (rw?this.getNode(inTable, rw.r, rw.c):null);
+ if(n){ nodes.push(n); }
+ }
+ //console.log(nodes);
+ return nodes;
+ },
+
+ findOverlappingNodes: function(inNode){
+ return this._findOverlappingNodes(findTable(inNode), getTrIndex(inNode.parentNode), getTdIndex(inNode));
+ }
+ });
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/_Builder.xd.js b/js/dojo-1.6/dojox/grid/_Builder.xd.js
new file mode 100644
index 0000000..1c61391
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_Builder.xd.js
@@ -0,0 +1,759 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid._Builder"],
+["require", "dojox.grid.util"],
+["require", "dojo.dnd.Moveable"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid._Builder"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Builder"] = true;
+dojo.provide("dojox.grid._Builder");
+
+dojo.require("dojox.grid.util");
+dojo.require("dojo.dnd.Moveable");
+
+(function(){
+ var dg = dojox.grid;
+
+ var getTdIndex = function(td){
+ return td.cellIndex >=0 ? td.cellIndex : dojo.indexOf(td.parentNode.cells, td);
+ };
+
+ var getTrIndex = function(tr){
+ return tr.rowIndex >=0 ? tr.rowIndex : dojo.indexOf(tr.parentNode.childNodes, tr);
+ };
+
+ var getTr = function(rowOwner, index){
+ return rowOwner && ((rowOwner.rows||0)[index] || rowOwner.childNodes[index]);
+ };
+
+ var findTable = function(node){
+ for(var n=node; n && n.tagName!='TABLE'; n=n.parentNode){}
+ return n;
+ };
+
+ var ascendDom = function(inNode, inWhile){
+ for(var n=inNode; n && inWhile(n); n=n.parentNode){}
+ return n;
+ };
+
+ var makeNotTagName = function(inTagName){
+ var name = inTagName.toUpperCase();
+ return function(node){ return node.tagName != name; };
+ };
+
+ var rowIndexTag = dojox.grid.util.rowIndexTag;
+ var gridViewTag = dojox.grid.util.gridViewTag;
+
+ // base class for generating markup for the views
+ dg._Builder = dojo.extend(function(view){
+ if(view){
+ this.view = view;
+ this.grid = view.grid;
+ }
+ },{
+ view: null,
+ // boilerplate HTML
+ _table: '<table class="dojoxGridRowTable" border="0" cellspacing="0" cellpadding="0" role="presentation"',
+
+ // Returns the table variable as an array - and with the view width, if specified
+ getTableArray: function(){
+ var html = [this._table];
+ if(this.view.viewWidth){
+ html.push([' style="width:', this.view.viewWidth, ';"'].join(''));
+ }
+ html.push('>');
+ return html;
+ },
+
+ // generate starting tags for a cell
+ generateCellMarkup: function(inCell, inMoreStyles, inMoreClasses, isHeader){
+ var result = [], html;
+ if(isHeader){
+ var sortInfo = inCell.index != inCell.grid.getSortIndex() ? "" : inCell.grid.sortInfo > 0 ? 'aria-sort="ascending"' : 'aria-sort="descending"';
+ if (!inCell.id){
+ inCell.id = this.grid.id + "Hdr" + inCell.index;
+ }
+ // column headers are not editable, mark as aria-readonly=true
+ html = ['<th tabIndex="-1" aria-readonly="true" role="columnheader"', sortInfo, 'id="', inCell.id, '"'];
+ }else{
+ // cells inherit grid aria-readonly property; default value for aria-readonly is false(grid is editable)
+ // if grid is editable (had any editable cells), mark non editable cells as aria-readonly=true
+ // if no editable cells, grid's aria-readonly value will have been set to true and cells will inherit
+ var editInfo = this.grid.editable && !inCell.editable ? 'aria-readonly="true"' : "";
+ html = ['<td tabIndex="-1" role="gridcell"', editInfo];
+ }
+ if(inCell.colSpan){
+ html.push(' colspan="', inCell.colSpan, '"');
+ }
+ if(inCell.rowSpan){
+ html.push(' rowspan="', inCell.rowSpan, '"');
+ }
+ html.push(' class="dojoxGridCell ');
+ if(inCell.classes){
+ html.push(inCell.classes, ' ');
+ }
+ if(inMoreClasses){
+ html.push(inMoreClasses, ' ');
+ }
+ // result[0] => td opener, style
+ result.push(html.join(''));
+ // SLOT: result[1] => td classes
+ result.push('');
+ html = ['" idx="', inCell.index, '" style="'];
+ if(inMoreStyles && inMoreStyles[inMoreStyles.length-1] != ';'){
+ inMoreStyles += ';';
+ }
+ html.push(inCell.styles, inMoreStyles||'', inCell.hidden?'display:none;':'');
+ if(inCell.unitWidth){
+ html.push('width:', inCell.unitWidth, ';');
+ }
+ // result[2] => markup
+ result.push(html.join(''));
+ // SLOT: result[3] => td style
+ result.push('');
+ html = [ '"' ];
+ if(inCell.attrs){
+ html.push(" ", inCell.attrs);
+ }
+ html.push('>');
+ // result[4] => td postfix
+ result.push(html.join(''));
+ // SLOT: result[5] => content
+ result.push('');
+ // result[6] => td closes
+ result.push(isHeader?'</th>':'</td>');
+ return result; // Array
+ },
+
+ // cell finding
+ isCellNode: function(inNode){
+ return Boolean(inNode && inNode!=dojo.doc && dojo.attr(inNode, "idx"));
+ },
+
+ getCellNodeIndex: function(inCellNode){
+ return inCellNode ? Number(dojo.attr(inCellNode, "idx")) : -1;
+ },
+
+ getCellNode: function(inRowNode, inCellIndex){
+ for(var i=0, row; (row=getTr(inRowNode.firstChild, i)); i++){
+ for(var j=0, cell; (cell=row.cells[j]); j++){
+ if(this.getCellNodeIndex(cell) == inCellIndex){
+ return cell;
+ }
+ }
+ }
+ return null;
+ },
+
+ findCellTarget: function(inSourceNode, inTopNode){
+ var n = inSourceNode;
+ while(n && (!this.isCellNode(n) || (n.offsetParent && gridViewTag in n.offsetParent.parentNode && n.offsetParent.parentNode[gridViewTag] != this.view.id)) && (n!=inTopNode)){
+ n = n.parentNode;
+ }
+ return n!=inTopNode ? n : null;
+ },
+
+ // event decoration
+ baseDecorateEvent: function(e){
+ e.dispatch = 'do' + e.type;
+ e.grid = this.grid;
+ e.sourceView = this.view;
+ e.cellNode = this.findCellTarget(e.target, e.rowNode);
+ e.cellIndex = this.getCellNodeIndex(e.cellNode);
+ e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null);
+ },
+
+ // event dispatch
+ findTarget: function(inSource, inTag){
+ var n = inSource;
+ while(n && (n!=this.domNode) && (!(inTag in n) || (gridViewTag in n && n[gridViewTag] != this.view.id))){
+ n = n.parentNode;
+ }
+ return (n != this.domNode) ? n : null;
+ },
+
+ findRowTarget: function(inSource){
+ return this.findTarget(inSource, rowIndexTag);
+ },
+
+ isIntraNodeEvent: function(e){
+ try{
+ return (e.cellNode && e.relatedTarget && dojo.isDescendant(e.relatedTarget, e.cellNode));
+ }catch(x){
+ // e.relatedTarget has permission problem in FF if it's an input: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+ return false;
+ }
+ },
+
+ isIntraRowEvent: function(e){
+ try{
+ var row = e.relatedTarget && this.findRowTarget(e.relatedTarget);
+ return !row && (e.rowIndex==-1) || row && (e.rowIndex==row.gridRowIndex);
+ }catch(x){
+ // e.relatedTarget on INPUT has permission problem in FF: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+ return false;
+ }
+ },
+
+ dispatchEvent: function(e){
+ if(e.dispatch in this){
+ return this[e.dispatch](e);
+ }
+ return false;
+ },
+
+ // dispatched event handlers
+ domouseover: function(e){
+ if(e.cellNode && (e.cellNode!=this.lastOverCellNode)){
+ this.lastOverCellNode = e.cellNode;
+ this.grid.onMouseOver(e);
+ }
+ this.grid.onMouseOverRow(e);
+ },
+
+ domouseout: function(e){
+ if(e.cellNode && (e.cellNode==this.lastOverCellNode) && !this.isIntraNodeEvent(e, this.lastOverCellNode)){
+ this.lastOverCellNode = null;
+ this.grid.onMouseOut(e);
+ if(!this.isIntraRowEvent(e)){
+ this.grid.onMouseOutRow(e);
+ }
+ }
+ },
+
+ domousedown: function(e){
+ if (e.cellNode)
+ this.grid.onMouseDown(e);
+ this.grid.onMouseDownRow(e);
+ }
+ });
+
+ // Produces html for grid data content. Owned by grid and used internally
+ // for rendering data. Override to implement custom rendering.
+ dg._ContentBuilder = dojo.extend(function(view){
+ dg._Builder.call(this, view);
+ },dg._Builder.prototype,{
+ update: function(){
+ this.prepareHtml();
+ },
+
+ // cache html for rendering data rows
+ prepareHtml: function(){
+ var defaultGet=this.grid.get, cells=this.view.structure.cells;
+ for(var j=0, row; (row=cells[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ cell.get = cell.get || (cell.value == undefined) && defaultGet;
+ cell.markup = this.generateCellMarkup(cell, cell.cellStyles, cell.cellClasses, false);
+ if (!this.grid.editable && cell.editable){
+ this.grid.editable = true;
+ }
+ }
+ }
+ },
+
+ // time critical: generate html using cache and data source
+ generateHtml: function(inDataIndex, inRowIndex){
+ var
+ html = this.getTableArray(),
+ v = this.view,
+ cells = v.structure.cells,
+ item = this.grid.getItem(inRowIndex);
+
+ dojox.grid.util.fire(this.view, "onBeforeRow", [inRowIndex, cells]);
+ for(var j=0, row; (row=cells[j]); j++){
+ if(row.hidden || row.header){
+ continue;
+ }
+ html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
+ for(var i=0, cell, m, cc, cs; (cell=row[i]); i++){
+ m = cell.markup; cc = cell.customClasses = []; cs = cell.customStyles = [];
+ // content (format can fill in cc and cs as side-effects)
+ m[5] = cell.format(inRowIndex, item);
+ // classes
+ m[1] = cc.join(' ');
+ // styles
+ m[3] = cs.join(';');
+ // in-place concat
+ html.push.apply(html, m);
+ }
+ html.push('</tr>');
+ }
+ html.push('</table>');
+ return html.join(''); // String
+ },
+
+ decorateEvent: function(e){
+ e.rowNode = this.findRowTarget(e.target);
+ if(!e.rowNode){return false;}
+ e.rowIndex = e.rowNode[rowIndexTag];
+ this.baseDecorateEvent(e);
+ e.cell = this.grid.getCell(e.cellIndex);
+ return true; // Boolean
+ }
+ });
+
+ // Produces html for grid header content. Owned by grid and used internally
+ // for rendering data. Override to implement custom rendering.
+ dg._HeaderBuilder = dojo.extend(function(view){
+ this.moveable = null;
+ dg._Builder.call(this, view);
+ },dg._Builder.prototype,{
+ _skipBogusClicks: false,
+ overResizeWidth: 4,
+ minColWidth: 1,
+
+ update: function(){
+ if(this.tableMap){
+ this.tableMap.mapRows(this.view.structure.cells);
+ }else{
+ this.tableMap = new dg._TableMap(this.view.structure.cells);
+ }
+ },
+
+ generateHtml: function(inGetValue, inValue){
+ var html = this.getTableArray(), cells = this.view.structure.cells;
+
+ dojox.grid.util.fire(this.view, "onBeforeRow", [-1, cells]);
+ for(var j=0, row; (row=cells[j]); j++){
+ if(row.hidden){
+ continue;
+ }
+ html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
+ for(var i=0, cell, markup; (cell=row[i]); i++){
+ cell.customClasses = [];
+ cell.customStyles = [];
+ if(this.view.simpleStructure){
+ if(cell.draggable){
+ if(cell.headerClasses){
+ if(cell.headerClasses.indexOf('dojoDndItem') == -1){
+ cell.headerClasses += ' dojoDndItem';
+ }
+ }else{
+ cell.headerClasses = 'dojoDndItem';
+ }
+ }
+ if(cell.attrs){
+ if(cell.attrs.indexOf("dndType='gridColumn_") == -1){
+ cell.attrs += " dndType='gridColumn_" + this.grid.id + "'";
+ }
+ }else{
+ cell.attrs = "dndType='gridColumn_" + this.grid.id + "'";
+ }
+ }
+ markup = this.generateCellMarkup(cell, cell.headerStyles, cell.headerClasses, true);
+ // content
+ markup[5] = (inValue != undefined ? inValue : inGetValue(cell));
+ // styles
+ markup[3] = cell.customStyles.join(';');
+ // classes
+ markup[1] = cell.customClasses.join(' '); //(cell.customClasses ? ' ' + cell.customClasses : '');
+ html.push(markup.join(''));
+ }
+ html.push('</tr>');
+ }
+ html.push('</table>');
+ return html.join('');
+ },
+
+ // event helpers
+ getCellX: function(e){
+ var n, x = e.layerX;
+ if(dojo.isMoz){
+ n = ascendDom(e.target, makeNotTagName("th"));
+ x -= (n && n.offsetLeft) || 0;
+ var t = e.sourceView.getScrollbarWidth();
+ if(!dojo._isBodyLtr()/*&& e.sourceView.headerNode.scrollLeft < t*/){
+ //fix #11253
+ table = ascendDom(n,makeNotTagName("table"));
+ x -= (table && table.offsetLeft) || 0;
+ }
+ //x -= getProp(ascendDom(e.target, mkNotTagName("td")), "offsetLeft") || 0;
+ }
+ n = ascendDom(e.target, function(){
+ if(!n || n == e.cellNode){
+ return false;
+ }
+ // Mozilla 1.8 (FF 1.5) has a bug that makes offsetLeft = -parent border width
+ // when parent has border, overflow: hidden, and is positioned
+ // handle this problem here ... not a general solution!
+ x += (n.offsetLeft < 0 ? 0 : n.offsetLeft);
+ return true;
+ });
+ return x;
+ },
+
+ // event decoration
+ decorateEvent: function(e){
+ this.baseDecorateEvent(e);
+ e.rowIndex = -1;
+ e.cellX = this.getCellX(e);
+ return true;
+ },
+
+ // event handlers
+ // resizing
+ prepareResize: function(e, mod){
+ do{
+ var i = getTdIndex(e.cellNode);
+ e.cellNode = (i ? e.cellNode.parentNode.cells[i+mod] : null);
+ e.cellIndex = (e.cellNode ? this.getCellNodeIndex(e.cellNode) : -1);
+ }while(e.cellNode && e.cellNode.style.display == "none");
+ return Boolean(e.cellNode);
+ },
+
+ canResize: function(e){
+ if(!e.cellNode || e.cellNode.colSpan > 1){
+ return false;
+ }
+ var cell = this.grid.getCell(e.cellIndex);
+ return !cell.noresize && cell.canResize();
+ },
+
+ overLeftResizeArea: function(e){
+ // We are never over a resize area if we are in the process of moving
+ if(dojo.hasClass(dojo.body(), "dojoDndMove")){
+ return false;
+ }
+ //Bugfix for crazy IE problem (#8807). IE returns position information for the icon and text arrow divs
+ //as if they were still on the left instead of returning the position they were 'float: right' to.
+ //So, the resize check ends up checking the wrong adjacent cell. This checks to see if the hover was over
+ //the image or text nodes, then just ignored them/treat them not in scale range.
+ if(dojo.isIE){
+ var tN = e.target;
+ if(dojo.hasClass(tN, "dojoxGridArrowButtonNode") ||
+ dojo.hasClass(tN, "dojoxGridArrowButtonChar")){
+ return false;
+ }
+ }
+
+ if(dojo._isBodyLtr()){
+ return (e.cellIndex>0) && (e.cellX > 0 && e.cellX < this.overResizeWidth) && this.prepareResize(e, -1);
+ }
+ var t = e.cellNode && (e.cellX > 0 && e.cellX < this.overResizeWidth);
+ return t;
+ },
+
+ overRightResizeArea: function(e){
+ // We are never over a resize area if we are in the process of moving
+ if(dojo.hasClass(dojo.body(), "dojoDndMove")){
+ return false;
+ }
+ //Bugfix for crazy IE problem (#8807). IE returns position information for the icon and text arrow divs
+ //as if they were still on the left instead of returning the position they were 'float: right' to.
+ //So, the resize check ends up checking the wrong adjacent cell. This checks to see if the hover was over
+ //the image or text nodes, then just ignored them/treat them not in scale range.
+ if(dojo.isIE){
+ var tN = e.target;
+ if(dojo.hasClass(tN, "dojoxGridArrowButtonNode") ||
+ dojo.hasClass(tN, "dojoxGridArrowButtonChar")){
+ return false;
+ }
+ }
+
+ if(dojo._isBodyLtr()){
+ return e.cellNode && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth);
+ }
+ return (e.cellIndex>0) && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth) && this.prepareResize(e, -1);
+ },
+
+ domousemove: function(e){
+ //console.log(e.cellIndex, e.cellX, e.cellNode.offsetWidth);
+ if(!this.moveable){
+ var c = (this.overRightResizeArea(e) ? 'dojoxGridColResize' : (this.overLeftResizeArea(e) ? 'dojoxGridColResize' : ''));
+ if(c && !this.canResize(e)){
+ c = 'dojoxGridColNoResize';
+ }
+ dojo.toggleClass(e.sourceView.headerNode, "dojoxGridColNoResize", (c == "dojoxGridColNoResize"));
+ dojo.toggleClass(e.sourceView.headerNode, "dojoxGridColResize", (c == "dojoxGridColResize"));
+ if(dojo.isIE){
+ var t = e.sourceView.headerNode.scrollLeft;
+ e.sourceView.headerNode.scrollLeft = t;
+ }
+ if(c){
+ dojo.stopEvent(e);
+ }
+ }
+ },
+
+ domousedown: function(e){
+ if(!this.moveable){
+ if((this.overRightResizeArea(e) || this.overLeftResizeArea(e)) && this.canResize(e)){
+ this.beginColumnResize(e);
+ }else{
+ this.grid.onMouseDown(e);
+ this.grid.onMouseOverRow(e);
+ }
+ //else{
+ // this.beginMoveColumn(e);
+ //}
+ }
+ },
+
+ doclick: function(e) {
+ if(this._skipBogusClicks){
+ dojo.stopEvent(e);
+ return true;
+ }
+ return false;
+ },
+
+ // column resizing
+ colResizeSetup: function(/*Event Object*/e, /*boolean*/ isMouse ){
+ //Set up the drag object for column resizing
+ // Called with mouse event in case of drag and drop,
+ // Also called from keyboard shift-arrow event when focus is on a header
+ var headContentBox = dojo.contentBox(e.sourceView.headerNode);
+
+ if(isMouse){ //IE draws line even with no mouse down so separate from keyboard
+ this.lineDiv = document.createElement('div');
+
+ // NOTE: this is for backwards compatibility with Dojo 1.3
+ var vw = (dojo.position||dojo._abs)(e.sourceView.headerNode, true);
+ var bodyContentBox = dojo.contentBox(e.sourceView.domNode);
+ //fix #11340
+ var l = e.pageX;
+ if(!dojo._isBodyLtr() && dojo.isIE < 8){
+ l -= dojox.html.metrics.getScrollbar().w;
+ }
+ dojo.style(this.lineDiv, {
+ top: vw.y + "px",
+ left: l + "px",
+ height: (bodyContentBox.h + headContentBox.h) + "px"
+ });
+ dojo.addClass(this.lineDiv, "dojoxGridResizeColLine");
+ this.lineDiv._origLeft = l;
+ dojo.body().appendChild(this.lineDiv);
+ }
+ var spanners = [], nodes = this.tableMap.findOverlappingNodes(e.cellNode);
+ for(var i=0, cell; (cell=nodes[i]); i++){
+ spanners.push({ node: cell, index: this.getCellNodeIndex(cell), width: cell.offsetWidth });
+ //console.log("spanner: " + this.getCellNodeIndex(cell));
+ }
+
+ var view = e.sourceView;
+ var adj = dojo._isBodyLtr() ? 1 : -1;
+ var views = e.grid.views.views;
+ var followers = [];
+ for(var j=view.idx+adj, cView; (cView=views[j]); j=j+adj){
+ followers.push({ node: cView.headerNode, left: window.parseInt(cView.headerNode.style.left) });
+ }
+ var table = view.headerContentNode.firstChild;
+ var drag = {
+ scrollLeft: e.sourceView.headerNode.scrollLeft,
+ view: view,
+ node: e.cellNode,
+ index: e.cellIndex,
+ w: dojo.contentBox(e.cellNode).w,
+ vw: headContentBox.w,
+ table: table,
+ tw: dojo.contentBox(table).w,
+ spanners: spanners,
+ followers: followers
+ };
+ return drag;
+ },
+ beginColumnResize: function(e){
+ this.moverDiv = document.createElement("div");
+ dojo.style(this.moverDiv,{position: "absolute", left:0}); // to make DnD work with dir=rtl
+ dojo.body().appendChild(this.moverDiv);
+ dojo.addClass(this.grid.domNode, "dojoxGridColumnResizing");
+ var m = (this.moveable = new dojo.dnd.Moveable(this.moverDiv));
+
+ var drag = this.colResizeSetup(e,true);
+
+ m.onMove = dojo.hitch(this, "doResizeColumn", drag);
+
+ dojo.connect(m, "onMoveStop", dojo.hitch(this, function(){
+ this.endResizeColumn(drag);
+ if(drag.node.releaseCapture){
+ drag.node.releaseCapture();
+ }
+ this.moveable.destroy();
+ delete this.moveable;
+ this.moveable = null;
+ dojo.removeClass(this.grid.domNode, "dojoxGridColumnResizing");
+ }));
+
+ if(e.cellNode.setCapture){
+ e.cellNode.setCapture();
+ }
+ m.onMouseDown(e);
+ },
+
+ doResizeColumn: function(inDrag, mover, leftTop){
+ var changeX = leftTop.l;
+ var data = {
+ deltaX: changeX,
+ w: inDrag.w + (dojo._isBodyLtr() ? changeX : -changeX),//fix #11341
+ vw: inDrag.vw + changeX,
+ tw: inDrag.tw + changeX
+ };
+
+ this.dragRecord = {inDrag: inDrag, mover: mover, leftTop:leftTop};
+
+ if(data.w >= this.minColWidth){
+ if (!mover) { // we are using keyboard do immediate resize
+ this.doResizeNow(inDrag, data);
+ }
+ else{
+ dojo.style(this.lineDiv, "left", (this.lineDiv._origLeft + data.deltaX) + "px");
+ }
+ }
+ },
+
+ endResizeColumn: function(inDrag){
+ if(this.dragRecord){
+ var leftTop = this.dragRecord.leftTop;
+ var changeX = dojo._isBodyLtr() ? leftTop.l : -leftTop.l;
+ // Make sure we are not under our minimum
+ // http://bugs.dojotoolkit.org/ticket/9390
+ changeX += Math.max(inDrag.w + changeX, this.minColWidth) - (inDrag.w + changeX);
+ if(dojo.isWebKit && inDrag.spanners.length){
+ // Webkit needs the pad border extents back in
+ changeX += dojo._getPadBorderExtents(inDrag.spanners[0].node).w;
+ }
+ var data = {
+ deltaX: changeX,
+ w: inDrag.w + changeX,
+ vw: inDrag.vw + changeX,
+ tw: inDrag.tw + changeX
+ };
+ // Only resize the columns when the drag has finished
+ this.doResizeNow(inDrag, data);
+ delete this.dragRecord;
+ }
+
+ dojo.destroy(this.lineDiv);
+ dojo.destroy(this.moverDiv);
+ dojo.destroy(this.moverDiv);
+ delete this.moverDiv;
+ this._skipBogusClicks = true;
+ inDrag.view.update();
+ this._skipBogusClicks = false;
+ this.grid.onResizeColumn(inDrag.index);
+ },
+ doResizeNow: function(inDrag, data){
+ inDrag.view.convertColPctToFixed();
+ if(inDrag.view.flexCells && !inDrag.view.testFlexCells()){
+ var t = findTable(inDrag.node);
+ if(t){
+ (t.style.width = '');
+ }
+ }
+ var i, s, sw, f, fl;
+ for(i=0; (s=inDrag.spanners[i]); i++){
+ sw = s.width + data.deltaX;
+ s.node.style.width = sw + 'px';
+ inDrag.view.setColWidth(s.index, sw);
+ }
+ if(dojo._isBodyLtr() || !dojo.isIE){//fix #11339
+ for(i=0; (f=inDrag.followers[i]); i++){
+ fl = f.left + data.deltaX;
+ f.node.style.left = fl + 'px';
+ }
+ }
+ inDrag.node.style.width = data.w + 'px';
+ inDrag.view.setColWidth(inDrag.index, data.w);
+ inDrag.view.headerNode.style.width = data.vw + 'px';
+ inDrag.view.setColumnsWidth(data.tw);
+ if(!dojo._isBodyLtr()){
+ inDrag.view.headerNode.scrollLeft = inDrag.scrollLeft + data.deltaX;
+ }
+ }
+ });
+
+ // Maps an html table into a structure parsable for information about cell row and col spanning.
+ // Used by HeaderBuilder.
+ dg._TableMap = dojo.extend(function(rows){
+ this.mapRows(rows);
+ },{
+ map: null,
+
+ mapRows: function(inRows){
+ // summary: Map table topography
+
+ //console.log('mapRows');
+ // # of rows
+ var rowCount = inRows.length;
+ if(!rowCount){
+ return;
+ }
+ // map which columns and rows fill which cells
+ this.map = [];
+ var row;
+ for(var k=0; (row=inRows[k]); k++){
+ this.map[k] = [];
+ }
+ for(var j=0; (row=inRows[j]); j++){
+ for(var i=0, x=0, cell, colSpan, rowSpan; (cell=row[i]); i++){
+ while(this.map[j][x]){x++;}
+ this.map[j][x] = { c: i, r: j };
+ rowSpan = cell.rowSpan || 1;
+ colSpan = cell.colSpan || 1;
+ for(var y=0; y<rowSpan; y++){
+ for(var s=0; s<colSpan; s++){
+ this.map[j+y][x+s] = this.map[j][x];
+ }
+ }
+ x += colSpan;
+ }
+ }
+ //this.dumMap();
+ },
+
+ dumpMap: function(){
+ for(var j=0, row, h=''; (row=this.map[j]); j++,h=''){
+ for(var i=0, cell; (cell=row[i]); i++){
+ h += cell.r + ',' + cell.c + ' ';
+ }
+ }
+ },
+
+ getMapCoords: function(inRow, inCol){
+ // summary: Find node's map coords by it's structure coords
+ for(var j=0, row; (row=this.map[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ if(cell.c==inCol && cell.r == inRow){
+ return { j: j, i: i };
+ }
+ //else{console.log(inRow, inCol, ' : ', i, j, " : ", cell.r, cell.c); };
+ }
+ }
+ return { j: -1, i: -1 };
+ },
+
+ getNode: function(inTable, inRow, inCol){
+ // summary: Find a node in inNode's table with the given structure coords
+ var row = inTable && inTable.rows[inRow];
+ return row && row.cells[inCol];
+ },
+
+ _findOverlappingNodes: function(inTable, inRow, inCol){
+ var nodes = [];
+ var m = this.getMapCoords(inRow, inCol);
+ //console.log("node j: %d, i: %d", m.j, m.i);
+ for(var j=0, row; (row=this.map[j]); j++){
+ if(j == m.j){ continue; }
+ var rw = row[m.i];
+ //console.log("overlaps: r: %d, c: %d", rw.r, rw.c);
+ var n = (rw?this.getNode(inTable, rw.r, rw.c):null);
+ if(n){ nodes.push(n); }
+ }
+ //console.log(nodes);
+ return nodes;
+ },
+
+ findOverlappingNodes: function(inNode){
+ return this._findOverlappingNodes(findTable(inNode), getTrIndex(inNode.parentNode), getTdIndex(inNode));
+ }
+ });
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/_CheckBoxSelector.js b/js/dojo-1.6/dojox/grid/_CheckBoxSelector.js
new file mode 100644
index 0000000..7f01718
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_CheckBoxSelector.js
@@ -0,0 +1,14 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid._CheckBoxSelector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._CheckBoxSelector"] = true;
+dojo.provide("dojox.grid._CheckBoxSelector");
+
+dojo.require("dojox.grid._Selector");
+
+}
diff --git a/js/dojo-1.6/dojox/grid/_CheckBoxSelector.xd.js b/js/dojo-1.6/dojox/grid/_CheckBoxSelector.xd.js
new file mode 100644
index 0000000..4f139b3
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_CheckBoxSelector.xd.js
@@ -0,0 +1,19 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid._CheckBoxSelector"],
+["require", "dojox.grid._Selector"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid._CheckBoxSelector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._CheckBoxSelector"] = true;
+dojo.provide("dojox.grid._CheckBoxSelector");
+
+dojo.require("dojox.grid._Selector");
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/_EditManager.js b/js/dojo-1.6/dojox/grid/_EditManager.js
new file mode 100644
index 0000000..df76859
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_EditManager.js
@@ -0,0 +1,250 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid._EditManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._EditManager"] = true;
+dojo.provide("dojox.grid._EditManager");
+
+dojo.require("dojox.grid.util");
+
+dojo.declare("dojox.grid._EditManager", null, {
+ // summary:
+ // Controls grid cell editing process. Owned by grid and used internally for editing.
+ constructor: function(inGrid){
+ // inGrid: dojox.Grid
+ // The dojox.Grid this editor should be attached to
+ this.grid = inGrid;
+ if(dojo.isIE){
+ this.connections = [dojo.connect(document.body, "onfocus", dojo.hitch(this, "_boomerangFocus"))];
+ }else{
+ this.connections = [dojo.connect(this.grid, 'onBlur', this, 'apply')];
+ }
+ },
+
+ info: {},
+
+ destroy: function(){
+ dojo.forEach(this.connections,dojo.disconnect);
+ },
+
+ cellFocus: function(inCell, inRowIndex){
+ // summary:
+ // Invoke editing when cell is focused
+ // inCell: cell object
+ // Grid cell object
+ // inRowIndex: Integer
+ // Grid row index
+ if(this.grid.singleClickEdit || this.isEditRow(inRowIndex)){
+ // if same row or quick editing, edit
+ this.setEditCell(inCell, inRowIndex);
+ }else{
+ // otherwise, apply any pending row edits
+ this.apply();
+ }
+ // if dynamic or static editing...
+ if(this.isEditing() || (inCell && inCell.editable && inCell.alwaysEditing)){
+ // let the editor focus itself as needed
+ this._focusEditor(inCell, inRowIndex);
+ }
+ },
+
+ rowClick: function(e){
+ if(this.isEditing() && !this.isEditRow(e.rowIndex)){
+ this.apply();
+ }
+ },
+
+ styleRow: function(inRow){
+ if(inRow.index == this.info.rowIndex){
+ inRow.customClasses += ' dojoxGridRowEditing';
+ }
+ },
+
+ dispatchEvent: function(e){
+ var c = e.cell, ed = (c && c["editable"]) ? c : 0;
+ return ed && ed.dispatchEvent(e.dispatch, e);
+ },
+
+ // Editing
+ isEditing: function(){
+ // summary:
+ // Indicates editing state of the grid.
+ // returns: Boolean
+ // True if grid is actively editing
+ return this.info.rowIndex !== undefined;
+ },
+
+ isEditCell: function(inRowIndex, inCellIndex){
+ // summary:
+ // Indicates if the given cell is being edited.
+ // inRowIndex: Integer
+ // Grid row index
+ // inCellIndex: Integer
+ // Grid cell index
+ // returns: Boolean
+ // True if given cell is being edited
+ return (this.info.rowIndex === inRowIndex) && (this.info.cell.index == inCellIndex);
+ },
+
+ isEditRow: function(inRowIndex){
+ // summary:
+ // Indicates if the given row is being edited.
+ // inRowIndex: Integer
+ // Grid row index
+ // returns: Boolean
+ // True if given row is being edited
+ return this.info.rowIndex === inRowIndex;
+ },
+
+ setEditCell: function(inCell, inRowIndex){
+ // summary:
+ // Set the given cell to be edited
+ // inRowIndex: Integer
+ // Grid row index
+ // inCell: Object
+ // Grid cell object
+ if(!this.isEditCell(inRowIndex, inCell.index) && this.grid.canEdit && this.grid.canEdit(inCell, inRowIndex)){
+ this.start(inCell, inRowIndex, this.isEditRow(inRowIndex) || inCell.editable);
+ }
+ },
+
+ _focusEditor: function(inCell, inRowIndex){
+ dojox.grid.util.fire(inCell, "focus", [inRowIndex]);
+ },
+
+ focusEditor: function(){
+ if(this.isEditing()){
+ this._focusEditor(this.info.cell, this.info.rowIndex);
+ }
+ },
+
+ // implement fix for focus boomerang effect on IE
+ _boomerangWindow: 500,
+ _shouldCatchBoomerang: function(){
+ return this._catchBoomerang > new Date().getTime();
+ },
+ _boomerangFocus: function(){
+ //console.log("_boomerangFocus");
+ if(this._shouldCatchBoomerang()){
+ // make sure we don't utterly lose focus
+ this.grid.focus.focusGrid();
+ // let the editor focus itself as needed
+ this.focusEditor();
+ // only catch once
+ this._catchBoomerang = 0;
+ }
+ },
+ _doCatchBoomerang: function(){
+ // give ourselves a few ms to boomerang IE focus effects
+ if(dojo.isIE){this._catchBoomerang = new Date().getTime() + this._boomerangWindow;}
+ },
+ // end boomerang fix API
+
+ start: function(inCell, inRowIndex, inEditing){
+ this.grid.beginUpdate();
+ this.editorApply();
+ if(this.isEditing() && !this.isEditRow(inRowIndex)){
+ this.applyRowEdit();
+ this.grid.updateRow(inRowIndex);
+ }
+ if(inEditing){
+ this.info = { cell: inCell, rowIndex: inRowIndex };
+ this.grid.doStartEdit(inCell, inRowIndex);
+ this.grid.updateRow(inRowIndex);
+ }else{
+ this.info = {};
+ }
+ this.grid.endUpdate();
+ // make sure we don't utterly lose focus
+ this.grid.focus.focusGrid();
+ // let the editor focus itself as needed
+ this._focusEditor(inCell, inRowIndex);
+ // give ourselves a few ms to boomerang IE focus effects
+ this._doCatchBoomerang();
+ },
+
+ _editorDo: function(inMethod){
+ var c = this.info.cell;
+ //c && c.editor && c.editor[inMethod](c, this.info.rowIndex);
+ if(c && c.editable){
+ c[inMethod](this.info.rowIndex);
+ }
+ },
+
+ editorApply: function(){
+ this._editorDo("apply");
+ },
+
+ editorCancel: function(){
+ this._editorDo("cancel");
+ },
+
+ applyCellEdit: function(inValue, inCell, inRowIndex){
+ if(this.grid.canEdit(inCell, inRowIndex)){
+ this.grid.doApplyCellEdit(inValue, inRowIndex, inCell.field);
+ }
+ },
+
+ applyRowEdit: function(){
+ this.grid.doApplyEdit(this.info.rowIndex, this.info.cell.field);
+ },
+
+ apply: function(){
+ // summary:
+ // Apply a grid edit
+ if(this.isEditing()){
+ this.grid.beginUpdate();
+ this.editorApply();
+ this.applyRowEdit();
+ this.info = {};
+ this.grid.endUpdate();
+ this.grid.focus.focusGrid();
+ this._doCatchBoomerang();
+ }
+ },
+
+ cancel: function(){
+ // summary:
+ // Cancel a grid edit
+ if(this.isEditing()){
+ this.grid.beginUpdate();
+ this.editorCancel();
+ this.info = {};
+ this.grid.endUpdate();
+ this.grid.focus.focusGrid();
+ this._doCatchBoomerang();
+ }
+ },
+
+ save: function(inRowIndex, inView){
+ // summary:
+ // Save the grid editing state
+ // inRowIndex: Integer
+ // Grid row index
+ // inView: Object
+ // Grid view
+ var c = this.info.cell;
+ if(this.isEditRow(inRowIndex) && (!inView || c.view==inView) && c.editable){
+ c.save(c, this.info.rowIndex);
+ }
+ },
+
+ restore: function(inView, inRowIndex){
+ // summary:
+ // Restores the grid editing state
+ // inRowIndex: Integer
+ // Grid row index
+ // inView: Object
+ // Grid view
+ var c = this.info.cell;
+ if(this.isEditRow(inRowIndex) && c.view == inView && c.editable){
+ c.restore(c, this.info.rowIndex);
+ }
+ }
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/_EditManager.xd.js b/js/dojo-1.6/dojox/grid/_EditManager.xd.js
new file mode 100644
index 0000000..cd335cb
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_EditManager.xd.js
@@ -0,0 +1,255 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid._EditManager"],
+["require", "dojox.grid.util"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid._EditManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._EditManager"] = true;
+dojo.provide("dojox.grid._EditManager");
+
+dojo.require("dojox.grid.util");
+
+dojo.declare("dojox.grid._EditManager", null, {
+ // summary:
+ // Controls grid cell editing process. Owned by grid and used internally for editing.
+ constructor: function(inGrid){
+ // inGrid: dojox.Grid
+ // The dojox.Grid this editor should be attached to
+ this.grid = inGrid;
+ if(dojo.isIE){
+ this.connections = [dojo.connect(document.body, "onfocus", dojo.hitch(this, "_boomerangFocus"))];
+ }else{
+ this.connections = [dojo.connect(this.grid, 'onBlur', this, 'apply')];
+ }
+ },
+
+ info: {},
+
+ destroy: function(){
+ dojo.forEach(this.connections,dojo.disconnect);
+ },
+
+ cellFocus: function(inCell, inRowIndex){
+ // summary:
+ // Invoke editing when cell is focused
+ // inCell: cell object
+ // Grid cell object
+ // inRowIndex: Integer
+ // Grid row index
+ if(this.grid.singleClickEdit || this.isEditRow(inRowIndex)){
+ // if same row or quick editing, edit
+ this.setEditCell(inCell, inRowIndex);
+ }else{
+ // otherwise, apply any pending row edits
+ this.apply();
+ }
+ // if dynamic or static editing...
+ if(this.isEditing() || (inCell && inCell.editable && inCell.alwaysEditing)){
+ // let the editor focus itself as needed
+ this._focusEditor(inCell, inRowIndex);
+ }
+ },
+
+ rowClick: function(e){
+ if(this.isEditing() && !this.isEditRow(e.rowIndex)){
+ this.apply();
+ }
+ },
+
+ styleRow: function(inRow){
+ if(inRow.index == this.info.rowIndex){
+ inRow.customClasses += ' dojoxGridRowEditing';
+ }
+ },
+
+ dispatchEvent: function(e){
+ var c = e.cell, ed = (c && c["editable"]) ? c : 0;
+ return ed && ed.dispatchEvent(e.dispatch, e);
+ },
+
+ // Editing
+ isEditing: function(){
+ // summary:
+ // Indicates editing state of the grid.
+ // returns: Boolean
+ // True if grid is actively editing
+ return this.info.rowIndex !== undefined;
+ },
+
+ isEditCell: function(inRowIndex, inCellIndex){
+ // summary:
+ // Indicates if the given cell is being edited.
+ // inRowIndex: Integer
+ // Grid row index
+ // inCellIndex: Integer
+ // Grid cell index
+ // returns: Boolean
+ // True if given cell is being edited
+ return (this.info.rowIndex === inRowIndex) && (this.info.cell.index == inCellIndex);
+ },
+
+ isEditRow: function(inRowIndex){
+ // summary:
+ // Indicates if the given row is being edited.
+ // inRowIndex: Integer
+ // Grid row index
+ // returns: Boolean
+ // True if given row is being edited
+ return this.info.rowIndex === inRowIndex;
+ },
+
+ setEditCell: function(inCell, inRowIndex){
+ // summary:
+ // Set the given cell to be edited
+ // inRowIndex: Integer
+ // Grid row index
+ // inCell: Object
+ // Grid cell object
+ if(!this.isEditCell(inRowIndex, inCell.index) && this.grid.canEdit && this.grid.canEdit(inCell, inRowIndex)){
+ this.start(inCell, inRowIndex, this.isEditRow(inRowIndex) || inCell.editable);
+ }
+ },
+
+ _focusEditor: function(inCell, inRowIndex){
+ dojox.grid.util.fire(inCell, "focus", [inRowIndex]);
+ },
+
+ focusEditor: function(){
+ if(this.isEditing()){
+ this._focusEditor(this.info.cell, this.info.rowIndex);
+ }
+ },
+
+ // implement fix for focus boomerang effect on IE
+ _boomerangWindow: 500,
+ _shouldCatchBoomerang: function(){
+ return this._catchBoomerang > new Date().getTime();
+ },
+ _boomerangFocus: function(){
+ //console.log("_boomerangFocus");
+ if(this._shouldCatchBoomerang()){
+ // make sure we don't utterly lose focus
+ this.grid.focus.focusGrid();
+ // let the editor focus itself as needed
+ this.focusEditor();
+ // only catch once
+ this._catchBoomerang = 0;
+ }
+ },
+ _doCatchBoomerang: function(){
+ // give ourselves a few ms to boomerang IE focus effects
+ if(dojo.isIE){this._catchBoomerang = new Date().getTime() + this._boomerangWindow;}
+ },
+ // end boomerang fix API
+
+ start: function(inCell, inRowIndex, inEditing){
+ this.grid.beginUpdate();
+ this.editorApply();
+ if(this.isEditing() && !this.isEditRow(inRowIndex)){
+ this.applyRowEdit();
+ this.grid.updateRow(inRowIndex);
+ }
+ if(inEditing){
+ this.info = { cell: inCell, rowIndex: inRowIndex };
+ this.grid.doStartEdit(inCell, inRowIndex);
+ this.grid.updateRow(inRowIndex);
+ }else{
+ this.info = {};
+ }
+ this.grid.endUpdate();
+ // make sure we don't utterly lose focus
+ this.grid.focus.focusGrid();
+ // let the editor focus itself as needed
+ this._focusEditor(inCell, inRowIndex);
+ // give ourselves a few ms to boomerang IE focus effects
+ this._doCatchBoomerang();
+ },
+
+ _editorDo: function(inMethod){
+ var c = this.info.cell;
+ //c && c.editor && c.editor[inMethod](c, this.info.rowIndex);
+ if(c && c.editable){
+ c[inMethod](this.info.rowIndex);
+ }
+ },
+
+ editorApply: function(){
+ this._editorDo("apply");
+ },
+
+ editorCancel: function(){
+ this._editorDo("cancel");
+ },
+
+ applyCellEdit: function(inValue, inCell, inRowIndex){
+ if(this.grid.canEdit(inCell, inRowIndex)){
+ this.grid.doApplyCellEdit(inValue, inRowIndex, inCell.field);
+ }
+ },
+
+ applyRowEdit: function(){
+ this.grid.doApplyEdit(this.info.rowIndex, this.info.cell.field);
+ },
+
+ apply: function(){
+ // summary:
+ // Apply a grid edit
+ if(this.isEditing()){
+ this.grid.beginUpdate();
+ this.editorApply();
+ this.applyRowEdit();
+ this.info = {};
+ this.grid.endUpdate();
+ this.grid.focus.focusGrid();
+ this._doCatchBoomerang();
+ }
+ },
+
+ cancel: function(){
+ // summary:
+ // Cancel a grid edit
+ if(this.isEditing()){
+ this.grid.beginUpdate();
+ this.editorCancel();
+ this.info = {};
+ this.grid.endUpdate();
+ this.grid.focus.focusGrid();
+ this._doCatchBoomerang();
+ }
+ },
+
+ save: function(inRowIndex, inView){
+ // summary:
+ // Save the grid editing state
+ // inRowIndex: Integer
+ // Grid row index
+ // inView: Object
+ // Grid view
+ var c = this.info.cell;
+ if(this.isEditRow(inRowIndex) && (!inView || c.view==inView) && c.editable){
+ c.save(c, this.info.rowIndex);
+ }
+ },
+
+ restore: function(inView, inRowIndex){
+ // summary:
+ // Restores the grid editing state
+ // inRowIndex: Integer
+ // Grid row index
+ // inView: Object
+ // Grid view
+ var c = this.info.cell;
+ if(this.isEditRow(inRowIndex) && c.view == inView && c.editable){
+ c.restore(c, this.info.rowIndex);
+ }
+ }
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/_Events.js b/js/dojo-1.6/dojox/grid/_Events.js
new file mode 100644
index 0000000..5b09ec0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_Events.js
@@ -0,0 +1,503 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid._Events"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Events"] = true;
+dojo.provide("dojox.grid._Events");
+
+dojo.declare("dojox.grid._Events", null, {
+ // summary:
+ // _Grid mixin that provides default implementations for grid events.
+ // description:
+ // Default synthetic events dispatched for _Grid. dojo.connect to events to
+ // retain default implementation or override them for custom handling.
+
+ // cellOverClass: String
+ // css class to apply to grid cells over which the cursor is placed.
+ cellOverClass: "dojoxGridCellOver",
+
+ onKeyEvent: function(e){
+ // summary: top level handler for Key Events
+ this.dispatchKeyEvent(e);
+ },
+
+ onContentEvent: function(e){
+ // summary: Top level handler for Content events
+ this.dispatchContentEvent(e);
+ },
+
+ onHeaderEvent: function(e){
+ // summary: Top level handler for header events
+ this.dispatchHeaderEvent(e);
+ },
+
+ onStyleRow: function(inRow){
+ // summary:
+ // Perform row styling on a given row. Called whenever row styling is updated.
+ //
+ // inRow: Object
+ // Object containing row state information: selected, true if the row is selcted; over:
+ // true of the mouse is over the row; odd: true if the row is odd. Use customClasses and
+ // customStyles to control row css classes and styles; both properties are strings.
+ //
+ // example: onStyleRow({ selected: true, over:true, odd:false })
+ var i = inRow;
+ i.customClasses += (i.odd?" dojoxGridRowOdd":"") + (i.selected?" dojoxGridRowSelected":"") + (i.over?" dojoxGridRowOver":"");
+ this.focus.styleRow(inRow);
+ this.edit.styleRow(inRow);
+ },
+
+ onKeyDown: function(e){
+ // summary:
+ // Grid key event handler. By default enter begins editing and applies edits, escape cancels an edit,
+ // tab, shift-tab, and arrow keys move grid cell focus.
+ if(e.altKey || e.metaKey){
+ return;
+ }
+ var dk = dojo.keys;
+ var colIdx;
+ switch(e.keyCode){
+ case dk.ESCAPE:
+ this.edit.cancel();
+ break;
+ case dk.ENTER:
+ if(!this.edit.isEditing()){
+ colIdx = this.focus.getHeaderIndex();
+ if(colIdx >= 0) {
+ this.setSortIndex(colIdx);
+ break;
+ }else {
+ this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ }
+ dojo.stopEvent(e);
+ }
+ if(!e.shiftKey){
+ var isEditing = this.edit.isEditing();
+ this.edit.apply();
+ if(!isEditing){
+ this.edit.setEditCell(this.focus.cell, this.focus.rowIndex);
+ }
+ }
+ if (!this.edit.isEditing()){
+ var curView = this.focus.focusView || this.views.views[0]; //if no focusView than only one view
+ curView.content.decorateEvent(e);
+ this.onRowClick(e);
+ }
+ break;
+ case dk.SPACE:
+ if(!this.edit.isEditing()){
+ colIdx = this.focus.getHeaderIndex();
+ if(colIdx >= 0) {
+ this.setSortIndex(colIdx);
+ break;
+ }else {
+ this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ }
+ dojo.stopEvent(e);
+ }
+ break;
+ case dk.TAB:
+ this.focus[e.shiftKey ? 'previousKey' : 'nextKey'](e);
+ break;
+ case dk.LEFT_ARROW:
+ case dk.RIGHT_ARROW:
+ if(!this.edit.isEditing()){
+ var keyCode = e.keyCode; // IE seems to lose after stopEvent when modifier keys
+ dojo.stopEvent(e);
+ colIdx = this.focus.getHeaderIndex();
+ if (colIdx >= 0 && (e.shiftKey && e.ctrlKey)){
+ this.focus.colSizeAdjust(e, colIdx, (keyCode == dk.LEFT_ARROW ? -1 : 1)*5);
+ }
+ else{
+ var offset = (keyCode == dk.LEFT_ARROW) ? 1 : -1;
+ if(dojo._isBodyLtr()){ offset *= -1; }
+ this.focus.move(0, offset);
+ }
+ }
+ break;
+ case dk.UP_ARROW:
+ if(!this.edit.isEditing() && this.focus.rowIndex !== 0){
+ dojo.stopEvent(e);
+ this.focus.move(-1, 0);
+ }
+ break;
+ case dk.DOWN_ARROW:
+ if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){
+ dojo.stopEvent(e);
+ this.focus.move(1, 0);
+ }
+ break;
+ case dk.PAGE_UP:
+ if(!this.edit.isEditing() && this.focus.rowIndex !== 0){
+ dojo.stopEvent(e);
+ if(this.focus.rowIndex != this.scroller.firstVisibleRow+1){
+ this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex, 0);
+ }else{
+ this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1));
+ this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1, 0);
+ }
+ }
+ break;
+ case dk.PAGE_DOWN:
+ if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){
+ dojo.stopEvent(e);
+ if(this.focus.rowIndex != this.scroller.lastVisibleRow-1){
+ this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1, 0);
+ }else{
+ this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1));
+ this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1, 0);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ },
+
+ onMouseOver: function(e){
+ // summary:
+ // Event fired when mouse is over the grid.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseOver(e) : this.onCellMouseOver(e);
+ },
+
+ onMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of the grid.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseOut(e) : this.onCellMouseOut(e);
+ },
+
+ onMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down inside grid.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseDown(e) : this.onCellMouseDown(e);
+ },
+
+ onMouseOverRow: function(e){
+ // summary:
+ // Event fired when mouse is over any row (data or header).
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(!this.rows.isOver(e.rowIndex)){
+ this.rows.setOverRow(e.rowIndex);
+ e.rowIndex == -1 ? this.onHeaderMouseOver(e) : this.onRowMouseOver(e);
+ }
+ },
+ onMouseOutRow: function(e){
+ // summary:
+ // Event fired when mouse moves out of any row (data or header).
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(this.rows.isOver(-1)){
+ this.onHeaderMouseOut(e);
+ }else if(!this.rows.isOver(-2)){
+ this.rows.setOverRow(-2);
+ this.onRowMouseOut(e);
+ }
+ },
+
+ onMouseDownRow: function(e){
+ // summary:
+ // Event fired when mouse is down inside grid row
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ if(e.rowIndex != -1)
+ this.onRowMouseDown(e);
+ },
+
+ // cell events
+ onCellMouseOver: function(e){
+ // summary:
+ // Event fired when mouse is over a cell.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ dojo.addClass(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onCellMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ dojo.removeClass(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onCellMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down in a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onCellClick: function(e){
+ // summary:
+ // Event fired when a cell is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this._click[0] = this._click[1];
+ this._click[1] = e;
+ if(!this.edit.isEditCell(e.rowIndex, e.cellIndex)){
+ this.focus.setFocusCell(e.cell, e.rowIndex);
+ }
+ this.onRowClick(e);
+ },
+
+ onCellDblClick: function(e){
+ // summary:
+ // Event fired when a cell is double-clicked.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(this._click.length > 1 && dojo.isIE){
+ this.edit.setEditCell(this._click[1].cell, this._click[1].rowIndex);
+ }else if(this._click.length > 1 && this._click[0].rowIndex != this._click[1].rowIndex){
+ this.edit.setEditCell(this._click[0].cell, this._click[0].rowIndex);
+ }else{
+ this.edit.setEditCell(e.cell, e.rowIndex);
+ }
+ this.onRowDblClick(e);
+ },
+
+ onCellContextMenu: function(e){
+ // summary:
+ // Event fired when a cell context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onRowContextMenu(e);
+ },
+
+ onCellFocus: function(inCell, inRowIndex){
+ // summary:
+ // Event fired when a cell receives focus.
+ // inCell: Object
+ // Cell object containing properties of the grid column.
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.edit.cellFocus(inCell, inRowIndex);
+ },
+
+ // row events
+ onRowClick: function(e){
+ // summary:
+ // Event fired when a row is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.edit.rowClick(e);
+ this.selection.clickSelectEvent(e);
+ },
+
+ onRowDblClick: function(e){
+ // summary:
+ // Event fired when a row is double clicked.
+ // e: Event
+ // decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over a data row.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a data row.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down in a row.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowContextMenu: function(e){
+ // summary:
+ // Event fired when a row context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ dojo.stopEvent(e);
+ },
+
+ // header events
+ onHeaderMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over the grid header.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of the grid header.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ dojo.addClass(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onHeaderCellMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ dojo.removeClass(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onHeaderCellMouseDown: function(e) {
+ // summary:
+ // Event fired when mouse is down in a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderClick: function(e){
+ // summary:
+ // Event fired when the grid header is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellClick: function(e){
+ // summary:
+ // Event fired when a header cell is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.setSortIndex(e.cell.index);
+ this.onHeaderClick(e);
+ },
+
+ onHeaderDblClick: function(e){
+ // summary:
+ // Event fired when the grid header is double clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellDblClick: function(e){
+ // summary:
+ // Event fired when a header cell is double clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onHeaderDblClick(e);
+ },
+
+ onHeaderCellContextMenu: function(e){
+ // summary:
+ // Event fired when a header cell context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onHeaderContextMenu(e);
+ },
+
+ onHeaderContextMenu: function(e){
+ // summary:
+ // Event fired when the grid header context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(!this.headerMenu){
+ dojo.stopEvent(e);
+ }
+ },
+
+ // editing
+ onStartEdit: function(inCell, inRowIndex){
+ // summary:
+ // Event fired when editing is started for a given grid cell
+ // inCell: Object
+ // Cell object containing properties of the grid column.
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
+ // summary:
+ // Event fired when editing is applied for a given grid cell
+ // inValue: String
+ // Value from cell editor
+ // inRowIndex: Integer
+ // Index of the grid row
+ // inFieldIndex: Integer
+ // Index in the grid's data store
+ },
+
+ onCancelEdit: function(inRowIndex){
+ // summary:
+ // Event fired when editing is cancelled for a given grid cell
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onApplyEdit: function(inRowIndex){
+ // summary:
+ // Event fired when editing is applied for a given grid row
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onCanSelect: function(inRowIndex){
+ // summary:
+ // Event to determine if a grid row may be selected
+ // inRowIndex: Integer
+ // Index of the grid row
+ // returns: Boolean
+ // true if the row can be selected
+ return true;
+ },
+
+ onCanDeselect: function(inRowIndex){
+ // summary:
+ // Event to determine if a grid row may be deselected
+ // inRowIndex: Integer
+ // Index of the grid row
+ // returns: Boolean
+ // true if the row can be deselected
+ return true;
+ },
+
+ onSelected: function(inRowIndex){
+ // summary:
+ // Event fired when a grid row is selected
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.updateRowStyles(inRowIndex);
+ },
+
+ onDeselected: function(inRowIndex){
+ // summary:
+ // Event fired when a grid row is deselected
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.updateRowStyles(inRowIndex);
+ },
+
+ onSelectionChanged: function(){
+ }
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/_Events.xd.js b/js/dojo-1.6/dojox/grid/_Events.xd.js
new file mode 100644
index 0000000..7d3359c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_Events.xd.js
@@ -0,0 +1,507 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid._Events"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid._Events"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Events"] = true;
+dojo.provide("dojox.grid._Events");
+
+dojo.declare("dojox.grid._Events", null, {
+ // summary:
+ // _Grid mixin that provides default implementations for grid events.
+ // description:
+ // Default synthetic events dispatched for _Grid. dojo.connect to events to
+ // retain default implementation or override them for custom handling.
+
+ // cellOverClass: String
+ // css class to apply to grid cells over which the cursor is placed.
+ cellOverClass: "dojoxGridCellOver",
+
+ onKeyEvent: function(e){
+ // summary: top level handler for Key Events
+ this.dispatchKeyEvent(e);
+ },
+
+ onContentEvent: function(e){
+ // summary: Top level handler for Content events
+ this.dispatchContentEvent(e);
+ },
+
+ onHeaderEvent: function(e){
+ // summary: Top level handler for header events
+ this.dispatchHeaderEvent(e);
+ },
+
+ onStyleRow: function(inRow){
+ // summary:
+ // Perform row styling on a given row. Called whenever row styling is updated.
+ //
+ // inRow: Object
+ // Object containing row state information: selected, true if the row is selcted; over:
+ // true of the mouse is over the row; odd: true if the row is odd. Use customClasses and
+ // customStyles to control row css classes and styles; both properties are strings.
+ //
+ // example: onStyleRow({ selected: true, over:true, odd:false })
+ var i = inRow;
+ i.customClasses += (i.odd?" dojoxGridRowOdd":"") + (i.selected?" dojoxGridRowSelected":"") + (i.over?" dojoxGridRowOver":"");
+ this.focus.styleRow(inRow);
+ this.edit.styleRow(inRow);
+ },
+
+ onKeyDown: function(e){
+ // summary:
+ // Grid key event handler. By default enter begins editing and applies edits, escape cancels an edit,
+ // tab, shift-tab, and arrow keys move grid cell focus.
+ if(e.altKey || e.metaKey){
+ return;
+ }
+ var dk = dojo.keys;
+ var colIdx;
+ switch(e.keyCode){
+ case dk.ESCAPE:
+ this.edit.cancel();
+ break;
+ case dk.ENTER:
+ if(!this.edit.isEditing()){
+ colIdx = this.focus.getHeaderIndex();
+ if(colIdx >= 0) {
+ this.setSortIndex(colIdx);
+ break;
+ }else {
+ this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ }
+ dojo.stopEvent(e);
+ }
+ if(!e.shiftKey){
+ var isEditing = this.edit.isEditing();
+ this.edit.apply();
+ if(!isEditing){
+ this.edit.setEditCell(this.focus.cell, this.focus.rowIndex);
+ }
+ }
+ if (!this.edit.isEditing()){
+ var curView = this.focus.focusView || this.views.views[0]; //if no focusView than only one view
+ curView.content.decorateEvent(e);
+ this.onRowClick(e);
+ }
+ break;
+ case dk.SPACE:
+ if(!this.edit.isEditing()){
+ colIdx = this.focus.getHeaderIndex();
+ if(colIdx >= 0) {
+ this.setSortIndex(colIdx);
+ break;
+ }else {
+ this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ }
+ dojo.stopEvent(e);
+ }
+ break;
+ case dk.TAB:
+ this.focus[e.shiftKey ? 'previousKey' : 'nextKey'](e);
+ break;
+ case dk.LEFT_ARROW:
+ case dk.RIGHT_ARROW:
+ if(!this.edit.isEditing()){
+ var keyCode = e.keyCode; // IE seems to lose after stopEvent when modifier keys
+ dojo.stopEvent(e);
+ colIdx = this.focus.getHeaderIndex();
+ if (colIdx >= 0 && (e.shiftKey && e.ctrlKey)){
+ this.focus.colSizeAdjust(e, colIdx, (keyCode == dk.LEFT_ARROW ? -1 : 1)*5);
+ }
+ else{
+ var offset = (keyCode == dk.LEFT_ARROW) ? 1 : -1;
+ if(dojo._isBodyLtr()){ offset *= -1; }
+ this.focus.move(0, offset);
+ }
+ }
+ break;
+ case dk.UP_ARROW:
+ if(!this.edit.isEditing() && this.focus.rowIndex !== 0){
+ dojo.stopEvent(e);
+ this.focus.move(-1, 0);
+ }
+ break;
+ case dk.DOWN_ARROW:
+ if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){
+ dojo.stopEvent(e);
+ this.focus.move(1, 0);
+ }
+ break;
+ case dk.PAGE_UP:
+ if(!this.edit.isEditing() && this.focus.rowIndex !== 0){
+ dojo.stopEvent(e);
+ if(this.focus.rowIndex != this.scroller.firstVisibleRow+1){
+ this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex, 0);
+ }else{
+ this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1));
+ this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1, 0);
+ }
+ }
+ break;
+ case dk.PAGE_DOWN:
+ if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){
+ dojo.stopEvent(e);
+ if(this.focus.rowIndex != this.scroller.lastVisibleRow-1){
+ this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1, 0);
+ }else{
+ this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1));
+ this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1, 0);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ },
+
+ onMouseOver: function(e){
+ // summary:
+ // Event fired when mouse is over the grid.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseOver(e) : this.onCellMouseOver(e);
+ },
+
+ onMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of the grid.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseOut(e) : this.onCellMouseOut(e);
+ },
+
+ onMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down inside grid.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseDown(e) : this.onCellMouseDown(e);
+ },
+
+ onMouseOverRow: function(e){
+ // summary:
+ // Event fired when mouse is over any row (data or header).
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(!this.rows.isOver(e.rowIndex)){
+ this.rows.setOverRow(e.rowIndex);
+ e.rowIndex == -1 ? this.onHeaderMouseOver(e) : this.onRowMouseOver(e);
+ }
+ },
+ onMouseOutRow: function(e){
+ // summary:
+ // Event fired when mouse moves out of any row (data or header).
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(this.rows.isOver(-1)){
+ this.onHeaderMouseOut(e);
+ }else if(!this.rows.isOver(-2)){
+ this.rows.setOverRow(-2);
+ this.onRowMouseOut(e);
+ }
+ },
+
+ onMouseDownRow: function(e){
+ // summary:
+ // Event fired when mouse is down inside grid row
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ if(e.rowIndex != -1)
+ this.onRowMouseDown(e);
+ },
+
+ // cell events
+ onCellMouseOver: function(e){
+ // summary:
+ // Event fired when mouse is over a cell.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ dojo.addClass(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onCellMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ dojo.removeClass(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onCellMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down in a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onCellClick: function(e){
+ // summary:
+ // Event fired when a cell is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this._click[0] = this._click[1];
+ this._click[1] = e;
+ if(!this.edit.isEditCell(e.rowIndex, e.cellIndex)){
+ this.focus.setFocusCell(e.cell, e.rowIndex);
+ }
+ this.onRowClick(e);
+ },
+
+ onCellDblClick: function(e){
+ // summary:
+ // Event fired when a cell is double-clicked.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(this._click.length > 1 && dojo.isIE){
+ this.edit.setEditCell(this._click[1].cell, this._click[1].rowIndex);
+ }else if(this._click.length > 1 && this._click[0].rowIndex != this._click[1].rowIndex){
+ this.edit.setEditCell(this._click[0].cell, this._click[0].rowIndex);
+ }else{
+ this.edit.setEditCell(e.cell, e.rowIndex);
+ }
+ this.onRowDblClick(e);
+ },
+
+ onCellContextMenu: function(e){
+ // summary:
+ // Event fired when a cell context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onRowContextMenu(e);
+ },
+
+ onCellFocus: function(inCell, inRowIndex){
+ // summary:
+ // Event fired when a cell receives focus.
+ // inCell: Object
+ // Cell object containing properties of the grid column.
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.edit.cellFocus(inCell, inRowIndex);
+ },
+
+ // row events
+ onRowClick: function(e){
+ // summary:
+ // Event fired when a row is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.edit.rowClick(e);
+ this.selection.clickSelectEvent(e);
+ },
+
+ onRowDblClick: function(e){
+ // summary:
+ // Event fired when a row is double clicked.
+ // e: Event
+ // decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over a data row.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a data row.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down in a row.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowContextMenu: function(e){
+ // summary:
+ // Event fired when a row context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ dojo.stopEvent(e);
+ },
+
+ // header events
+ onHeaderMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over the grid header.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of the grid header.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ dojo.addClass(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onHeaderCellMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ dojo.removeClass(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onHeaderCellMouseDown: function(e) {
+ // summary:
+ // Event fired when mouse is down in a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderClick: function(e){
+ // summary:
+ // Event fired when the grid header is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellClick: function(e){
+ // summary:
+ // Event fired when a header cell is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.setSortIndex(e.cell.index);
+ this.onHeaderClick(e);
+ },
+
+ onHeaderDblClick: function(e){
+ // summary:
+ // Event fired when the grid header is double clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellDblClick: function(e){
+ // summary:
+ // Event fired when a header cell is double clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onHeaderDblClick(e);
+ },
+
+ onHeaderCellContextMenu: function(e){
+ // summary:
+ // Event fired when a header cell context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onHeaderContextMenu(e);
+ },
+
+ onHeaderContextMenu: function(e){
+ // summary:
+ // Event fired when the grid header context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(!this.headerMenu){
+ dojo.stopEvent(e);
+ }
+ },
+
+ // editing
+ onStartEdit: function(inCell, inRowIndex){
+ // summary:
+ // Event fired when editing is started for a given grid cell
+ // inCell: Object
+ // Cell object containing properties of the grid column.
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
+ // summary:
+ // Event fired when editing is applied for a given grid cell
+ // inValue: String
+ // Value from cell editor
+ // inRowIndex: Integer
+ // Index of the grid row
+ // inFieldIndex: Integer
+ // Index in the grid's data store
+ },
+
+ onCancelEdit: function(inRowIndex){
+ // summary:
+ // Event fired when editing is cancelled for a given grid cell
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onApplyEdit: function(inRowIndex){
+ // summary:
+ // Event fired when editing is applied for a given grid row
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onCanSelect: function(inRowIndex){
+ // summary:
+ // Event to determine if a grid row may be selected
+ // inRowIndex: Integer
+ // Index of the grid row
+ // returns: Boolean
+ // true if the row can be selected
+ return true;
+ },
+
+ onCanDeselect: function(inRowIndex){
+ // summary:
+ // Event to determine if a grid row may be deselected
+ // inRowIndex: Integer
+ // Index of the grid row
+ // returns: Boolean
+ // true if the row can be deselected
+ return true;
+ },
+
+ onSelected: function(inRowIndex){
+ // summary:
+ // Event fired when a grid row is selected
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.updateRowStyles(inRowIndex);
+ },
+
+ onDeselected: function(inRowIndex){
+ // summary:
+ // Event fired when a grid row is deselected
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.updateRowStyles(inRowIndex);
+ },
+
+ onSelectionChanged: function(){
+ }
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/_FocusManager.js b/js/dojo-1.6/dojox/grid/_FocusManager.js
new file mode 100644
index 0000000..74a139f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_FocusManager.js
@@ -0,0 +1,612 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid._FocusManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._FocusManager"] = true;
+dojo.provide("dojox.grid._FocusManager");
+
+dojo.require("dojox.grid.util");
+
+// focus management
+dojo.declare("dojox.grid._FocusManager", null, {
+ // summary:
+ // Controls grid cell focus. Owned by grid and used internally for focusing.
+ // Note: grid cell actually receives keyboard input only when cell is being edited.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ this.cell = null;
+ this.rowIndex = -1;
+ this._connects = [];
+ this._headerConnects = [];
+ this.headerMenu = this.grid.headerMenu;
+ this._connects.push(dojo.connect(this.grid.domNode, "onfocus", this, "doFocus"));
+ this._connects.push(dojo.connect(this.grid.domNode, "onblur", this, "doBlur"));
+ this._connects.push(dojo.connect(this.grid.domNode, "oncontextmenu", this, "doContextMenu"));
+ this._connects.push(dojo.connect(this.grid.lastFocusNode, "onfocus", this, "doLastNodeFocus"));
+ this._connects.push(dojo.connect(this.grid.lastFocusNode, "onblur", this, "doLastNodeBlur"));
+ this._connects.push(dojo.connect(this.grid,"_onFetchComplete", this, "_delayedCellFocus"));
+ this._connects.push(dojo.connect(this.grid,"postrender", this, "_delayedHeaderFocus"));
+ },
+ destroy: function(){
+ dojo.forEach(this._connects, dojo.disconnect);
+ dojo.forEach(this._headerConnects, dojo.disconnect);
+ delete this.grid;
+ delete this.cell;
+ },
+ _colHeadNode: null,
+ _colHeadFocusIdx: null,
+ _contextMenuBindNode: null,
+ tabbingOut: false,
+ focusClass: "dojoxGridCellFocus",
+ focusView: null,
+ initFocusView: function(){
+ this.focusView = this.grid.views.getFirstScrollingView() || this.focusView || this.grid.views.views[0];
+ this._initColumnHeaders();
+ },
+ isFocusCell: function(inCell, inRowIndex){
+ // summary:
+ // states if the given cell is focused
+ // inCell: object
+ // grid cell object
+ // inRowIndex: int
+ // grid row index
+ // returns:
+ // true of the given grid cell is focused
+ return (this.cell == inCell) && (this.rowIndex == inRowIndex);
+ },
+ isLastFocusCell: function(){
+ if(this.cell){
+ return (this.rowIndex == this.grid.rowCount-1) && (this.cell.index == this.grid.layout.cellCount-1);
+ }
+ return false;
+ },
+ isFirstFocusCell: function(){
+ if(this.cell){
+ return (this.rowIndex === 0) && (this.cell.index === 0);
+ }
+ return false;
+ },
+ isNoFocusCell: function(){
+ return (this.rowIndex < 0) || !this.cell;
+ },
+ isNavHeader: function(){
+ // summary:
+ // states whether currently navigating among column headers.
+ // returns:
+ // true if focus is on a column header; false otherwise.
+ return (!!this._colHeadNode);
+ },
+ getHeaderIndex: function(){
+ // summary:
+ // if one of the column headers currently has focus, return its index.
+ // returns:
+ // index of the focused column header, or -1 if none have focus.
+ if(this._colHeadNode){
+ return dojo.indexOf(this._findHeaderCells(), this._colHeadNode);
+ }else{
+ return -1;
+ }
+ },
+ _focusifyCellNode: function(inBork){
+ var n = this.cell && this.cell.getNode(this.rowIndex);
+ if(n){
+ dojo.toggleClass(n, this.focusClass, inBork);
+ if(inBork){
+ var sl = this.scrollIntoView();
+ try{
+ if(!this.grid.edit.isEditing()){
+ dojox.grid.util.fire(n, "focus");
+ if(sl){ this.cell.view.scrollboxNode.scrollLeft = sl; }
+ }
+ }catch(e){}
+ }
+ }
+ },
+ _delayedCellFocus: function(){
+ if(this.isNavHeader()||!this.grid._focused){
+ return;
+ }
+ var n = this.cell && this.cell.getNode(this.rowIndex);
+ if(n){
+ try{
+ if(!this.grid.edit.isEditing()){
+ dojo.toggleClass(n, this.focusClass, true);
+ this.blurHeader();
+ dojox.grid.util.fire(n, "focus");
+ }
+ }
+ catch(e){}
+ }
+ },
+ _delayedHeaderFocus: function(){
+ if(this.isNavHeader()){
+ this.focusHeader();
+ this.grid.domNode.focus();
+ }
+ },
+ _initColumnHeaders: function(){
+ dojo.forEach(this._headerConnects, dojo.disconnect);
+ this._headerConnects = [];
+ var headers = this._findHeaderCells();
+ for(var i = 0; i < headers.length; i++){
+ this._headerConnects.push(dojo.connect(headers[i], "onfocus", this, "doColHeaderFocus"));
+ this._headerConnects.push(dojo.connect(headers[i], "onblur", this, "doColHeaderBlur"));
+ }
+ },
+ _findHeaderCells: function(){
+ // This should be a one liner:
+ // dojo.query("th[tabindex=-1]", this.grid.viewsHeaderNode);
+ // But there is a bug in dojo.query() for IE -- see trac #7037.
+ var allHeads = dojo.query("th", this.grid.viewsHeaderNode);
+ var headers = [];
+ for (var i = 0; i < allHeads.length; i++){
+ var aHead = allHeads[i];
+ var hasTabIdx = dojo.hasAttr(aHead, "tabIndex");
+ var tabindex = dojo.attr(aHead, "tabIndex");
+ if (hasTabIdx && tabindex < 0) {
+ headers.push(aHead);
+ }
+ }
+ return headers;
+ },
+ _setActiveColHeader: function(/*Node*/colHeaderNode, /*Integer*/colFocusIdx, /*Integer*/ prevColFocusIdx){
+ //console.log("setActiveColHeader() - colHeaderNode:colFocusIdx:prevColFocusIdx = " + colHeaderNode + ":" + colFocusIdx + ":" + prevColFocusIdx);
+ dojo.attr(this.grid.domNode, "aria-activedescendant",colHeaderNode.id);
+ if (prevColFocusIdx != null && prevColFocusIdx >= 0 && prevColFocusIdx != colFocusIdx){
+ dojo.toggleClass(this._findHeaderCells()[prevColFocusIdx],this.focusClass,false);
+ }
+ dojo.toggleClass(colHeaderNode,this.focusClass, true);
+ this._colHeadNode = colHeaderNode;
+ this._colHeadFocusIdx = colFocusIdx;
+ this._scrollHeader(this._colHeadFocusIdx);
+ },
+ scrollIntoView: function(){
+ var info = (this.cell ? this._scrollInfo(this.cell) : null);
+ if(!info || !info.s){
+ return null;
+ }
+ var rt = this.grid.scroller.findScrollTop(this.rowIndex);
+ // place cell within horizontal view
+ if(info.n && info.sr){
+ if(info.n.offsetLeft + info.n.offsetWidth > info.sr.l + info.sr.w){
+ info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w;
+ }else if(info.n.offsetLeft < info.sr.l){
+ info.s.scrollLeft = info.n.offsetLeft;
+ }
+ }
+ // place cell within vertical view
+ if(info.r && info.sr){
+ if(rt + info.r.offsetHeight > info.sr.t + info.sr.h){
+ this.grid.setScrollTop(rt + info.r.offsetHeight - info.sr.h);
+ }else if(rt < info.sr.t){
+ this.grid.setScrollTop(rt);
+ }
+ }
+
+ return info.s.scrollLeft;
+ },
+ _scrollInfo: function(cell, domNode){
+ if(cell){
+ var cl = cell,
+ sbn = cl.view.scrollboxNode,
+ sbnr = {
+ w: sbn.clientWidth,
+ l: sbn.scrollLeft,
+ t: sbn.scrollTop,
+ h: sbn.clientHeight
+ },
+ rn = cl.view.getRowNode(this.rowIndex);
+ return {
+ c: cl,
+ s: sbn,
+ sr: sbnr,
+ n: (domNode ? domNode : cell.getNode(this.rowIndex)),
+ r: rn
+ };
+ }
+ return null;
+ },
+ _scrollHeader: function(currentIdx){
+ var info = null;
+ if(this._colHeadNode){
+ var cell = this.grid.getCell(currentIdx);
+ info = this._scrollInfo(cell, cell.getNode(0));
+ }
+ if(info && info.s && info.sr && info.n){
+ // scroll horizontally as needed.
+ var scroll = info.sr.l + info.sr.w;
+ if(info.n.offsetLeft + info.n.offsetWidth > scroll){
+ info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w;
+ }else if(info.n.offsetLeft < info.sr.l){
+ info.s.scrollLeft = info.n.offsetLeft;
+ }else if(dojo.isIE <= 7 && cell && cell.view.headerNode){
+ // Trac 7158: scroll dojoxGridHeader for IE7 and lower
+ cell.view.headerNode.scrollLeft = info.s.scrollLeft;
+ }
+ }
+ },
+ _isHeaderHidden: function(){
+ // summary:
+ // determine if the grid headers are hidden
+ // relies on documented technique of setting .dojoxGridHeader { display:none; }
+ // returns: Boolean
+ // true if headers are hidden
+ // false if headers are not hidden
+
+ var curView = this.focusView;
+ if (!curView){
+ // find one so we can determine if headers are hidden
+ // there is no focusView after adding items to empty grid (test_data_grid_empty.html)
+ for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) {
+ if(cView.headerNode ){
+ curView=cView;
+ break;
+ }
+ }
+ }
+ return (curView && dojo.getComputedStyle(curView.headerNode).display == "none");
+ },
+ colSizeAdjust: function (e, colIdx, delta){ // adjust the column specified by colIdx by the specified delta px
+ var headers = this._findHeaderCells();
+ var view = this.focusView;
+ if (!view) {
+ for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) {
+ // find first view with a tableMap in order to work with empty grid
+ if(cView.header.tableMap.map ){
+ view=cView;
+ break;
+ }
+ }
+ }
+ var curHeader = headers[colIdx];
+ if (!view || (colIdx == headers.length-1 && colIdx === 0)){
+ return; // can't adjust single col. grid
+ }
+ view.content.baseDecorateEvent(e);
+ // need to adjust event with header cell info since focus is no longer on header cell
+ e.cellNode = curHeader; //this.findCellTarget(e.target, e.rowNode);
+ e.cellIndex = view.content.getCellNodeIndex(e.cellNode);
+ e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null);
+ if (view.header.canResize(e)){
+ var deltaObj = {
+ l: delta
+ };
+ var drag = view.header.colResizeSetup(e,false);
+ view.header.doResizeColumn(drag, null, deltaObj);
+ view.update();
+ }
+ },
+ styleRow: function(inRow){
+ return;
+ },
+ setFocusIndex: function(inRowIndex, inCellIndex){
+ // summary:
+ // focuses the given grid cell
+ // inRowIndex: int
+ // grid row index
+ // inCellIndex: int
+ // grid cell index
+ this.setFocusCell(this.grid.getCell(inCellIndex), inRowIndex);
+ },
+ setFocusCell: function(inCell, inRowIndex){
+ // summary:
+ // focuses the given grid cell
+ // inCell: object
+ // grid cell object
+ // inRowIndex: int
+ // grid row index
+ if(inCell && !this.isFocusCell(inCell, inRowIndex)){
+ this.tabbingOut = false;
+ if (this._colHeadNode){
+ this.blurHeader();
+ }
+ this._colHeadNode = this._colHeadFocusIdx = null;
+ this.focusGridView();
+ this._focusifyCellNode(false);
+ this.cell = inCell;
+ this.rowIndex = inRowIndex;
+ this._focusifyCellNode(true);
+ }
+ // even if this cell isFocusCell, the document focus may need to be rejiggered
+ // call opera on delay to prevent keypress from altering focus
+ if(dojo.isOpera){
+ setTimeout(dojo.hitch(this.grid, 'onCellFocus', this.cell, this.rowIndex), 1);
+ }else{
+ this.grid.onCellFocus(this.cell, this.rowIndex);
+ }
+ },
+ next: function(){
+ // summary:
+ // focus next grid cell
+ if(this.cell){
+ var row=this.rowIndex, col=this.cell.index+1, cc=this.grid.layout.cellCount-1, rc=this.grid.rowCount-1;
+ if(col > cc){
+ col = 0;
+ row++;
+ }
+ if(row > rc){
+ col = cc;
+ row = rc;
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var nextCell = this.grid.getCell(col);
+ if (!this.isLastFocusCell() && (!nextCell.editable ||
+ this.grid.canEdit && !this.grid.canEdit(nextCell, row))){
+ this.cell=nextCell;
+ this.rowIndex=row;
+ this.next();
+ return;
+ }
+ }
+ this.setFocusIndex(row, col);
+ }
+ },
+ previous: function(){
+ // summary:
+ // focus previous grid cell
+ if(this.cell){
+ var row=(this.rowIndex || 0), col=(this.cell.index || 0) - 1;
+ if(col < 0){
+ col = this.grid.layout.cellCount-1;
+ row--;
+ }
+ if(row < 0){
+ row = 0;
+ col = 0;
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var prevCell = this.grid.getCell(col);
+ if (!this.isFirstFocusCell() && !prevCell.editable){
+ this.cell=prevCell;
+ this.rowIndex=row;
+ this.previous();
+ return;
+ }
+ }
+ this.setFocusIndex(row, col);
+ }
+ },
+ move: function(inRowDelta, inColDelta) {
+ // summary:
+ // focus grid cell or simulate focus to column header based on position relative to current focus
+ // inRowDelta: int
+ // vertical distance from current focus
+ // inColDelta: int
+ // horizontal distance from current focus
+
+ var colDir = inColDelta < 0 ? -1 : 1;
+ // Handle column headers.
+ if(this.isNavHeader()){
+ var headers = this._findHeaderCells();
+ var savedIdx = currentIdx = dojo.indexOf(headers, this._colHeadNode);
+ currentIdx += inColDelta;
+ while(currentIdx >=0 && currentIdx < headers.length && headers[currentIdx].style.display == "none"){
+ // skip over hidden column headers
+ currentIdx += colDir;
+ }
+ if((currentIdx >= 0) && (currentIdx < headers.length)){
+ this._setActiveColHeader(headers[currentIdx],currentIdx, savedIdx);
+ }
+ }else{
+ if(this.cell){
+ // Handle grid proper.
+ var sc = this.grid.scroller,
+ r = this.rowIndex,
+ rc = this.grid.rowCount-1,
+ row = Math.min(rc, Math.max(0, r+inRowDelta));
+ if(inRowDelta){
+ if(inRowDelta>0){
+ if(row > sc.getLastPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r));
+ }
+ }else if(inRowDelta<0){
+ if(row <= sc.getPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row));
+ }
+ }
+ }
+ var cc = this.grid.layout.cellCount-1,
+ i = this.cell.index,
+ col = Math.min(cc, Math.max(0, i+inColDelta));
+ var cell = this.grid.getCell(col);
+ while(col>=0 && col < cc && cell && cell.hidden === true){
+ // skip hidden cells
+ col += colDir;
+ cell = this.grid.getCell(col);
+ }
+ if (!cell || cell.hidden === true){
+ // don't change col if would move to hidden
+ col = i;
+ }
+ this.setFocusIndex(row, col);
+ if(inRowDelta){
+ this.grid.updateRow(r);
+ }
+ }
+ }
+ },
+ previousKey: function(e){
+ if(this.grid.edit.isEditing()){
+ dojo.stopEvent(e);
+ this.previous();
+ }else if(!this.isNavHeader() && !this._isHeaderHidden()) {
+ this.grid.domNode.focus(); // will call doFocus and set focus into header.
+ dojo.stopEvent(e);
+ }else{
+ this.tabOut(this.grid.domNode);
+ if (this._colHeadFocusIdx != null) { // clear grid header focus
+ dojo.toggleClass(this._findHeaderCells()[this._colHeadFocusIdx], this.focusClass, false);
+ this._colHeadFocusIdx = null;
+ }
+ this._focusifyCellNode(false);
+ }
+ },
+ nextKey: function(e) {
+ var isEmpty = (this.grid.rowCount === 0);
+ if(e.target === this.grid.domNode && this._colHeadFocusIdx == null){
+ this.focusHeader();
+ dojo.stopEvent(e);
+ }else if(this.isNavHeader()){
+ // if tabbing from col header, then go to grid proper.
+ this.blurHeader();
+ if(!this.findAndFocusGridCell()){
+ this.tabOut(this.grid.lastFocusNode);
+ }
+ this._colHeadNode = this._colHeadFocusIdx= null;
+ }else if(this.grid.edit.isEditing()){
+ dojo.stopEvent(e);
+ this.next();
+ }else{
+ this.tabOut(this.grid.lastFocusNode);
+ }
+ },
+ tabOut: function(inFocusNode){
+ this.tabbingOut = true;
+ inFocusNode.focus();
+ },
+ focusGridView: function(){
+ dojox.grid.util.fire(this.focusView, "focus");
+ },
+ focusGrid: function(inSkipFocusCell){
+ this.focusGridView();
+ this._focusifyCellNode(true);
+ },
+ findAndFocusGridCell: function(){
+ // summary:
+ // find the first focusable grid cell
+ // returns: Boolean
+ // true if focus was set to a cell
+ // false if no cell found to set focus onto
+
+ var didFocus = true;
+ var isEmpty = (this.grid.rowCount === 0); // If grid is empty this.grid.rowCount == 0
+ if (this.isNoFocusCell() && !isEmpty){
+ var cellIdx = 0;
+ var cell = this.grid.getCell(cellIdx);
+ if (cell.hidden) {
+ // if first cell isn't visible, use _colHeadFocusIdx
+ // could also use a while loop to find first visible cell - not sure that is worth it
+ cellIdx = this.isNavHeader() ? this._colHeadFocusIdx : 0;
+ }
+ this.setFocusIndex(0, cellIdx);
+ }
+ else if (this.cell && !isEmpty){
+ if (this.focusView && !this.focusView.rowNodes[this.rowIndex]){
+ // if rowNode for current index is undefined (likely as a result of a sort and because of #7304)
+ // scroll to that row
+ this.grid.scrollToRow(this.rowIndex);
+ }
+ this.focusGrid();
+ }else {
+ didFocus = false;
+ }
+ this._colHeadNode = this._colHeadFocusIdx= null;
+ return didFocus;
+ },
+ focusHeader: function(){
+ var headerNodes = this._findHeaderCells();
+ var saveColHeadFocusIdx = this._colHeadFocusIdx;
+ if (this._isHeaderHidden()){
+ // grid header is hidden, focus a cell
+ this.findAndFocusGridCell();
+ }
+ else if (!this._colHeadFocusIdx) {
+ if (this.isNoFocusCell()) {
+ this._colHeadFocusIdx = 0;
+ }
+ else {
+ this._colHeadFocusIdx = this.cell.index;
+ }
+ }
+ this._colHeadNode = headerNodes[this._colHeadFocusIdx];
+ while(this._colHeadNode && this._colHeadFocusIdx >=0 && this._colHeadFocusIdx < headerNodes.length &&
+ this._colHeadNode.style.display == "none"){
+ // skip over hidden column headers
+ this._colHeadFocusIdx++;
+ this._colHeadNode = headerNodes[this._colHeadFocusIdx];
+ }
+ if(this._colHeadNode && this._colHeadNode.style.display != "none"){
+ // Column header cells know longer receive actual focus. So, for keyboard invocation of
+ // contextMenu to work, the contextMenu must be bound to the grid.domNode rather than the viewsHeaderNode.
+ // unbind the contextmenu from the viewsHeaderNode and to the grid when header cells are active. Reset
+ // the binding back to the viewsHeaderNode when header cells are no longer acive (in blurHeader) #10483
+ if (this.headerMenu && this._contextMenuBindNode != this.grid.domNode){
+ this.headerMenu.unBindDomNode(this.grid.viewsHeaderNode);
+ this.headerMenu.bindDomNode(this.grid.domNode);
+ this._contextMenuBindNode = this.grid.domNode;
+ }
+ this._setActiveColHeader(this._colHeadNode, this._colHeadFocusIdx, saveColHeadFocusIdx);
+ this._scrollHeader(this._colHeadFocusIdx);
+ this._focusifyCellNode(false);
+ }else {
+ // all col head nodes are hidden - focus the grid
+ this.findAndFocusGridCell();
+ }
+ },
+ blurHeader: function(){
+ dojo.removeClass(this._colHeadNode, this.focusClass);
+ dojo.removeAttr(this.grid.domNode,"aria-activedescendant");
+ // reset contextMenu onto viewsHeaderNode so right mouse on header will invoke (see focusHeader)
+ if (this.headerMenu && this._contextMenuBindNode == this.grid.domNode) {
+ var viewsHeader = this.grid.viewsHeaderNode;
+ this.headerMenu.unBindDomNode(this.grid.domNode);
+ this.headerMenu.bindDomNode(viewsHeader);
+ this._contextMenuBindNode = viewsHeader;
+ }
+ },
+ doFocus: function(e){
+ // trap focus only for grid dom node
+ if(e && e.target != e.currentTarget){
+ dojo.stopEvent(e);
+ return;
+ }
+ // do not focus for scrolling if grid is about to blur
+ if(!this.tabbingOut){
+ this.focusHeader();
+ }
+ this.tabbingOut = false;
+ dojo.stopEvent(e);
+ },
+ doBlur: function(e){
+ dojo.stopEvent(e); // FF2
+ },
+ doContextMenu: function(e){
+ //stop contextMenu event if no header Menu to prevent default/browser contextMenu
+ if (!this.headerMenu){
+ dojo.stopEvent(e);
+ }
+ },
+ doLastNodeFocus: function(e){
+ if (this.tabbingOut){
+ this._focusifyCellNode(false);
+ }else if(this.grid.rowCount >0){
+ if (this.isNoFocusCell()){
+ this.setFocusIndex(0,0);
+ }
+ this._focusifyCellNode(true);
+ }else {
+ this.focusHeader();
+ }
+ this.tabbingOut = false;
+ dojo.stopEvent(e); // FF2
+ },
+ doLastNodeBlur: function(e){
+ dojo.stopEvent(e); // FF2
+ },
+ doColHeaderFocus: function(e){
+ this._setActiveColHeader(e.target,dojo.attr(e.target, "idx"),this._colHeadFocusIdx);
+ this._scrollHeader(this.getHeaderIndex());
+ dojo.stopEvent(e);
+ },
+ doColHeaderBlur: function(e){
+ dojo.toggleClass(e.target, this.focusClass, false);
+ }
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/_FocusManager.xd.js b/js/dojo-1.6/dojox/grid/_FocusManager.xd.js
new file mode 100644
index 0000000..d8783da
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_FocusManager.xd.js
@@ -0,0 +1,617 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid._FocusManager"],
+["require", "dojox.grid.util"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid._FocusManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._FocusManager"] = true;
+dojo.provide("dojox.grid._FocusManager");
+
+dojo.require("dojox.grid.util");
+
+// focus management
+dojo.declare("dojox.grid._FocusManager", null, {
+ // summary:
+ // Controls grid cell focus. Owned by grid and used internally for focusing.
+ // Note: grid cell actually receives keyboard input only when cell is being edited.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ this.cell = null;
+ this.rowIndex = -1;
+ this._connects = [];
+ this._headerConnects = [];
+ this.headerMenu = this.grid.headerMenu;
+ this._connects.push(dojo.connect(this.grid.domNode, "onfocus", this, "doFocus"));
+ this._connects.push(dojo.connect(this.grid.domNode, "onblur", this, "doBlur"));
+ this._connects.push(dojo.connect(this.grid.domNode, "oncontextmenu", this, "doContextMenu"));
+ this._connects.push(dojo.connect(this.grid.lastFocusNode, "onfocus", this, "doLastNodeFocus"));
+ this._connects.push(dojo.connect(this.grid.lastFocusNode, "onblur", this, "doLastNodeBlur"));
+ this._connects.push(dojo.connect(this.grid,"_onFetchComplete", this, "_delayedCellFocus"));
+ this._connects.push(dojo.connect(this.grid,"postrender", this, "_delayedHeaderFocus"));
+ },
+ destroy: function(){
+ dojo.forEach(this._connects, dojo.disconnect);
+ dojo.forEach(this._headerConnects, dojo.disconnect);
+ delete this.grid;
+ delete this.cell;
+ },
+ _colHeadNode: null,
+ _colHeadFocusIdx: null,
+ _contextMenuBindNode: null,
+ tabbingOut: false,
+ focusClass: "dojoxGridCellFocus",
+ focusView: null,
+ initFocusView: function(){
+ this.focusView = this.grid.views.getFirstScrollingView() || this.focusView || this.grid.views.views[0];
+ this._initColumnHeaders();
+ },
+ isFocusCell: function(inCell, inRowIndex){
+ // summary:
+ // states if the given cell is focused
+ // inCell: object
+ // grid cell object
+ // inRowIndex: int
+ // grid row index
+ // returns:
+ // true of the given grid cell is focused
+ return (this.cell == inCell) && (this.rowIndex == inRowIndex);
+ },
+ isLastFocusCell: function(){
+ if(this.cell){
+ return (this.rowIndex == this.grid.rowCount-1) && (this.cell.index == this.grid.layout.cellCount-1);
+ }
+ return false;
+ },
+ isFirstFocusCell: function(){
+ if(this.cell){
+ return (this.rowIndex === 0) && (this.cell.index === 0);
+ }
+ return false;
+ },
+ isNoFocusCell: function(){
+ return (this.rowIndex < 0) || !this.cell;
+ },
+ isNavHeader: function(){
+ // summary:
+ // states whether currently navigating among column headers.
+ // returns:
+ // true if focus is on a column header; false otherwise.
+ return (!!this._colHeadNode);
+ },
+ getHeaderIndex: function(){
+ // summary:
+ // if one of the column headers currently has focus, return its index.
+ // returns:
+ // index of the focused column header, or -1 if none have focus.
+ if(this._colHeadNode){
+ return dojo.indexOf(this._findHeaderCells(), this._colHeadNode);
+ }else{
+ return -1;
+ }
+ },
+ _focusifyCellNode: function(inBork){
+ var n = this.cell && this.cell.getNode(this.rowIndex);
+ if(n){
+ dojo.toggleClass(n, this.focusClass, inBork);
+ if(inBork){
+ var sl = this.scrollIntoView();
+ try{
+ if(!this.grid.edit.isEditing()){
+ dojox.grid.util.fire(n, "focus");
+ if(sl){ this.cell.view.scrollboxNode.scrollLeft = sl; }
+ }
+ }catch(e){}
+ }
+ }
+ },
+ _delayedCellFocus: function(){
+ if(this.isNavHeader()||!this.grid._focused){
+ return;
+ }
+ var n = this.cell && this.cell.getNode(this.rowIndex);
+ if(n){
+ try{
+ if(!this.grid.edit.isEditing()){
+ dojo.toggleClass(n, this.focusClass, true);
+ this.blurHeader();
+ dojox.grid.util.fire(n, "focus");
+ }
+ }
+ catch(e){}
+ }
+ },
+ _delayedHeaderFocus: function(){
+ if(this.isNavHeader()){
+ this.focusHeader();
+ this.grid.domNode.focus();
+ }
+ },
+ _initColumnHeaders: function(){
+ dojo.forEach(this._headerConnects, dojo.disconnect);
+ this._headerConnects = [];
+ var headers = this._findHeaderCells();
+ for(var i = 0; i < headers.length; i++){
+ this._headerConnects.push(dojo.connect(headers[i], "onfocus", this, "doColHeaderFocus"));
+ this._headerConnects.push(dojo.connect(headers[i], "onblur", this, "doColHeaderBlur"));
+ }
+ },
+ _findHeaderCells: function(){
+ // This should be a one liner:
+ // dojo.query("th[tabindex=-1]", this.grid.viewsHeaderNode);
+ // But there is a bug in dojo.query() for IE -- see trac #7037.
+ var allHeads = dojo.query("th", this.grid.viewsHeaderNode);
+ var headers = [];
+ for (var i = 0; i < allHeads.length; i++){
+ var aHead = allHeads[i];
+ var hasTabIdx = dojo.hasAttr(aHead, "tabIndex");
+ var tabindex = dojo.attr(aHead, "tabIndex");
+ if (hasTabIdx && tabindex < 0) {
+ headers.push(aHead);
+ }
+ }
+ return headers;
+ },
+ _setActiveColHeader: function(/*Node*/colHeaderNode, /*Integer*/colFocusIdx, /*Integer*/ prevColFocusIdx){
+ //console.log("setActiveColHeader() - colHeaderNode:colFocusIdx:prevColFocusIdx = " + colHeaderNode + ":" + colFocusIdx + ":" + prevColFocusIdx);
+ dojo.attr(this.grid.domNode, "aria-activedescendant",colHeaderNode.id);
+ if (prevColFocusIdx != null && prevColFocusIdx >= 0 && prevColFocusIdx != colFocusIdx){
+ dojo.toggleClass(this._findHeaderCells()[prevColFocusIdx],this.focusClass,false);
+ }
+ dojo.toggleClass(colHeaderNode,this.focusClass, true);
+ this._colHeadNode = colHeaderNode;
+ this._colHeadFocusIdx = colFocusIdx;
+ this._scrollHeader(this._colHeadFocusIdx);
+ },
+ scrollIntoView: function(){
+ var info = (this.cell ? this._scrollInfo(this.cell) : null);
+ if(!info || !info.s){
+ return null;
+ }
+ var rt = this.grid.scroller.findScrollTop(this.rowIndex);
+ // place cell within horizontal view
+ if(info.n && info.sr){
+ if(info.n.offsetLeft + info.n.offsetWidth > info.sr.l + info.sr.w){
+ info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w;
+ }else if(info.n.offsetLeft < info.sr.l){
+ info.s.scrollLeft = info.n.offsetLeft;
+ }
+ }
+ // place cell within vertical view
+ if(info.r && info.sr){
+ if(rt + info.r.offsetHeight > info.sr.t + info.sr.h){
+ this.grid.setScrollTop(rt + info.r.offsetHeight - info.sr.h);
+ }else if(rt < info.sr.t){
+ this.grid.setScrollTop(rt);
+ }
+ }
+
+ return info.s.scrollLeft;
+ },
+ _scrollInfo: function(cell, domNode){
+ if(cell){
+ var cl = cell,
+ sbn = cl.view.scrollboxNode,
+ sbnr = {
+ w: sbn.clientWidth,
+ l: sbn.scrollLeft,
+ t: sbn.scrollTop,
+ h: sbn.clientHeight
+ },
+ rn = cl.view.getRowNode(this.rowIndex);
+ return {
+ c: cl,
+ s: sbn,
+ sr: sbnr,
+ n: (domNode ? domNode : cell.getNode(this.rowIndex)),
+ r: rn
+ };
+ }
+ return null;
+ },
+ _scrollHeader: function(currentIdx){
+ var info = null;
+ if(this._colHeadNode){
+ var cell = this.grid.getCell(currentIdx);
+ info = this._scrollInfo(cell, cell.getNode(0));
+ }
+ if(info && info.s && info.sr && info.n){
+ // scroll horizontally as needed.
+ var scroll = info.sr.l + info.sr.w;
+ if(info.n.offsetLeft + info.n.offsetWidth > scroll){
+ info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w;
+ }else if(info.n.offsetLeft < info.sr.l){
+ info.s.scrollLeft = info.n.offsetLeft;
+ }else if(dojo.isIE <= 7 && cell && cell.view.headerNode){
+ // Trac 7158: scroll dojoxGridHeader for IE7 and lower
+ cell.view.headerNode.scrollLeft = info.s.scrollLeft;
+ }
+ }
+ },
+ _isHeaderHidden: function(){
+ // summary:
+ // determine if the grid headers are hidden
+ // relies on documented technique of setting .dojoxGridHeader { display:none; }
+ // returns: Boolean
+ // true if headers are hidden
+ // false if headers are not hidden
+
+ var curView = this.focusView;
+ if (!curView){
+ // find one so we can determine if headers are hidden
+ // there is no focusView after adding items to empty grid (test_data_grid_empty.html)
+ for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) {
+ if(cView.headerNode ){
+ curView=cView;
+ break;
+ }
+ }
+ }
+ return (curView && dojo.getComputedStyle(curView.headerNode).display == "none");
+ },
+ colSizeAdjust: function (e, colIdx, delta){ // adjust the column specified by colIdx by the specified delta px
+ var headers = this._findHeaderCells();
+ var view = this.focusView;
+ if (!view) {
+ for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) {
+ // find first view with a tableMap in order to work with empty grid
+ if(cView.header.tableMap.map ){
+ view=cView;
+ break;
+ }
+ }
+ }
+ var curHeader = headers[colIdx];
+ if (!view || (colIdx == headers.length-1 && colIdx === 0)){
+ return; // can't adjust single col. grid
+ }
+ view.content.baseDecorateEvent(e);
+ // need to adjust event with header cell info since focus is no longer on header cell
+ e.cellNode = curHeader; //this.findCellTarget(e.target, e.rowNode);
+ e.cellIndex = view.content.getCellNodeIndex(e.cellNode);
+ e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null);
+ if (view.header.canResize(e)){
+ var deltaObj = {
+ l: delta
+ };
+ var drag = view.header.colResizeSetup(e,false);
+ view.header.doResizeColumn(drag, null, deltaObj);
+ view.update();
+ }
+ },
+ styleRow: function(inRow){
+ return;
+ },
+ setFocusIndex: function(inRowIndex, inCellIndex){
+ // summary:
+ // focuses the given grid cell
+ // inRowIndex: int
+ // grid row index
+ // inCellIndex: int
+ // grid cell index
+ this.setFocusCell(this.grid.getCell(inCellIndex), inRowIndex);
+ },
+ setFocusCell: function(inCell, inRowIndex){
+ // summary:
+ // focuses the given grid cell
+ // inCell: object
+ // grid cell object
+ // inRowIndex: int
+ // grid row index
+ if(inCell && !this.isFocusCell(inCell, inRowIndex)){
+ this.tabbingOut = false;
+ if (this._colHeadNode){
+ this.blurHeader();
+ }
+ this._colHeadNode = this._colHeadFocusIdx = null;
+ this.focusGridView();
+ this._focusifyCellNode(false);
+ this.cell = inCell;
+ this.rowIndex = inRowIndex;
+ this._focusifyCellNode(true);
+ }
+ // even if this cell isFocusCell, the document focus may need to be rejiggered
+ // call opera on delay to prevent keypress from altering focus
+ if(dojo.isOpera){
+ setTimeout(dojo.hitch(this.grid, 'onCellFocus', this.cell, this.rowIndex), 1);
+ }else{
+ this.grid.onCellFocus(this.cell, this.rowIndex);
+ }
+ },
+ next: function(){
+ // summary:
+ // focus next grid cell
+ if(this.cell){
+ var row=this.rowIndex, col=this.cell.index+1, cc=this.grid.layout.cellCount-1, rc=this.grid.rowCount-1;
+ if(col > cc){
+ col = 0;
+ row++;
+ }
+ if(row > rc){
+ col = cc;
+ row = rc;
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var nextCell = this.grid.getCell(col);
+ if (!this.isLastFocusCell() && (!nextCell.editable ||
+ this.grid.canEdit && !this.grid.canEdit(nextCell, row))){
+ this.cell=nextCell;
+ this.rowIndex=row;
+ this.next();
+ return;
+ }
+ }
+ this.setFocusIndex(row, col);
+ }
+ },
+ previous: function(){
+ // summary:
+ // focus previous grid cell
+ if(this.cell){
+ var row=(this.rowIndex || 0), col=(this.cell.index || 0) - 1;
+ if(col < 0){
+ col = this.grid.layout.cellCount-1;
+ row--;
+ }
+ if(row < 0){
+ row = 0;
+ col = 0;
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var prevCell = this.grid.getCell(col);
+ if (!this.isFirstFocusCell() && !prevCell.editable){
+ this.cell=prevCell;
+ this.rowIndex=row;
+ this.previous();
+ return;
+ }
+ }
+ this.setFocusIndex(row, col);
+ }
+ },
+ move: function(inRowDelta, inColDelta) {
+ // summary:
+ // focus grid cell or simulate focus to column header based on position relative to current focus
+ // inRowDelta: int
+ // vertical distance from current focus
+ // inColDelta: int
+ // horizontal distance from current focus
+
+ var colDir = inColDelta < 0 ? -1 : 1;
+ // Handle column headers.
+ if(this.isNavHeader()){
+ var headers = this._findHeaderCells();
+ var savedIdx = currentIdx = dojo.indexOf(headers, this._colHeadNode);
+ currentIdx += inColDelta;
+ while(currentIdx >=0 && currentIdx < headers.length && headers[currentIdx].style.display == "none"){
+ // skip over hidden column headers
+ currentIdx += colDir;
+ }
+ if((currentIdx >= 0) && (currentIdx < headers.length)){
+ this._setActiveColHeader(headers[currentIdx],currentIdx, savedIdx);
+ }
+ }else{
+ if(this.cell){
+ // Handle grid proper.
+ var sc = this.grid.scroller,
+ r = this.rowIndex,
+ rc = this.grid.rowCount-1,
+ row = Math.min(rc, Math.max(0, r+inRowDelta));
+ if(inRowDelta){
+ if(inRowDelta>0){
+ if(row > sc.getLastPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r));
+ }
+ }else if(inRowDelta<0){
+ if(row <= sc.getPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row));
+ }
+ }
+ }
+ var cc = this.grid.layout.cellCount-1,
+ i = this.cell.index,
+ col = Math.min(cc, Math.max(0, i+inColDelta));
+ var cell = this.grid.getCell(col);
+ while(col>=0 && col < cc && cell && cell.hidden === true){
+ // skip hidden cells
+ col += colDir;
+ cell = this.grid.getCell(col);
+ }
+ if (!cell || cell.hidden === true){
+ // don't change col if would move to hidden
+ col = i;
+ }
+ this.setFocusIndex(row, col);
+ if(inRowDelta){
+ this.grid.updateRow(r);
+ }
+ }
+ }
+ },
+ previousKey: function(e){
+ if(this.grid.edit.isEditing()){
+ dojo.stopEvent(e);
+ this.previous();
+ }else if(!this.isNavHeader() && !this._isHeaderHidden()) {
+ this.grid.domNode.focus(); // will call doFocus and set focus into header.
+ dojo.stopEvent(e);
+ }else{
+ this.tabOut(this.grid.domNode);
+ if (this._colHeadFocusIdx != null) { // clear grid header focus
+ dojo.toggleClass(this._findHeaderCells()[this._colHeadFocusIdx], this.focusClass, false);
+ this._colHeadFocusIdx = null;
+ }
+ this._focusifyCellNode(false);
+ }
+ },
+ nextKey: function(e) {
+ var isEmpty = (this.grid.rowCount === 0);
+ if(e.target === this.grid.domNode && this._colHeadFocusIdx == null){
+ this.focusHeader();
+ dojo.stopEvent(e);
+ }else if(this.isNavHeader()){
+ // if tabbing from col header, then go to grid proper.
+ this.blurHeader();
+ if(!this.findAndFocusGridCell()){
+ this.tabOut(this.grid.lastFocusNode);
+ }
+ this._colHeadNode = this._colHeadFocusIdx= null;
+ }else if(this.grid.edit.isEditing()){
+ dojo.stopEvent(e);
+ this.next();
+ }else{
+ this.tabOut(this.grid.lastFocusNode);
+ }
+ },
+ tabOut: function(inFocusNode){
+ this.tabbingOut = true;
+ inFocusNode.focus();
+ },
+ focusGridView: function(){
+ dojox.grid.util.fire(this.focusView, "focus");
+ },
+ focusGrid: function(inSkipFocusCell){
+ this.focusGridView();
+ this._focusifyCellNode(true);
+ },
+ findAndFocusGridCell: function(){
+ // summary:
+ // find the first focusable grid cell
+ // returns: Boolean
+ // true if focus was set to a cell
+ // false if no cell found to set focus onto
+
+ var didFocus = true;
+ var isEmpty = (this.grid.rowCount === 0); // If grid is empty this.grid.rowCount == 0
+ if (this.isNoFocusCell() && !isEmpty){
+ var cellIdx = 0;
+ var cell = this.grid.getCell(cellIdx);
+ if (cell.hidden) {
+ // if first cell isn't visible, use _colHeadFocusIdx
+ // could also use a while loop to find first visible cell - not sure that is worth it
+ cellIdx = this.isNavHeader() ? this._colHeadFocusIdx : 0;
+ }
+ this.setFocusIndex(0, cellIdx);
+ }
+ else if (this.cell && !isEmpty){
+ if (this.focusView && !this.focusView.rowNodes[this.rowIndex]){
+ // if rowNode for current index is undefined (likely as a result of a sort and because of #7304)
+ // scroll to that row
+ this.grid.scrollToRow(this.rowIndex);
+ }
+ this.focusGrid();
+ }else {
+ didFocus = false;
+ }
+ this._colHeadNode = this._colHeadFocusIdx= null;
+ return didFocus;
+ },
+ focusHeader: function(){
+ var headerNodes = this._findHeaderCells();
+ var saveColHeadFocusIdx = this._colHeadFocusIdx;
+ if (this._isHeaderHidden()){
+ // grid header is hidden, focus a cell
+ this.findAndFocusGridCell();
+ }
+ else if (!this._colHeadFocusIdx) {
+ if (this.isNoFocusCell()) {
+ this._colHeadFocusIdx = 0;
+ }
+ else {
+ this._colHeadFocusIdx = this.cell.index;
+ }
+ }
+ this._colHeadNode = headerNodes[this._colHeadFocusIdx];
+ while(this._colHeadNode && this._colHeadFocusIdx >=0 && this._colHeadFocusIdx < headerNodes.length &&
+ this._colHeadNode.style.display == "none"){
+ // skip over hidden column headers
+ this._colHeadFocusIdx++;
+ this._colHeadNode = headerNodes[this._colHeadFocusIdx];
+ }
+ if(this._colHeadNode && this._colHeadNode.style.display != "none"){
+ // Column header cells know longer receive actual focus. So, for keyboard invocation of
+ // contextMenu to work, the contextMenu must be bound to the grid.domNode rather than the viewsHeaderNode.
+ // unbind the contextmenu from the viewsHeaderNode and to the grid when header cells are active. Reset
+ // the binding back to the viewsHeaderNode when header cells are no longer acive (in blurHeader) #10483
+ if (this.headerMenu && this._contextMenuBindNode != this.grid.domNode){
+ this.headerMenu.unBindDomNode(this.grid.viewsHeaderNode);
+ this.headerMenu.bindDomNode(this.grid.domNode);
+ this._contextMenuBindNode = this.grid.domNode;
+ }
+ this._setActiveColHeader(this._colHeadNode, this._colHeadFocusIdx, saveColHeadFocusIdx);
+ this._scrollHeader(this._colHeadFocusIdx);
+ this._focusifyCellNode(false);
+ }else {
+ // all col head nodes are hidden - focus the grid
+ this.findAndFocusGridCell();
+ }
+ },
+ blurHeader: function(){
+ dojo.removeClass(this._colHeadNode, this.focusClass);
+ dojo.removeAttr(this.grid.domNode,"aria-activedescendant");
+ // reset contextMenu onto viewsHeaderNode so right mouse on header will invoke (see focusHeader)
+ if (this.headerMenu && this._contextMenuBindNode == this.grid.domNode) {
+ var viewsHeader = this.grid.viewsHeaderNode;
+ this.headerMenu.unBindDomNode(this.grid.domNode);
+ this.headerMenu.bindDomNode(viewsHeader);
+ this._contextMenuBindNode = viewsHeader;
+ }
+ },
+ doFocus: function(e){
+ // trap focus only for grid dom node
+ if(e && e.target != e.currentTarget){
+ dojo.stopEvent(e);
+ return;
+ }
+ // do not focus for scrolling if grid is about to blur
+ if(!this.tabbingOut){
+ this.focusHeader();
+ }
+ this.tabbingOut = false;
+ dojo.stopEvent(e);
+ },
+ doBlur: function(e){
+ dojo.stopEvent(e); // FF2
+ },
+ doContextMenu: function(e){
+ //stop contextMenu event if no header Menu to prevent default/browser contextMenu
+ if (!this.headerMenu){
+ dojo.stopEvent(e);
+ }
+ },
+ doLastNodeFocus: function(e){
+ if (this.tabbingOut){
+ this._focusifyCellNode(false);
+ }else if(this.grid.rowCount >0){
+ if (this.isNoFocusCell()){
+ this.setFocusIndex(0,0);
+ }
+ this._focusifyCellNode(true);
+ }else {
+ this.focusHeader();
+ }
+ this.tabbingOut = false;
+ dojo.stopEvent(e); // FF2
+ },
+ doLastNodeBlur: function(e){
+ dojo.stopEvent(e); // FF2
+ },
+ doColHeaderFocus: function(e){
+ this._setActiveColHeader(e.target,dojo.attr(e.target, "idx"),this._colHeadFocusIdx);
+ this._scrollHeader(this.getHeaderIndex());
+ dojo.stopEvent(e);
+ },
+ doColHeaderBlur: function(e){
+ dojo.toggleClass(e.target, this.focusClass, false);
+ }
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/_Grid.js b/js/dojo-1.6/dojox/grid/_Grid.js
new file mode 100644
index 0000000..7fdcf30
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_Grid.js
@@ -0,0 +1,1382 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid._Grid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Grid"] = true;
+dojo.provide("dojox.grid._Grid");
+
+dojo.require("dijit.dijit");
+dojo.require("dijit.Menu");
+
+dojo.require("dojox.html.metrics");
+dojo.require("dojox.grid.util");
+dojo.require("dojox.grid._Scroller");
+dojo.require("dojox.grid._Layout");
+dojo.require("dojox.grid._View");
+dojo.require("dojox.grid._ViewManager");
+dojo.require("dojox.grid._RowManager");
+dojo.require("dojox.grid._FocusManager");
+dojo.require("dojox.grid._EditManager");
+dojo.require("dojox.grid.Selection");
+dojo.require("dojox.grid._RowSelector");
+dojo.require("dojox.grid._Events");
+
+
+dojo.requireLocalization("dijit", "loading", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
+
+(function(){
+ // NOTE: this is for backwards compatibility with Dojo 1.3
+ if(!dojo.isCopyKey){
+ dojo.isCopyKey = dojo.dnd.getCopyKeyState;
+ }
+ /*=====
+ dojox.grid.__CellDef = function(){
+ // name: String?
+ // The text to use in the header of the grid for this cell.
+ // get: Function?
+ // function(rowIndex){} rowIndex is of type Integer. This
+ // function will be called when a cell requests data. Returns the
+ // unformatted data for the cell.
+ // value: String?
+ // If "get" is not specified, this is used as the data for the cell.
+ // defaultValue: String?
+ // If "get" and "value" aren't specified or if "get" returns an undefined
+ // value, this is used as the data for the cell. "formatter" is not run
+ // on this if "get" returns an undefined value.
+ // formatter: Function?
+ // function(data, rowIndex){} data is of type anything, rowIndex
+ // is of type Integer. This function will be called after the cell
+ // has its data but before it passes it back to the grid to render.
+ // Returns the formatted version of the cell's data.
+ // type: dojox.grid.cells._Base|Function?
+ // TODO
+ // editable: Boolean?
+ // Whether this cell should be editable or not.
+ // hidden: Boolean?
+ // If true, the cell will not be displayed.
+ // noresize: Boolean?
+ // If true, the cell will not be able to be resized.
+ // width: Integer|String?
+ // A CSS size. If it's an Integer, the width will be in em's.
+ // colSpan: Integer?
+ // How many columns to span this cell. Will not work in the first
+ // sub-row of cells.
+ // rowSpan: Integer?
+ // How many sub-rows to span this cell.
+ // styles: String?
+ // A string of styles to apply to both the header cell and main
+ // grid cells. Must end in a ';'.
+ // headerStyles: String?
+ // A string of styles to apply to just the header cell. Must end
+ // in a ';'
+ // cellStyles: String?
+ // A string of styles to apply to just the main grid cells. Must
+ // end in a ';'
+ // classes: String?
+ // A space separated list of classes to apply to both the header
+ // cell and the main grid cells.
+ // headerClasses: String?
+ // A space separated list of classes to apply to just the header
+ // cell.
+ // cellClasses: String?
+ // A space separated list of classes to apply to just the main
+ // grid cells.
+ // attrs: String?
+ // A space separated string of attribute='value' pairs to add to
+ // the header cell element and main grid cell elements.
+ this.name = name;
+ this.value = value;
+ this.get = get;
+ this.formatter = formatter;
+ this.type = type;
+ this.editable = editable;
+ this.hidden = hidden;
+ this.width = width;
+ this.colSpan = colSpan;
+ this.rowSpan = rowSpan;
+ this.styles = styles;
+ this.headerStyles = headerStyles;
+ this.cellStyles = cellStyles;
+ this.classes = classes;
+ this.headerClasses = headerClasses;
+ this.cellClasses = cellClasses;
+ this.attrs = attrs;
+ }
+ =====*/
+
+ /*=====
+ dojox.grid.__ViewDef = function(){
+ // noscroll: Boolean?
+ // If true, no scrollbars will be rendered without scrollbars.
+ // width: Integer|String?
+ // A CSS size. If it's an Integer, the width will be in em's. If
+ // "noscroll" is true, this value is ignored.
+ // cells: dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]?
+ // The structure of the cells within this grid.
+ // type: String?
+ // A string containing the constructor of a subclass of
+ // dojox.grid._View. If this is not specified, dojox.grid._View
+ // is used.
+ // defaultCell: dojox.grid.__CellDef?
+ // A cell definition with default values for all cells in this view. If
+ // a property is defined in a cell definition in the "cells" array and
+ // this property, the cell definition's property will override this
+ // property's property.
+ // onBeforeRow: Function?
+ // function(rowIndex, cells){} rowIndex is of type Integer, cells
+ // is of type Array[dojox.grid.__CellDef[]]. This function is called
+ // before each row of data is rendered. Before the header is
+ // rendered, rowIndex will be -1. "cells" is a reference to the
+ // internal structure of this view's cells so any changes you make to
+ // it will persist between calls.
+ // onAfterRow: Function?
+ // function(rowIndex, cells, rowNode){} rowIndex is of type Integer, cells
+ // is of type Array[dojox.grid.__CellDef[]], rowNode is of type DOMNode.
+ // This function is called after each row of data is rendered. After the
+ // header is rendered, rowIndex will be -1. "cells" is a reference to the
+ // internal structure of this view's cells so any changes you make to
+ // it will persist between calls.
+ this.noscroll = noscroll;
+ this.width = width;
+ this.cells = cells;
+ this.type = type;
+ this.defaultCell = defaultCell;
+ this.onBeforeRow = onBeforeRow;
+ this.onAfterRow = onAfterRow;
+ }
+ =====*/
+
+ dojo.declare('dojox.grid._Grid',
+ [ dijit._Widget, dijit._Templated, dojox.grid._Events ],
+ {
+ // summary:
+ // A grid widget with virtual scrolling, cell editing, complex rows,
+ // sorting, fixed columns, sizeable columns, etc.
+ //
+ // description:
+ // _Grid provides the full set of grid features without any
+ // direct connection to a data store.
+ //
+ // The grid exposes a get function for the grid, or optionally
+ // individual columns, to populate cell contents.
+ //
+ // The grid is rendered based on its structure, an object describing
+ // column and cell layout.
+ //
+ // example:
+ // A quick sample:
+ //
+ // define a get function
+ // | function get(inRowIndex){ // called in cell context
+ // | return [this.index, inRowIndex].join(', ');
+ // | }
+ //
+ // define the grid structure:
+ // | var structure = [ // array of view objects
+ // | { cells: [// array of rows, a row is an array of cells
+ // | [
+ // | { name: "Alpha", width: 6 },
+ // | { name: "Beta" },
+ // | { name: "Gamma", get: get }]
+ // | ]}
+ // | ];
+ //
+ // | <div id="grid"
+ // | rowCount="100" get="get"
+ // | structure="structure"
+ // | dojoType="dojox.grid._Grid"></div>
+
+ templateString:"<div hidefocus=\"hidefocus\" role=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\r\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" role=\"presentation\"></div>\r\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" role=\"presentation\"></div>\r\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\r\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\r\n</div>\r\n",
+
+ // classTag: String
+ // CSS class applied to the grid's domNode
+ classTag: 'dojoxGrid',
+
+ // settings
+ // rowCount: Integer
+ // Number of rows to display.
+ rowCount: 5,
+
+ // keepRows: Integer
+ // Number of rows to keep in the rendering cache.
+ keepRows: 75,
+
+ // rowsPerPage: Integer
+ // Number of rows to render at a time.
+ rowsPerPage: 25,
+
+ // autoWidth: Boolean
+ // If autoWidth is true, grid width is automatically set to fit the data.
+ autoWidth: false,
+
+ // initialWidth: String
+ // A css string to use to set our initial width (only used if autoWidth
+ // is true). The first rendering of the grid will be this width, any
+ // resizing of columns, etc will result in the grid switching to
+ // autoWidth mode. Note, this width will override any styling in a
+ // stylesheet or directly on the node.
+ initialWidth: "",
+
+ // autoHeight: Boolean|Integer
+ // If autoHeight is true, grid height is automatically set to fit the data.
+ // If it is an integer, the height will be automatically set to fit the data
+ // if there are fewer than that many rows - and the height will be set to show
+ // that many rows if there are more
+ autoHeight: '',
+
+ // rowHeight: Integer
+ // If rowHeight is set to a positive number, it will define the height of the rows
+ // in pixels. This can provide a significant performance advantage, since it
+ // eliminates the need to measure row sizes during rendering, which is one
+ // the primary bottlenecks in the DataGrid's performance.
+ rowHeight: 0,
+
+ // autoRender: Boolean
+ // If autoRender is true, grid will render itself after initialization.
+ autoRender: true,
+
+ // defaultHeight: String
+ // default height of the grid, measured in any valid css unit.
+ defaultHeight: '15em',
+
+ // height: String
+ // explicit height of the grid, measured in any valid css unit. This will be populated (and overridden)
+ // if the height: css attribute exists on the source node.
+ height: '',
+
+ // structure: dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]
+ // View layout defintion.
+ structure: null,
+
+ // elasticView: Integer
+ // Override defaults and make the indexed grid view elastic, thus filling available horizontal space.
+ elasticView: -1,
+
+ // singleClickEdit: boolean
+ // Single-click starts editing. Default is double-click
+ singleClickEdit: false,
+
+ // selectionMode: String
+ // Set the selection mode of grid's Selection. Value must be 'single', 'multiple',
+ // or 'extended'. Default is 'extended'.
+ selectionMode: 'extended',
+
+ // rowSelector: Boolean|String
+ // If set to true, will add a row selector view to this grid. If set to a CSS width, will add
+ // a row selector of that width to this grid.
+ rowSelector: '',
+
+ // columnReordering: Boolean
+ // If set to true, will add drag and drop reordering to views with one row of columns.
+ columnReordering: false,
+
+ // headerMenu: dijit.Menu
+ // If set to a dijit.Menu, will use this as a context menu for the grid headers.
+ headerMenu: null,
+
+ // placeholderLabel: String
+ // Label of placeholders to search for in the header menu to replace with column toggling
+ // menu items.
+ placeholderLabel: "GridColumns",
+
+ // selectable: Boolean
+ // Set to true if you want to be able to select the text within the grid.
+ selectable: false,
+
+ // Used to store the last two clicks, to ensure double-clicking occurs based on the intended row
+ _click: null,
+
+ // loadingMessage: String
+ // Message that shows while the grid is loading
+ loadingMessage: "<span class='dojoxGridLoading'>${loadingState}</span>",
+
+ // errorMessage: String
+ // Message that shows when the grid encounters an error loading
+ errorMessage: "<span class='dojoxGridError'>${errorState}</span>",
+
+ // noDataMessage: String
+ // Message that shows if the grid has no data - wrap it in a
+ // span with class 'dojoxGridNoData' if you want it to be
+ // styled similar to the loading and error messages
+ noDataMessage: "",
+
+ // escapeHTMLInData: Boolean
+ // This will escape HTML brackets from the data to prevent HTML from
+ // user-inputted data being rendered with may contain JavaScript and result in
+ // XSS attacks. This is true by default, and it is recommended that it remain
+ // true. Setting this to false will allow data to be displayed in the grid without
+ // filtering, and should be only used if it is known that the data won't contain
+ // malicious scripts. If HTML is needed in grid cells, it is recommended that
+ // you use the formatter function to generate the HTML (the output of
+ // formatter functions is not filtered, even with escapeHTMLInData set to true).
+ escapeHTMLInData: true,
+
+ // formatterScope: Object
+ // An object to execute format functions within. If not set, the
+ // format functions will execute within the scope of the cell that
+ // has a format function.
+ formatterScope: null,
+
+ // editable: boolean
+ // indicates if the grid contains editable cells, default is false
+ // set to true if editable cell encountered during rendering
+ editable: false,
+
+ // private
+ sortInfo: 0,
+ themeable: true,
+ _placeholders: null,
+
+ // _layoutClass: Object
+ // The class to use for our layout - can be overridden by grid subclasses
+ _layoutClass: dojox.grid._Layout,
+
+ // initialization
+ buildRendering: function(){
+ this.inherited(arguments);
+ if(!this.domNode.getAttribute('tabIndex')){
+ this.domNode.tabIndex = "0";
+ }
+ this.createScroller();
+ this.createLayout();
+ this.createViews();
+ this.createManagers();
+
+ this.createSelection();
+
+ this.connect(this.selection, "onSelected", "onSelected");
+ this.connect(this.selection, "onDeselected", "onDeselected");
+ this.connect(this.selection, "onChanged", "onSelectionChanged");
+
+ dojox.html.metrics.initOnFontResize();
+ this.connect(dojox.html.metrics, "onFontResize", "textSizeChanged");
+ dojox.grid.util.funnelEvents(this.domNode, this, 'doKeyEvent', dojox.grid.util.keyEvents);
+ if (this.selectionMode != "none") {
+ dojo.attr(this.domNode, "aria-multiselectable", this.selectionMode == "single" ? "false" : "true");
+ }
+
+ dojo.addClass(this.domNode, this.classTag);
+ if(!this.isLeftToRight()){
+ dojo.addClass(this.domNode, this.classTag+"Rtl");
+ }
+ },
+
+ postMixInProperties: function(){
+ this.inherited(arguments);
+ var messages = dojo.i18n.getLocalization("dijit", "loading", this.lang);
+ this.loadingMessage = dojo.string.substitute(this.loadingMessage, messages);
+ this.errorMessage = dojo.string.substitute(this.errorMessage, messages);
+ if(this.srcNodeRef && this.srcNodeRef.style.height){
+ this.height = this.srcNodeRef.style.height;
+ }
+ // Call this to update our autoheight to start out
+ this._setAutoHeightAttr(this.autoHeight, true);
+ this.lastScrollTop = this.scrollTop = 0;
+ },
+
+ postCreate: function(){
+ this._placeholders = [];
+ this._setHeaderMenuAttr(this.headerMenu);
+ this._setStructureAttr(this.structure);
+ this._click = [];
+ this.inherited(arguments);
+ if(this.domNode && this.autoWidth && this.initialWidth){
+ this.domNode.style.width = this.initialWidth;
+ }
+ if (this.domNode && !this.editable){
+ // default value for aria-readonly is false, set to true if grid is not editable
+ dojo.attr(this.domNode,"aria-readonly", "true");
+ }
+ },
+
+ destroy: function(){
+ this.domNode.onReveal = null;
+ this.domNode.onSizeChange = null;
+
+ // Fixes IE domNode leak
+ delete this._click;
+
+ this.edit.destroy();
+ delete this.edit;
+
+ this.views.destroyViews();
+ if(this.scroller){
+ this.scroller.destroy();
+ delete this.scroller;
+ }
+ if(this.focus){
+ this.focus.destroy();
+ delete this.focus;
+ }
+ if(this.headerMenu&&this._placeholders.length){
+ dojo.forEach(this._placeholders, function(p){ p.unReplace(true); });
+ this.headerMenu.unBindDomNode(this.viewsHeaderNode);
+ }
+ this.inherited(arguments);
+ },
+
+ _setAutoHeightAttr: function(ah, skipRender){
+ // Calculate our autoheight - turn it into a boolean or an integer
+ if(typeof ah == "string"){
+ if(!ah || ah == "false"){
+ ah = false;
+ }else if (ah == "true"){
+ ah = true;
+ }else{
+ ah = window.parseInt(ah, 10);
+ }
+ }
+ if(typeof ah == "number"){
+ if(isNaN(ah)){
+ ah = false;
+ }
+ // Autoheight must be at least 1, if it's a number. If it's
+ // less than 0, we'll take that to mean "all" rows (same as
+ // autoHeight=true - if it is equal to zero, we'll take that
+ // to mean autoHeight=false
+ if(ah < 0){
+ ah = true;
+ }else if (ah === 0){
+ ah = false;
+ }
+ }
+ this.autoHeight = ah;
+ if(typeof ah == "boolean"){
+ this._autoHeight = ah;
+ }else if(typeof ah == "number"){
+ this._autoHeight = (ah >= this.get('rowCount'));
+ }else{
+ this._autoHeight = false;
+ }
+ if(this._started && !skipRender){
+ this.render();
+ }
+ },
+
+ _getRowCountAttr: function(){
+ return this.updating && this.invalidated && this.invalidated.rowCount != undefined ?
+ this.invalidated.rowCount : this.rowCount;
+ },
+
+ textSizeChanged: function(){
+ this.render();
+ },
+
+ sizeChange: function(){
+ this.update();
+ },
+
+ createManagers: function(){
+ // summary:
+ // create grid managers for various tasks including rows, focus, selection, editing
+
+ // row manager
+ this.rows = new dojox.grid._RowManager(this);
+ // focus manager
+ this.focus = new dojox.grid._FocusManager(this);
+ // edit manager
+ this.edit = new dojox.grid._EditManager(this);
+ },
+
+ createSelection: function(){
+ // summary: Creates a new Grid selection manager.
+
+ // selection manager
+ this.selection = new dojox.grid.Selection(this);
+ },
+
+ createScroller: function(){
+ // summary: Creates a new virtual scroller
+ this.scroller = new dojox.grid._Scroller();
+ this.scroller.grid = this;
+ this.scroller.renderRow = dojo.hitch(this, "renderRow");
+ this.scroller.removeRow = dojo.hitch(this, "rowRemoved");
+ },
+
+ createLayout: function(){
+ // summary: Creates a new Grid layout
+ this.layout = new this._layoutClass(this);
+ this.connect(this.layout, "moveColumn", "onMoveColumn");
+ },
+
+ onMoveColumn: function(){
+ this.render();
+ },
+
+ onResizeColumn: function(/*int*/ cellIdx){
+ // Called when a column is resized.
+ },
+
+ // views
+ createViews: function(){
+ this.views = new dojox.grid._ViewManager(this);
+ this.views.createView = dojo.hitch(this, "createView");
+ },
+
+ createView: function(inClass, idx){
+ var c = dojo.getObject(inClass);
+ var view = new c({ grid: this, index: idx });
+ this.viewsNode.appendChild(view.domNode);
+ this.viewsHeaderNode.appendChild(view.headerNode);
+ this.views.addView(view);
+ dojo.attr(this.domNode, "align", dojo._isBodyLtr() ? 'left' : 'right');
+ return view;
+ },
+
+ buildViews: function(){
+ for(var i=0, vs; (vs=this.layout.structure[i]); i++){
+ this.createView(vs.type || dojox._scopeName + ".grid._View", i).setStructure(vs);
+ }
+ this.scroller.setContentNodes(this.views.getContentNodes());
+ },
+
+ _setStructureAttr: function(structure){
+ var s = structure;
+ if(s && dojo.isString(s)){
+ dojo.deprecated("dojox.grid._Grid.set('structure', 'objVar')", "use dojox.grid._Grid.set('structure', objVar) instead", "2.0");
+ s=dojo.getObject(s);
+ }
+ this.structure = s;
+ if(!s){
+ if(this.layout.structure){
+ s = this.layout.structure;
+ }else{
+ return;
+ }
+ }
+ this.views.destroyViews();
+ if(s !== this.layout.structure){
+ this.layout.setStructure(s);
+ }
+ this._structureChanged();
+ },
+
+ setStructure: function(/* dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]] */ inStructure){
+ // summary:
+ // Install a new structure and rebuild the grid.
+ dojo.deprecated("dojox.grid._Grid.setStructure(obj)", "use dojox.grid._Grid.set('structure', obj) instead.", "2.0");
+ this._setStructureAttr(inStructure);
+ },
+
+ getColumnTogglingItems: function(){
+ // Summary: returns an array of dijit.CheckedMenuItem widgets that can be
+ // added to a menu for toggling columns on and off.
+ return dojo.map(this.layout.cells, function(cell){
+ if(!cell.menuItems){ cell.menuItems = []; }
+
+ var self = this;
+ var item = new dijit.CheckedMenuItem({
+ label: cell.name,
+ checked: !cell.hidden,
+ _gridCell: cell,
+ onChange: function(checked){
+ if(self.layout.setColumnVisibility(this._gridCell.index, checked)){
+ var items = this._gridCell.menuItems;
+ if(items.length > 1){
+ dojo.forEach(items, function(item){
+ if(item !== this){
+ item.setAttribute("checked", checked);
+ }
+ }, this);
+ }
+ checked = dojo.filter(self.layout.cells, function(c){
+ if(c.menuItems.length > 1){
+ dojo.forEach(c.menuItems, "item.set('disabled', false);");
+ }else{
+ c.menuItems[0].set('disabled', false);
+ }
+ return !c.hidden;
+ });
+ if(checked.length == 1){
+ dojo.forEach(checked[0].menuItems, "item.set('disabled', true);");
+ }
+ }
+ },
+ destroy: function(){
+ var index = dojo.indexOf(this._gridCell.menuItems, this);
+ this._gridCell.menuItems.splice(index, 1);
+ delete this._gridCell;
+ dijit.CheckedMenuItem.prototype.destroy.apply(this, arguments);
+ }
+ });
+ cell.menuItems.push(item);
+ return item;
+ }, this); // dijit.CheckedMenuItem[]
+ },
+
+ _setHeaderMenuAttr: function(menu){
+ if(this._placeholders && this._placeholders.length){
+ dojo.forEach(this._placeholders, function(p){
+ p.unReplace(true);
+ });
+ this._placeholders = [];
+ }
+ if(this.headerMenu){
+ this.headerMenu.unBindDomNode(this.viewsHeaderNode);
+ }
+ this.headerMenu = menu;
+ if(!menu){ return; }
+
+ this.headerMenu.bindDomNode(this.viewsHeaderNode);
+ if(this.headerMenu.getPlaceholders){
+ this._placeholders = this.headerMenu.getPlaceholders(this.placeholderLabel);
+ }
+ },
+
+ setHeaderMenu: function(/* dijit.Menu */ menu){
+ dojo.deprecated("dojox.grid._Grid.setHeaderMenu(obj)", "use dojox.grid._Grid.set('headerMenu', obj) instead.", "2.0");
+ this._setHeaderMenuAttr(menu);
+ },
+
+ setupHeaderMenu: function(){
+ if(this._placeholders && this._placeholders.length){
+ dojo.forEach(this._placeholders, function(p){
+ if(p._replaced){
+ p.unReplace(true);
+ }
+ p.replace(this.getColumnTogglingItems());
+ }, this);
+ }
+ },
+
+ _fetch: function(start){
+ this.setScrollTop(0);
+ },
+
+ getItem: function(inRowIndex){
+ return null;
+ },
+
+ showMessage: function(message){
+ if(message){
+ this.messagesNode.innerHTML = message;
+ this.messagesNode.style.display = "";
+ }else{
+ this.messagesNode.innerHTML = "";
+ this.messagesNode.style.display = "none";
+ }
+ },
+
+ _structureChanged: function() {
+ this.buildViews();
+ if(this.autoRender && this._started){
+ this.render();
+ }
+ },
+
+ hasLayout: function() {
+ return this.layout.cells.length;
+ },
+
+ // sizing
+ resize: function(changeSize, resultSize){
+ // summary:
+ // Update the grid's rendering dimensions and resize it
+
+ // Calling sizeChange calls update() which calls _resize...so let's
+ // save our input values, if any, and use them there when it gets
+ // called. This saves us an extra call to _resize(), which can
+ // get kind of heavy.
+ this._pendingChangeSize = changeSize;
+ this._pendingResultSize = resultSize;
+ this.sizeChange();
+ },
+
+ _getPadBorder: function() {
+ this._padBorder = this._padBorder || dojo._getPadBorderExtents(this.domNode);
+ return this._padBorder;
+ },
+
+ _getHeaderHeight: function(){
+ var vns = this.viewsHeaderNode.style, t = vns.display == "none" ? 0 : this.views.measureHeader();
+ vns.height = t + 'px';
+ // header heights are reset during measuring so must be normalized after measuring.
+ this.views.normalizeHeaderNodeHeight();
+ return t;
+ },
+
+ _resize: function(changeSize, resultSize){
+ // Restore our pending values, if any
+ changeSize = changeSize || this._pendingChangeSize;
+ resultSize = resultSize || this._pendingResultSize;
+ delete this._pendingChangeSize;
+ delete this._pendingResultSize;
+ // if we have set up everything except the DOM, we cannot resize
+ if(!this.domNode){ return; }
+ var pn = this.domNode.parentNode;
+ if(!pn || pn.nodeType != 1 || !this.hasLayout() || pn.style.visibility == "hidden" || pn.style.display == "none"){
+ return;
+ }
+ // useful measurement
+ var padBorder = this._getPadBorder();
+ var hh = undefined;
+ var h;
+ // grid height
+ if(this._autoHeight){
+ this.domNode.style.height = 'auto';
+ }else if(typeof this.autoHeight == "number"){
+ h = hh = this._getHeaderHeight();
+ h += (this.scroller.averageRowHeight * this.autoHeight);
+ this.domNode.style.height = h + "px";
+ }else if(this.domNode.clientHeight <= padBorder.h){
+ if(pn == document.body){
+ this.domNode.style.height = this.defaultHeight;
+ }else if(this.height){
+ this.domNode.style.height = this.height;
+ }else{
+ this.fitTo = "parent";
+ }
+ }
+ // if we are given dimensions, size the grid's domNode to those dimensions
+ if(resultSize){
+ changeSize = resultSize;
+ }
+ if(changeSize){
+ dojo.marginBox(this.domNode, changeSize);
+ this.height = this.domNode.style.height;
+ delete this.fitTo;
+ }else if(this.fitTo == "parent"){
+ h = this._parentContentBoxHeight = this._parentContentBoxHeight || dojo._getContentBox(pn).h;
+ this.domNode.style.height = Math.max(0, h) + "px";
+ }
+
+ var hasFlex = dojo.some(this.views.views, function(v){ return v.flexCells; });
+
+ if(!this._autoHeight && (h || dojo._getContentBox(this.domNode).h) === 0){
+ // We need to hide the header, since the Grid is essentially hidden.
+ this.viewsHeaderNode.style.display = "none";
+ }else{
+ // Otherwise, show the header and give it an appropriate height.
+ this.viewsHeaderNode.style.display = "block";
+ if(!hasFlex && hh === undefined){
+ hh = this._getHeaderHeight();
+ }
+ }
+ if(hasFlex){
+ hh = undefined;
+ }
+
+ // NOTE: it is essential that width be applied before height
+ // Header height can only be calculated properly after view widths have been set.
+ // This is because flex column width is naturally 0 in Firefox.
+ // Therefore prior to width sizing flex columns with spaces are maximally wrapped
+ // and calculated to be too tall.
+ this.adaptWidth();
+ this.adaptHeight(hh);
+
+ this.postresize();
+ },
+
+ adaptWidth: function() {
+ // private: sets width and position for views and update grid width if necessary
+ var doAutoWidth = (!this.initialWidth && this.autoWidth);
+ var w = doAutoWidth ? 0 : this.domNode.clientWidth || (this.domNode.offsetWidth - this._getPadBorder().w),
+ vw = this.views.arrange(1, w);
+ this.views.onEach("adaptWidth");
+ if(doAutoWidth){
+ this.domNode.style.width = vw + "px";
+ }
+ },
+
+ adaptHeight: function(inHeaderHeight){
+ // private: measures and normalizes header height, then sets view heights, and then updates scroller
+ // content extent
+ var t = inHeaderHeight === undefined ? this._getHeaderHeight() : inHeaderHeight;
+ var h = (this._autoHeight ? -1 : Math.max(this.domNode.clientHeight - t, 0) || 0);
+ this.views.onEach('setSize', [0, h]);
+ this.views.onEach('adaptHeight');
+ if(!this._autoHeight){
+ var numScroll = 0, numNoScroll = 0;
+ var noScrolls = dojo.filter(this.views.views, function(v){
+ var has = v.hasHScrollbar();
+ if(has){ numScroll++; }else{ numNoScroll++; }
+ return (!has);
+ });
+ if(numScroll > 0 && numNoScroll > 0){
+ dojo.forEach(noScrolls, function(v){
+ v.adaptHeight(true);
+ });
+ }
+ }
+ if(this.autoHeight === true || h != -1 || (typeof this.autoHeight == "number" && this.autoHeight >= this.get('rowCount'))){
+ this.scroller.windowHeight = h;
+ }else{
+ this.scroller.windowHeight = Math.max(this.domNode.clientHeight - t, 0);
+ }
+ },
+
+ // startup
+ startup: function(){
+ if(this._started){return;}
+ this.inherited(arguments);
+ if(this.autoRender){
+ this.render();
+ }
+ },
+
+ // render
+ render: function(){
+ // summary:
+ // Render the grid, headers, and views. Edit and scrolling states are reset. To retain edit and
+ // scrolling states, see Update.
+
+ if(!this.domNode){return;}
+ if(!this._started){return;}
+
+ if(!this.hasLayout()) {
+ this.scroller.init(0, this.keepRows, this.rowsPerPage);
+ return;
+ }
+ //
+ this.update = this.defaultUpdate;
+ this._render();
+ },
+
+ _render: function(){
+ this.scroller.init(this.get('rowCount'), this.keepRows, this.rowsPerPage);
+ this.prerender();
+ this.setScrollTop(0);
+ this.postrender();
+ },
+
+ prerender: function(){
+ // if autoHeight, make sure scroller knows not to virtualize; everything must be rendered.
+ this.keepRows = this._autoHeight ? 0 : this.keepRows;
+ this.scroller.setKeepInfo(this.keepRows);
+ this.views.render();
+ this._resize();
+ },
+
+ postrender: function(){
+ this.postresize();
+ this.focus.initFocusView();
+ // make rows unselectable
+ dojo.setSelectable(this.domNode, this.selectable);
+ },
+
+ postresize: function(){
+ // views are position absolute, so they do not inflate the parent
+ if(this._autoHeight){
+ var size = Math.max(this.views.measureContent()) + 'px';
+
+ this.viewsNode.style.height = size;
+ }
+ },
+
+ renderRow: function(inRowIndex, inNodes){
+ // summary: private, used internally to render rows
+ this.views.renderRow(inRowIndex, inNodes, this._skipRowRenormalize);
+ },
+
+ rowRemoved: function(inRowIndex){
+ // summary: private, used internally to remove rows
+ this.views.rowRemoved(inRowIndex);
+ },
+
+ invalidated: null,
+
+ updating: false,
+
+ beginUpdate: function(){
+ // summary:
+ // Use to make multiple changes to rows while queueing row updating.
+ // NOTE: not currently supporting nested begin/endUpdate calls
+ this.invalidated = [];
+ this.updating = true;
+ },
+
+ endUpdate: function(){
+ // summary:
+ // Use after calling beginUpdate to render any changes made to rows.
+ this.updating = false;
+ var i = this.invalidated, r;
+ if(i.all){
+ this.update();
+ }else if(i.rowCount != undefined){
+ this.updateRowCount(i.rowCount);
+ }else{
+ for(r in i){
+ this.updateRow(Number(r));
+ }
+ }
+ this.invalidated = [];
+ },
+
+ // update
+ defaultUpdate: function(){
+ // note: initial update calls render and subsequently this function.
+ if(!this.domNode){return;}
+ if(this.updating){
+ this.invalidated.all = true;
+ return;
+ }
+ //this.edit.saveState(inRowIndex);
+ this.lastScrollTop = this.scrollTop;
+ this.prerender();
+ this.scroller.invalidateNodes();
+ this.setScrollTop(this.lastScrollTop);
+ this.postrender();
+ //this.edit.restoreState(inRowIndex);
+ },
+
+ update: function(){
+ // summary:
+ // Update the grid, retaining edit and scrolling states.
+ this.render();
+ },
+
+ updateRow: function(inRowIndex){
+ // summary:
+ // Render a single row.
+ // inRowIndex: Integer
+ // Index of the row to render
+ inRowIndex = Number(inRowIndex);
+ if(this.updating){
+ this.invalidated[inRowIndex]=true;
+ }else{
+ this.views.updateRow(inRowIndex);
+ this.scroller.rowHeightChanged(inRowIndex);
+ }
+ },
+
+ updateRows: function(startIndex, howMany){
+ // summary:
+ // Render consecutive rows at once.
+ // startIndex: Integer
+ // Index of the starting row to render
+ // howMany: Integer
+ // How many rows to update.
+ startIndex = Number(startIndex);
+ howMany = Number(howMany);
+ var i;
+ if(this.updating){
+ for(i=0; i<howMany; i++){
+ this.invalidated[i+startIndex]=true;
+ }
+ }else{
+ for(i=0; i<howMany; i++){
+ this.views.updateRow(i+startIndex, this._skipRowRenormalize);
+ }
+ this.scroller.rowHeightChanged(startIndex);
+ }
+ },
+
+ updateRowCount: function(inRowCount){
+ //summary:
+ // Change the number of rows.
+ // inRowCount: int
+ // Number of rows in the grid.
+ if(this.updating){
+ this.invalidated.rowCount = inRowCount;
+ }else{
+ this.rowCount = inRowCount;
+ this._setAutoHeightAttr(this.autoHeight, true);
+ if(this.layout.cells.length){
+ this.scroller.updateRowCount(inRowCount);
+ }
+ this._resize();
+ if(this.layout.cells.length){
+ this.setScrollTop(this.scrollTop);
+ }
+ }
+ },
+
+ updateRowStyles: function(inRowIndex){
+ // summary:
+ // Update the styles for a row after it's state has changed.
+ this.views.updateRowStyles(inRowIndex);
+ },
+ getRowNode: function(inRowIndex){
+ // summary:
+ // find the rowNode that is not a rowSelector
+ if (this.focus.focusView && !(this.focus.focusView instanceof dojox.grid._RowSelector)){
+ return this.focus.focusView.rowNodes[inRowIndex];
+ }else{ // search through views
+ for (var i = 0, cView; (cView = this.views.views[i]); i++) {
+ if (!(cView instanceof dojox.grid._RowSelector)) {
+ return cView.rowNodes[inRowIndex];
+ }
+ }
+ }
+ return null;
+ },
+ rowHeightChanged: function(inRowIndex){
+ // summary:
+ // Update grid when the height of a row has changed. Row height is handled automatically as rows
+ // are rendered. Use this function only to update a row's height outside the normal rendering process.
+ // inRowIndex: Integer
+ // index of the row that has changed height
+
+ this.views.renormalizeRow(inRowIndex);
+ this.scroller.rowHeightChanged(inRowIndex);
+ },
+
+ // fastScroll: Boolean
+ // flag modifies vertical scrolling behavior. Defaults to true but set to false for slower
+ // scroll performance but more immediate scrolling feedback
+ fastScroll: true,
+
+ delayScroll: false,
+
+ // scrollRedrawThreshold: int
+ // pixel distance a user must scroll vertically to trigger grid scrolling.
+ scrollRedrawThreshold: (dojo.isIE ? 100 : 50),
+
+ // scroll methods
+ scrollTo: function(inTop){
+ // summary:
+ // Vertically scroll the grid to a given pixel position
+ // inTop: Integer
+ // vertical position of the grid in pixels
+ if(!this.fastScroll){
+ this.setScrollTop(inTop);
+ return;
+ }
+ var delta = Math.abs(this.lastScrollTop - inTop);
+ this.lastScrollTop = inTop;
+ if(delta > this.scrollRedrawThreshold || this.delayScroll){
+ this.delayScroll = true;
+ this.scrollTop = inTop;
+ this.views.setScrollTop(inTop);
+ if(this._pendingScroll){
+ window.clearTimeout(this._pendingScroll);
+ }
+ var _this = this;
+ this._pendingScroll = window.setTimeout(function(){
+ delete _this._pendingScroll;
+ _this.finishScrollJob();
+ }, 200);
+ }else{
+ this.setScrollTop(inTop);
+ }
+ },
+
+ finishScrollJob: function(){
+ this.delayScroll = false;
+ this.setScrollTop(this.scrollTop);
+ },
+
+ setScrollTop: function(inTop){
+ this.scroller.scroll(this.views.setScrollTop(inTop));
+ },
+
+ scrollToRow: function(inRowIndex){
+ // summary:
+ // Scroll the grid to a specific row.
+ // inRowIndex: Integer
+ // grid row index
+ this.setScrollTop(this.scroller.findScrollTop(inRowIndex) + 1);
+ },
+
+ // styling (private, used internally to style individual parts of a row)
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ this.rows.styleRowNode(inRowIndex, inRowNode);
+ }
+ },
+
+ // called when the mouse leaves the grid so we can deselect all hover rows
+ _mouseOut: function(e){
+ this.rows.setOverRow(-2);
+ },
+
+ // cells
+ getCell: function(inIndex){
+ // summary:
+ // Retrieves the cell object for a given grid column.
+ // inIndex: Integer
+ // Grid column index of cell to retrieve
+ // returns:
+ // a grid cell
+ return this.layout.cells[inIndex];
+ },
+
+ setCellWidth: function(inIndex, inUnitWidth){
+ this.getCell(inIndex).unitWidth = inUnitWidth;
+ },
+
+ getCellName: function(inCell){
+ // summary: Returns the cell name of a passed cell
+ return "Cell " + inCell.index; // String
+ },
+
+ // sorting
+ canSort: function(inSortInfo){
+ // summary:
+ // Determines if the grid can be sorted
+ // inSortInfo: Integer
+ // Sort information, 1-based index of column on which to sort, positive for an ascending sort
+ // and negative for a descending sort
+ // returns: Boolean
+ // True if grid can be sorted on the given column in the given direction
+ },
+
+ sort: function(){
+ },
+
+ getSortAsc: function(inSortInfo){
+ // summary:
+ // Returns true if grid is sorted in an ascending direction.
+ inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo;
+ return Boolean(inSortInfo > 0); // Boolean
+ },
+
+ getSortIndex: function(inSortInfo){
+ // summary:
+ // Returns the index of the column on which the grid is sorted
+ inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo;
+ return Math.abs(inSortInfo) - 1; // Integer
+ },
+
+ setSortIndex: function(inIndex, inAsc){
+ // summary:
+ // Sort the grid on a column in a specified direction
+ // inIndex: Integer
+ // Column index on which to sort.
+ // inAsc: Boolean
+ // If true, sort the grid in ascending order, otherwise in descending order
+ var si = inIndex +1;
+ if(inAsc != undefined){
+ si *= (inAsc ? 1 : -1);
+ } else if(this.getSortIndex() == inIndex){
+ si = -this.sortInfo;
+ }
+ this.setSortInfo(si);
+ },
+
+ setSortInfo: function(inSortInfo){
+ if(this.canSort(inSortInfo)){
+ this.sortInfo = inSortInfo;
+ this.sort();
+ this.update();
+ }
+ },
+
+ // DOM event handler
+ doKeyEvent: function(e){
+ e.dispatch = 'do' + e.type;
+ this.onKeyEvent(e);
+ },
+
+ // event dispatch
+ //: protected
+ _dispatch: function(m, e){
+ if(m in this){
+ return this[m](e);
+ }
+ return false;
+ },
+
+ dispatchKeyEvent: function(e){
+ this._dispatch(e.dispatch, e);
+ },
+
+ dispatchContentEvent: function(e){
+ this.edit.dispatchEvent(e) || e.sourceView.dispatchContentEvent(e) || this._dispatch(e.dispatch, e);
+ },
+
+ dispatchHeaderEvent: function(e){
+ e.sourceView.dispatchHeaderEvent(e) || this._dispatch('doheader' + e.type, e);
+ },
+
+ dokeydown: function(e){
+ this.onKeyDown(e);
+ },
+
+ doclick: function(e){
+ if(e.cellNode){
+ this.onCellClick(e);
+ }else{
+ this.onRowClick(e);
+ }
+ },
+
+ dodblclick: function(e){
+ if(e.cellNode){
+ this.onCellDblClick(e);
+ }else{
+ this.onRowDblClick(e);
+ }
+ },
+
+ docontextmenu: function(e){
+ if(e.cellNode){
+ this.onCellContextMenu(e);
+ }else{
+ this.onRowContextMenu(e);
+ }
+ },
+
+ doheaderclick: function(e){
+ if(e.cellNode){
+ this.onHeaderCellClick(e);
+ }else{
+ this.onHeaderClick(e);
+ }
+ },
+
+ doheaderdblclick: function(e){
+ if(e.cellNode){
+ this.onHeaderCellDblClick(e);
+ }else{
+ this.onHeaderDblClick(e);
+ }
+ },
+
+ doheadercontextmenu: function(e){
+ if(e.cellNode){
+ this.onHeaderCellContextMenu(e);
+ }else{
+ this.onHeaderContextMenu(e);
+ }
+ },
+
+ // override to modify editing process
+ doStartEdit: function(inCell, inRowIndex){
+ this.onStartEdit(inCell, inRowIndex);
+ },
+
+ doApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
+ this.onApplyCellEdit(inValue, inRowIndex, inFieldIndex);
+ },
+
+ doCancelEdit: function(inRowIndex){
+ this.onCancelEdit(inRowIndex);
+ },
+
+ doApplyEdit: function(inRowIndex){
+ this.onApplyEdit(inRowIndex);
+ },
+
+ // row editing
+ addRow: function(){
+ // summary:
+ // Add a row to the grid.
+ this.updateRowCount(this.get('rowCount')+1);
+ },
+
+ removeSelectedRows: function(){
+ // summary:
+ // Remove the selected rows from the grid.
+ if(this.allItemsSelected){
+ this.updateRowCount(0);
+ }else{
+ this.updateRowCount(Math.max(0, this.get('rowCount') - this.selection.getSelected().length));
+ }
+ this.selection.clear();
+ }
+
+ });
+
+ dojox.grid._Grid.markupFactory = function(props, node, ctor, cellFunc){
+ var d = dojo;
+ var widthFromAttr = function(n){
+ var w = d.attr(n, "width")||"auto";
+ if((w != "auto")&&(w.slice(-2) != "em")&&(w.slice(-1) != "%")){
+ w = parseInt(w, 10)+"px";
+ }
+ return w;
+ };
+ // if(!props.store){ console.debug("no store!"); }
+ // if a structure isn't referenced, do we have enough
+ // data to try to build one automatically?
+ if( !props.structure &&
+ node.nodeName.toLowerCase() == "table"){
+
+ // try to discover a structure
+ props.structure = d.query("> colgroup", node).map(function(cg){
+ var sv = d.attr(cg, "span");
+ var v = {
+ noscroll: (d.attr(cg, "noscroll") == "true") ? true : false,
+ __span: (!!sv ? parseInt(sv, 10) : 1),
+ cells: []
+ };
+ if(d.hasAttr(cg, "width")){
+ v.width = widthFromAttr(cg);
+ }
+ return v; // for vendetta
+ });
+ if(!props.structure.length){
+ props.structure.push({
+ __span: Infinity,
+ cells: [] // catch-all view
+ });
+ }
+ // check to see if we're gonna have more than one view
+
+ // for each tr in our th, create a row of cells
+ d.query("thead > tr", node).forEach(function(tr, tr_idx){
+ var cellCount = 0;
+ var viewIdx = 0;
+ var lastViewIdx;
+ var cView = null;
+ d.query("> th", tr).map(function(th){
+ // what view will this cell go into?
+
+ // NOTE:
+ // to prevent extraneous iteration, we start counters over
+ // for each row, incrementing over the surface area of the
+ // structure that colgroup processing generates and
+ // creating cell objects for each <th> to place into those
+ // cell groups. There's a lot of state-keepking logic
+ // here, but it is what it has to be.
+ if(!cView){ // current view book keeping
+ lastViewIdx = 0;
+ cView = props.structure[0];
+ }else if(cellCount >= (lastViewIdx+cView.__span)){
+ viewIdx++;
+ // move to allocating things into the next view
+ lastViewIdx += cView.__span;
+ var lastView = cView;
+ cView = props.structure[viewIdx];
+ }
+
+ // actually define the cell from what markup hands us
+ var cell = {
+ name: d.trim(d.attr(th, "name")||th.innerHTML),
+ colSpan: parseInt(d.attr(th, "colspan")||1, 10),
+ type: d.trim(d.attr(th, "cellType")||""),
+ id: d.trim(d.attr(th,"id")||"")
+ };
+ cellCount += cell.colSpan;
+ var rowSpan = d.attr(th, "rowspan");
+ if(rowSpan){
+ cell.rowSpan = rowSpan;
+ }
+ if(d.hasAttr(th, "width")){
+ cell.width = widthFromAttr(th);
+ }
+ if(d.hasAttr(th, "relWidth")){
+ cell.relWidth = window.parseInt(dojo.attr(th, "relWidth"), 10);
+ }
+ if(d.hasAttr(th, "hidden")){
+ cell.hidden = (d.attr(th, "hidden") == "true" || d.attr(th, "hidden") === true/*always boolean true in Chrome*/);
+ }
+
+ if(cellFunc){
+ cellFunc(th, cell);
+ }
+
+ cell.type = cell.type ? dojo.getObject(cell.type) : dojox.grid.cells.Cell;
+
+ if(cell.type && cell.type.markupFactory){
+ cell.type.markupFactory(th, cell);
+ }
+
+ if(!cView.cells[tr_idx]){
+ cView.cells[tr_idx] = [];
+ }
+ cView.cells[tr_idx].push(cell);
+ });
+ });
+ }
+
+ return new ctor(props, node);
+ };
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/_Grid.xd.js b/js/dojo-1.6/dojox/grid/_Grid.xd.js
new file mode 100644
index 0000000..a096802
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_Grid.xd.js
@@ -0,0 +1,1401 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid._Grid"],
+["require", "dijit.dijit"],
+["require", "dijit.Menu"],
+["require", "dojox.html.metrics"],
+["require", "dojox.grid.util"],
+["require", "dojox.grid._Scroller"],
+["require", "dojox.grid._Layout"],
+["require", "dojox.grid._View"],
+["require", "dojox.grid._ViewManager"],
+["require", "dojox.grid._RowManager"],
+["require", "dojox.grid._FocusManager"],
+["require", "dojox.grid._EditManager"],
+["require", "dojox.grid.Selection"],
+["require", "dojox.grid._RowSelector"],
+["require", "dojox.grid._Events"],
+["requireLocalization", "dijit", "loading", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw", "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid._Grid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Grid"] = true;
+dojo.provide("dojox.grid._Grid");
+
+dojo.require("dijit.dijit");
+dojo.require("dijit.Menu");
+
+dojo.require("dojox.html.metrics");
+dojo.require("dojox.grid.util");
+dojo.require("dojox.grid._Scroller");
+dojo.require("dojox.grid._Layout");
+dojo.require("dojox.grid._View");
+dojo.require("dojox.grid._ViewManager");
+dojo.require("dojox.grid._RowManager");
+dojo.require("dojox.grid._FocusManager");
+dojo.require("dojox.grid._EditManager");
+dojo.require("dojox.grid.Selection");
+dojo.require("dojox.grid._RowSelector");
+dojo.require("dojox.grid._Events");
+
+
+;
+
+(function(){
+ // NOTE: this is for backwards compatibility with Dojo 1.3
+ if(!dojo.isCopyKey){
+ dojo.isCopyKey = dojo.dnd.getCopyKeyState;
+ }
+ /*=====
+ dojox.grid.__CellDef = function(){
+ // name: String?
+ // The text to use in the header of the grid for this cell.
+ // get: Function?
+ // function(rowIndex){} rowIndex is of type Integer. This
+ // function will be called when a cell requests data. Returns the
+ // unformatted data for the cell.
+ // value: String?
+ // If "get" is not specified, this is used as the data for the cell.
+ // defaultValue: String?
+ // If "get" and "value" aren't specified or if "get" returns an undefined
+ // value, this is used as the data for the cell. "formatter" is not run
+ // on this if "get" returns an undefined value.
+ // formatter: Function?
+ // function(data, rowIndex){} data is of type anything, rowIndex
+ // is of type Integer. This function will be called after the cell
+ // has its data but before it passes it back to the grid to render.
+ // Returns the formatted version of the cell's data.
+ // type: dojox.grid.cells._Base|Function?
+ // TODO
+ // editable: Boolean?
+ // Whether this cell should be editable or not.
+ // hidden: Boolean?
+ // If true, the cell will not be displayed.
+ // noresize: Boolean?
+ // If true, the cell will not be able to be resized.
+ // width: Integer|String?
+ // A CSS size. If it's an Integer, the width will be in em's.
+ // colSpan: Integer?
+ // How many columns to span this cell. Will not work in the first
+ // sub-row of cells.
+ // rowSpan: Integer?
+ // How many sub-rows to span this cell.
+ // styles: String?
+ // A string of styles to apply to both the header cell and main
+ // grid cells. Must end in a ';'.
+ // headerStyles: String?
+ // A string of styles to apply to just the header cell. Must end
+ // in a ';'
+ // cellStyles: String?
+ // A string of styles to apply to just the main grid cells. Must
+ // end in a ';'
+ // classes: String?
+ // A space separated list of classes to apply to both the header
+ // cell and the main grid cells.
+ // headerClasses: String?
+ // A space separated list of classes to apply to just the header
+ // cell.
+ // cellClasses: String?
+ // A space separated list of classes to apply to just the main
+ // grid cells.
+ // attrs: String?
+ // A space separated string of attribute='value' pairs to add to
+ // the header cell element and main grid cell elements.
+ this.name = name;
+ this.value = value;
+ this.get = get;
+ this.formatter = formatter;
+ this.type = type;
+ this.editable = editable;
+ this.hidden = hidden;
+ this.width = width;
+ this.colSpan = colSpan;
+ this.rowSpan = rowSpan;
+ this.styles = styles;
+ this.headerStyles = headerStyles;
+ this.cellStyles = cellStyles;
+ this.classes = classes;
+ this.headerClasses = headerClasses;
+ this.cellClasses = cellClasses;
+ this.attrs = attrs;
+ }
+ =====*/
+
+ /*=====
+ dojox.grid.__ViewDef = function(){
+ // noscroll: Boolean?
+ // If true, no scrollbars will be rendered without scrollbars.
+ // width: Integer|String?
+ // A CSS size. If it's an Integer, the width will be in em's. If
+ // "noscroll" is true, this value is ignored.
+ // cells: dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]?
+ // The structure of the cells within this grid.
+ // type: String?
+ // A string containing the constructor of a subclass of
+ // dojox.grid._View. If this is not specified, dojox.grid._View
+ // is used.
+ // defaultCell: dojox.grid.__CellDef?
+ // A cell definition with default values for all cells in this view. If
+ // a property is defined in a cell definition in the "cells" array and
+ // this property, the cell definition's property will override this
+ // property's property.
+ // onBeforeRow: Function?
+ // function(rowIndex, cells){} rowIndex is of type Integer, cells
+ // is of type Array[dojox.grid.__CellDef[]]. This function is called
+ // before each row of data is rendered. Before the header is
+ // rendered, rowIndex will be -1. "cells" is a reference to the
+ // internal structure of this view's cells so any changes you make to
+ // it will persist between calls.
+ // onAfterRow: Function?
+ // function(rowIndex, cells, rowNode){} rowIndex is of type Integer, cells
+ // is of type Array[dojox.grid.__CellDef[]], rowNode is of type DOMNode.
+ // This function is called after each row of data is rendered. After the
+ // header is rendered, rowIndex will be -1. "cells" is a reference to the
+ // internal structure of this view's cells so any changes you make to
+ // it will persist between calls.
+ this.noscroll = noscroll;
+ this.width = width;
+ this.cells = cells;
+ this.type = type;
+ this.defaultCell = defaultCell;
+ this.onBeforeRow = onBeforeRow;
+ this.onAfterRow = onAfterRow;
+ }
+ =====*/
+
+ dojo.declare('dojox.grid._Grid',
+ [ dijit._Widget, dijit._Templated, dojox.grid._Events ],
+ {
+ // summary:
+ // A grid widget with virtual scrolling, cell editing, complex rows,
+ // sorting, fixed columns, sizeable columns, etc.
+ //
+ // description:
+ // _Grid provides the full set of grid features without any
+ // direct connection to a data store.
+ //
+ // The grid exposes a get function for the grid, or optionally
+ // individual columns, to populate cell contents.
+ //
+ // The grid is rendered based on its structure, an object describing
+ // column and cell layout.
+ //
+ // example:
+ // A quick sample:
+ //
+ // define a get function
+ // | function get(inRowIndex){ // called in cell context
+ // | return [this.index, inRowIndex].join(', ');
+ // | }
+ //
+ // define the grid structure:
+ // | var structure = [ // array of view objects
+ // | { cells: [// array of rows, a row is an array of cells
+ // | [
+ // | { name: "Alpha", width: 6 },
+ // | { name: "Beta" },
+ // | { name: "Gamma", get: get }]
+ // | ]}
+ // | ];
+ //
+ // | <div id="grid"
+ // | rowCount="100" get="get"
+ // | structure="structure"
+ // | dojoType="dojox.grid._Grid"></div>
+
+ templateString:"<div hidefocus=\"hidefocus\" role=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\r\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" role=\"presentation\"></div>\r\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" role=\"presentation\"></div>\r\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\r\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\r\n</div>\r\n",
+
+ // classTag: String
+ // CSS class applied to the grid's domNode
+ classTag: 'dojoxGrid',
+
+ // settings
+ // rowCount: Integer
+ // Number of rows to display.
+ rowCount: 5,
+
+ // keepRows: Integer
+ // Number of rows to keep in the rendering cache.
+ keepRows: 75,
+
+ // rowsPerPage: Integer
+ // Number of rows to render at a time.
+ rowsPerPage: 25,
+
+ // autoWidth: Boolean
+ // If autoWidth is true, grid width is automatically set to fit the data.
+ autoWidth: false,
+
+ // initialWidth: String
+ // A css string to use to set our initial width (only used if autoWidth
+ // is true). The first rendering of the grid will be this width, any
+ // resizing of columns, etc will result in the grid switching to
+ // autoWidth mode. Note, this width will override any styling in a
+ // stylesheet or directly on the node.
+ initialWidth: "",
+
+ // autoHeight: Boolean|Integer
+ // If autoHeight is true, grid height is automatically set to fit the data.
+ // If it is an integer, the height will be automatically set to fit the data
+ // if there are fewer than that many rows - and the height will be set to show
+ // that many rows if there are more
+ autoHeight: '',
+
+ // rowHeight: Integer
+ // If rowHeight is set to a positive number, it will define the height of the rows
+ // in pixels. This can provide a significant performance advantage, since it
+ // eliminates the need to measure row sizes during rendering, which is one
+ // the primary bottlenecks in the DataGrid's performance.
+ rowHeight: 0,
+
+ // autoRender: Boolean
+ // If autoRender is true, grid will render itself after initialization.
+ autoRender: true,
+
+ // defaultHeight: String
+ // default height of the grid, measured in any valid css unit.
+ defaultHeight: '15em',
+
+ // height: String
+ // explicit height of the grid, measured in any valid css unit. This will be populated (and overridden)
+ // if the height: css attribute exists on the source node.
+ height: '',
+
+ // structure: dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]
+ // View layout defintion.
+ structure: null,
+
+ // elasticView: Integer
+ // Override defaults and make the indexed grid view elastic, thus filling available horizontal space.
+ elasticView: -1,
+
+ // singleClickEdit: boolean
+ // Single-click starts editing. Default is double-click
+ singleClickEdit: false,
+
+ // selectionMode: String
+ // Set the selection mode of grid's Selection. Value must be 'single', 'multiple',
+ // or 'extended'. Default is 'extended'.
+ selectionMode: 'extended',
+
+ // rowSelector: Boolean|String
+ // If set to true, will add a row selector view to this grid. If set to a CSS width, will add
+ // a row selector of that width to this grid.
+ rowSelector: '',
+
+ // columnReordering: Boolean
+ // If set to true, will add drag and drop reordering to views with one row of columns.
+ columnReordering: false,
+
+ // headerMenu: dijit.Menu
+ // If set to a dijit.Menu, will use this as a context menu for the grid headers.
+ headerMenu: null,
+
+ // placeholderLabel: String
+ // Label of placeholders to search for in the header menu to replace with column toggling
+ // menu items.
+ placeholderLabel: "GridColumns",
+
+ // selectable: Boolean
+ // Set to true if you want to be able to select the text within the grid.
+ selectable: false,
+
+ // Used to store the last two clicks, to ensure double-clicking occurs based on the intended row
+ _click: null,
+
+ // loadingMessage: String
+ // Message that shows while the grid is loading
+ loadingMessage: "<span class='dojoxGridLoading'>${loadingState}</span>",
+
+ // errorMessage: String
+ // Message that shows when the grid encounters an error loading
+ errorMessage: "<span class='dojoxGridError'>${errorState}</span>",
+
+ // noDataMessage: String
+ // Message that shows if the grid has no data - wrap it in a
+ // span with class 'dojoxGridNoData' if you want it to be
+ // styled similar to the loading and error messages
+ noDataMessage: "",
+
+ // escapeHTMLInData: Boolean
+ // This will escape HTML brackets from the data to prevent HTML from
+ // user-inputted data being rendered with may contain JavaScript and result in
+ // XSS attacks. This is true by default, and it is recommended that it remain
+ // true. Setting this to false will allow data to be displayed in the grid without
+ // filtering, and should be only used if it is known that the data won't contain
+ // malicious scripts. If HTML is needed in grid cells, it is recommended that
+ // you use the formatter function to generate the HTML (the output of
+ // formatter functions is not filtered, even with escapeHTMLInData set to true).
+ escapeHTMLInData: true,
+
+ // formatterScope: Object
+ // An object to execute format functions within. If not set, the
+ // format functions will execute within the scope of the cell that
+ // has a format function.
+ formatterScope: null,
+
+ // editable: boolean
+ // indicates if the grid contains editable cells, default is false
+ // set to true if editable cell encountered during rendering
+ editable: false,
+
+ // private
+ sortInfo: 0,
+ themeable: true,
+ _placeholders: null,
+
+ // _layoutClass: Object
+ // The class to use for our layout - can be overridden by grid subclasses
+ _layoutClass: dojox.grid._Layout,
+
+ // initialization
+ buildRendering: function(){
+ this.inherited(arguments);
+ if(!this.domNode.getAttribute('tabIndex')){
+ this.domNode.tabIndex = "0";
+ }
+ this.createScroller();
+ this.createLayout();
+ this.createViews();
+ this.createManagers();
+
+ this.createSelection();
+
+ this.connect(this.selection, "onSelected", "onSelected");
+ this.connect(this.selection, "onDeselected", "onDeselected");
+ this.connect(this.selection, "onChanged", "onSelectionChanged");
+
+ dojox.html.metrics.initOnFontResize();
+ this.connect(dojox.html.metrics, "onFontResize", "textSizeChanged");
+ dojox.grid.util.funnelEvents(this.domNode, this, 'doKeyEvent', dojox.grid.util.keyEvents);
+ if (this.selectionMode != "none") {
+ dojo.attr(this.domNode, "aria-multiselectable", this.selectionMode == "single" ? "false" : "true");
+ }
+
+ dojo.addClass(this.domNode, this.classTag);
+ if(!this.isLeftToRight()){
+ dojo.addClass(this.domNode, this.classTag+"Rtl");
+ }
+ },
+
+ postMixInProperties: function(){
+ this.inherited(arguments);
+ var messages = dojo.i18n.getLocalization("dijit", "loading", this.lang);
+ this.loadingMessage = dojo.string.substitute(this.loadingMessage, messages);
+ this.errorMessage = dojo.string.substitute(this.errorMessage, messages);
+ if(this.srcNodeRef && this.srcNodeRef.style.height){
+ this.height = this.srcNodeRef.style.height;
+ }
+ // Call this to update our autoheight to start out
+ this._setAutoHeightAttr(this.autoHeight, true);
+ this.lastScrollTop = this.scrollTop = 0;
+ },
+
+ postCreate: function(){
+ this._placeholders = [];
+ this._setHeaderMenuAttr(this.headerMenu);
+ this._setStructureAttr(this.structure);
+ this._click = [];
+ this.inherited(arguments);
+ if(this.domNode && this.autoWidth && this.initialWidth){
+ this.domNode.style.width = this.initialWidth;
+ }
+ if (this.domNode && !this.editable){
+ // default value for aria-readonly is false, set to true if grid is not editable
+ dojo.attr(this.domNode,"aria-readonly", "true");
+ }
+ },
+
+ destroy: function(){
+ this.domNode.onReveal = null;
+ this.domNode.onSizeChange = null;
+
+ // Fixes IE domNode leak
+ delete this._click;
+
+ this.edit.destroy();
+ delete this.edit;
+
+ this.views.destroyViews();
+ if(this.scroller){
+ this.scroller.destroy();
+ delete this.scroller;
+ }
+ if(this.focus){
+ this.focus.destroy();
+ delete this.focus;
+ }
+ if(this.headerMenu&&this._placeholders.length){
+ dojo.forEach(this._placeholders, function(p){ p.unReplace(true); });
+ this.headerMenu.unBindDomNode(this.viewsHeaderNode);
+ }
+ this.inherited(arguments);
+ },
+
+ _setAutoHeightAttr: function(ah, skipRender){
+ // Calculate our autoheight - turn it into a boolean or an integer
+ if(typeof ah == "string"){
+ if(!ah || ah == "false"){
+ ah = false;
+ }else if (ah == "true"){
+ ah = true;
+ }else{
+ ah = window.parseInt(ah, 10);
+ }
+ }
+ if(typeof ah == "number"){
+ if(isNaN(ah)){
+ ah = false;
+ }
+ // Autoheight must be at least 1, if it's a number. If it's
+ // less than 0, we'll take that to mean "all" rows (same as
+ // autoHeight=true - if it is equal to zero, we'll take that
+ // to mean autoHeight=false
+ if(ah < 0){
+ ah = true;
+ }else if (ah === 0){
+ ah = false;
+ }
+ }
+ this.autoHeight = ah;
+ if(typeof ah == "boolean"){
+ this._autoHeight = ah;
+ }else if(typeof ah == "number"){
+ this._autoHeight = (ah >= this.get('rowCount'));
+ }else{
+ this._autoHeight = false;
+ }
+ if(this._started && !skipRender){
+ this.render();
+ }
+ },
+
+ _getRowCountAttr: function(){
+ return this.updating && this.invalidated && this.invalidated.rowCount != undefined ?
+ this.invalidated.rowCount : this.rowCount;
+ },
+
+ textSizeChanged: function(){
+ this.render();
+ },
+
+ sizeChange: function(){
+ this.update();
+ },
+
+ createManagers: function(){
+ // summary:
+ // create grid managers for various tasks including rows, focus, selection, editing
+
+ // row manager
+ this.rows = new dojox.grid._RowManager(this);
+ // focus manager
+ this.focus = new dojox.grid._FocusManager(this);
+ // edit manager
+ this.edit = new dojox.grid._EditManager(this);
+ },
+
+ createSelection: function(){
+ // summary: Creates a new Grid selection manager.
+
+ // selection manager
+ this.selection = new dojox.grid.Selection(this);
+ },
+
+ createScroller: function(){
+ // summary: Creates a new virtual scroller
+ this.scroller = new dojox.grid._Scroller();
+ this.scroller.grid = this;
+ this.scroller.renderRow = dojo.hitch(this, "renderRow");
+ this.scroller.removeRow = dojo.hitch(this, "rowRemoved");
+ },
+
+ createLayout: function(){
+ // summary: Creates a new Grid layout
+ this.layout = new this._layoutClass(this);
+ this.connect(this.layout, "moveColumn", "onMoveColumn");
+ },
+
+ onMoveColumn: function(){
+ this.render();
+ },
+
+ onResizeColumn: function(/*int*/ cellIdx){
+ // Called when a column is resized.
+ },
+
+ // views
+ createViews: function(){
+ this.views = new dojox.grid._ViewManager(this);
+ this.views.createView = dojo.hitch(this, "createView");
+ },
+
+ createView: function(inClass, idx){
+ var c = dojo.getObject(inClass);
+ var view = new c({ grid: this, index: idx });
+ this.viewsNode.appendChild(view.domNode);
+ this.viewsHeaderNode.appendChild(view.headerNode);
+ this.views.addView(view);
+ dojo.attr(this.domNode, "align", dojo._isBodyLtr() ? 'left' : 'right');
+ return view;
+ },
+
+ buildViews: function(){
+ for(var i=0, vs; (vs=this.layout.structure[i]); i++){
+ this.createView(vs.type || dojox._scopeName + ".grid._View", i).setStructure(vs);
+ }
+ this.scroller.setContentNodes(this.views.getContentNodes());
+ },
+
+ _setStructureAttr: function(structure){
+ var s = structure;
+ if(s && dojo.isString(s)){
+ dojo.deprecated("dojox.grid._Grid.set('structure', 'objVar')", "use dojox.grid._Grid.set('structure', objVar) instead", "2.0");
+ s=dojo.getObject(s);
+ }
+ this.structure = s;
+ if(!s){
+ if(this.layout.structure){
+ s = this.layout.structure;
+ }else{
+ return;
+ }
+ }
+ this.views.destroyViews();
+ if(s !== this.layout.structure){
+ this.layout.setStructure(s);
+ }
+ this._structureChanged();
+ },
+
+ setStructure: function(/* dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]] */ inStructure){
+ // summary:
+ // Install a new structure and rebuild the grid.
+ dojo.deprecated("dojox.grid._Grid.setStructure(obj)", "use dojox.grid._Grid.set('structure', obj) instead.", "2.0");
+ this._setStructureAttr(inStructure);
+ },
+
+ getColumnTogglingItems: function(){
+ // Summary: returns an array of dijit.CheckedMenuItem widgets that can be
+ // added to a menu for toggling columns on and off.
+ return dojo.map(this.layout.cells, function(cell){
+ if(!cell.menuItems){ cell.menuItems = []; }
+
+ var self = this;
+ var item = new dijit.CheckedMenuItem({
+ label: cell.name,
+ checked: !cell.hidden,
+ _gridCell: cell,
+ onChange: function(checked){
+ if(self.layout.setColumnVisibility(this._gridCell.index, checked)){
+ var items = this._gridCell.menuItems;
+ if(items.length > 1){
+ dojo.forEach(items, function(item){
+ if(item !== this){
+ item.setAttribute("checked", checked);
+ }
+ }, this);
+ }
+ checked = dojo.filter(self.layout.cells, function(c){
+ if(c.menuItems.length > 1){
+ dojo.forEach(c.menuItems, "item.set('disabled', false);");
+ }else{
+ c.menuItems[0].set('disabled', false);
+ }
+ return !c.hidden;
+ });
+ if(checked.length == 1){
+ dojo.forEach(checked[0].menuItems, "item.set('disabled', true);");
+ }
+ }
+ },
+ destroy: function(){
+ var index = dojo.indexOf(this._gridCell.menuItems, this);
+ this._gridCell.menuItems.splice(index, 1);
+ delete this._gridCell;
+ dijit.CheckedMenuItem.prototype.destroy.apply(this, arguments);
+ }
+ });
+ cell.menuItems.push(item);
+ return item;
+ }, this); // dijit.CheckedMenuItem[]
+ },
+
+ _setHeaderMenuAttr: function(menu){
+ if(this._placeholders && this._placeholders.length){
+ dojo.forEach(this._placeholders, function(p){
+ p.unReplace(true);
+ });
+ this._placeholders = [];
+ }
+ if(this.headerMenu){
+ this.headerMenu.unBindDomNode(this.viewsHeaderNode);
+ }
+ this.headerMenu = menu;
+ if(!menu){ return; }
+
+ this.headerMenu.bindDomNode(this.viewsHeaderNode);
+ if(this.headerMenu.getPlaceholders){
+ this._placeholders = this.headerMenu.getPlaceholders(this.placeholderLabel);
+ }
+ },
+
+ setHeaderMenu: function(/* dijit.Menu */ menu){
+ dojo.deprecated("dojox.grid._Grid.setHeaderMenu(obj)", "use dojox.grid._Grid.set('headerMenu', obj) instead.", "2.0");
+ this._setHeaderMenuAttr(menu);
+ },
+
+ setupHeaderMenu: function(){
+ if(this._placeholders && this._placeholders.length){
+ dojo.forEach(this._placeholders, function(p){
+ if(p._replaced){
+ p.unReplace(true);
+ }
+ p.replace(this.getColumnTogglingItems());
+ }, this);
+ }
+ },
+
+ _fetch: function(start){
+ this.setScrollTop(0);
+ },
+
+ getItem: function(inRowIndex){
+ return null;
+ },
+
+ showMessage: function(message){
+ if(message){
+ this.messagesNode.innerHTML = message;
+ this.messagesNode.style.display = "";
+ }else{
+ this.messagesNode.innerHTML = "";
+ this.messagesNode.style.display = "none";
+ }
+ },
+
+ _structureChanged: function() {
+ this.buildViews();
+ if(this.autoRender && this._started){
+ this.render();
+ }
+ },
+
+ hasLayout: function() {
+ return this.layout.cells.length;
+ },
+
+ // sizing
+ resize: function(changeSize, resultSize){
+ // summary:
+ // Update the grid's rendering dimensions and resize it
+
+ // Calling sizeChange calls update() which calls _resize...so let's
+ // save our input values, if any, and use them there when it gets
+ // called. This saves us an extra call to _resize(), which can
+ // get kind of heavy.
+ this._pendingChangeSize = changeSize;
+ this._pendingResultSize = resultSize;
+ this.sizeChange();
+ },
+
+ _getPadBorder: function() {
+ this._padBorder = this._padBorder || dojo._getPadBorderExtents(this.domNode);
+ return this._padBorder;
+ },
+
+ _getHeaderHeight: function(){
+ var vns = this.viewsHeaderNode.style, t = vns.display == "none" ? 0 : this.views.measureHeader();
+ vns.height = t + 'px';
+ // header heights are reset during measuring so must be normalized after measuring.
+ this.views.normalizeHeaderNodeHeight();
+ return t;
+ },
+
+ _resize: function(changeSize, resultSize){
+ // Restore our pending values, if any
+ changeSize = changeSize || this._pendingChangeSize;
+ resultSize = resultSize || this._pendingResultSize;
+ delete this._pendingChangeSize;
+ delete this._pendingResultSize;
+ // if we have set up everything except the DOM, we cannot resize
+ if(!this.domNode){ return; }
+ var pn = this.domNode.parentNode;
+ if(!pn || pn.nodeType != 1 || !this.hasLayout() || pn.style.visibility == "hidden" || pn.style.display == "none"){
+ return;
+ }
+ // useful measurement
+ var padBorder = this._getPadBorder();
+ var hh = undefined;
+ var h;
+ // grid height
+ if(this._autoHeight){
+ this.domNode.style.height = 'auto';
+ }else if(typeof this.autoHeight == "number"){
+ h = hh = this._getHeaderHeight();
+ h += (this.scroller.averageRowHeight * this.autoHeight);
+ this.domNode.style.height = h + "px";
+ }else if(this.domNode.clientHeight <= padBorder.h){
+ if(pn == document.body){
+ this.domNode.style.height = this.defaultHeight;
+ }else if(this.height){
+ this.domNode.style.height = this.height;
+ }else{
+ this.fitTo = "parent";
+ }
+ }
+ // if we are given dimensions, size the grid's domNode to those dimensions
+ if(resultSize){
+ changeSize = resultSize;
+ }
+ if(changeSize){
+ dojo.marginBox(this.domNode, changeSize);
+ this.height = this.domNode.style.height;
+ delete this.fitTo;
+ }else if(this.fitTo == "parent"){
+ h = this._parentContentBoxHeight = this._parentContentBoxHeight || dojo._getContentBox(pn).h;
+ this.domNode.style.height = Math.max(0, h) + "px";
+ }
+
+ var hasFlex = dojo.some(this.views.views, function(v){ return v.flexCells; });
+
+ if(!this._autoHeight && (h || dojo._getContentBox(this.domNode).h) === 0){
+ // We need to hide the header, since the Grid is essentially hidden.
+ this.viewsHeaderNode.style.display = "none";
+ }else{
+ // Otherwise, show the header and give it an appropriate height.
+ this.viewsHeaderNode.style.display = "block";
+ if(!hasFlex && hh === undefined){
+ hh = this._getHeaderHeight();
+ }
+ }
+ if(hasFlex){
+ hh = undefined;
+ }
+
+ // NOTE: it is essential that width be applied before height
+ // Header height can only be calculated properly after view widths have been set.
+ // This is because flex column width is naturally 0 in Firefox.
+ // Therefore prior to width sizing flex columns with spaces are maximally wrapped
+ // and calculated to be too tall.
+ this.adaptWidth();
+ this.adaptHeight(hh);
+
+ this.postresize();
+ },
+
+ adaptWidth: function() {
+ // private: sets width and position for views and update grid width if necessary
+ var doAutoWidth = (!this.initialWidth && this.autoWidth);
+ var w = doAutoWidth ? 0 : this.domNode.clientWidth || (this.domNode.offsetWidth - this._getPadBorder().w),
+ vw = this.views.arrange(1, w);
+ this.views.onEach("adaptWidth");
+ if(doAutoWidth){
+ this.domNode.style.width = vw + "px";
+ }
+ },
+
+ adaptHeight: function(inHeaderHeight){
+ // private: measures and normalizes header height, then sets view heights, and then updates scroller
+ // content extent
+ var t = inHeaderHeight === undefined ? this._getHeaderHeight() : inHeaderHeight;
+ var h = (this._autoHeight ? -1 : Math.max(this.domNode.clientHeight - t, 0) || 0);
+ this.views.onEach('setSize', [0, h]);
+ this.views.onEach('adaptHeight');
+ if(!this._autoHeight){
+ var numScroll = 0, numNoScroll = 0;
+ var noScrolls = dojo.filter(this.views.views, function(v){
+ var has = v.hasHScrollbar();
+ if(has){ numScroll++; }else{ numNoScroll++; }
+ return (!has);
+ });
+ if(numScroll > 0 && numNoScroll > 0){
+ dojo.forEach(noScrolls, function(v){
+ v.adaptHeight(true);
+ });
+ }
+ }
+ if(this.autoHeight === true || h != -1 || (typeof this.autoHeight == "number" && this.autoHeight >= this.get('rowCount'))){
+ this.scroller.windowHeight = h;
+ }else{
+ this.scroller.windowHeight = Math.max(this.domNode.clientHeight - t, 0);
+ }
+ },
+
+ // startup
+ startup: function(){
+ if(this._started){return;}
+ this.inherited(arguments);
+ if(this.autoRender){
+ this.render();
+ }
+ },
+
+ // render
+ render: function(){
+ // summary:
+ // Render the grid, headers, and views. Edit and scrolling states are reset. To retain edit and
+ // scrolling states, see Update.
+
+ if(!this.domNode){return;}
+ if(!this._started){return;}
+
+ if(!this.hasLayout()) {
+ this.scroller.init(0, this.keepRows, this.rowsPerPage);
+ return;
+ }
+ //
+ this.update = this.defaultUpdate;
+ this._render();
+ },
+
+ _render: function(){
+ this.scroller.init(this.get('rowCount'), this.keepRows, this.rowsPerPage);
+ this.prerender();
+ this.setScrollTop(0);
+ this.postrender();
+ },
+
+ prerender: function(){
+ // if autoHeight, make sure scroller knows not to virtualize; everything must be rendered.
+ this.keepRows = this._autoHeight ? 0 : this.keepRows;
+ this.scroller.setKeepInfo(this.keepRows);
+ this.views.render();
+ this._resize();
+ },
+
+ postrender: function(){
+ this.postresize();
+ this.focus.initFocusView();
+ // make rows unselectable
+ dojo.setSelectable(this.domNode, this.selectable);
+ },
+
+ postresize: function(){
+ // views are position absolute, so they do not inflate the parent
+ if(this._autoHeight){
+ var size = Math.max(this.views.measureContent()) + 'px';
+
+ this.viewsNode.style.height = size;
+ }
+ },
+
+ renderRow: function(inRowIndex, inNodes){
+ // summary: private, used internally to render rows
+ this.views.renderRow(inRowIndex, inNodes, this._skipRowRenormalize);
+ },
+
+ rowRemoved: function(inRowIndex){
+ // summary: private, used internally to remove rows
+ this.views.rowRemoved(inRowIndex);
+ },
+
+ invalidated: null,
+
+ updating: false,
+
+ beginUpdate: function(){
+ // summary:
+ // Use to make multiple changes to rows while queueing row updating.
+ // NOTE: not currently supporting nested begin/endUpdate calls
+ this.invalidated = [];
+ this.updating = true;
+ },
+
+ endUpdate: function(){
+ // summary:
+ // Use after calling beginUpdate to render any changes made to rows.
+ this.updating = false;
+ var i = this.invalidated, r;
+ if(i.all){
+ this.update();
+ }else if(i.rowCount != undefined){
+ this.updateRowCount(i.rowCount);
+ }else{
+ for(r in i){
+ this.updateRow(Number(r));
+ }
+ }
+ this.invalidated = [];
+ },
+
+ // update
+ defaultUpdate: function(){
+ // note: initial update calls render and subsequently this function.
+ if(!this.domNode){return;}
+ if(this.updating){
+ this.invalidated.all = true;
+ return;
+ }
+ //this.edit.saveState(inRowIndex);
+ this.lastScrollTop = this.scrollTop;
+ this.prerender();
+ this.scroller.invalidateNodes();
+ this.setScrollTop(this.lastScrollTop);
+ this.postrender();
+ //this.edit.restoreState(inRowIndex);
+ },
+
+ update: function(){
+ // summary:
+ // Update the grid, retaining edit and scrolling states.
+ this.render();
+ },
+
+ updateRow: function(inRowIndex){
+ // summary:
+ // Render a single row.
+ // inRowIndex: Integer
+ // Index of the row to render
+ inRowIndex = Number(inRowIndex);
+ if(this.updating){
+ this.invalidated[inRowIndex]=true;
+ }else{
+ this.views.updateRow(inRowIndex);
+ this.scroller.rowHeightChanged(inRowIndex);
+ }
+ },
+
+ updateRows: function(startIndex, howMany){
+ // summary:
+ // Render consecutive rows at once.
+ // startIndex: Integer
+ // Index of the starting row to render
+ // howMany: Integer
+ // How many rows to update.
+ startIndex = Number(startIndex);
+ howMany = Number(howMany);
+ var i;
+ if(this.updating){
+ for(i=0; i<howMany; i++){
+ this.invalidated[i+startIndex]=true;
+ }
+ }else{
+ for(i=0; i<howMany; i++){
+ this.views.updateRow(i+startIndex, this._skipRowRenormalize);
+ }
+ this.scroller.rowHeightChanged(startIndex);
+ }
+ },
+
+ updateRowCount: function(inRowCount){
+ //summary:
+ // Change the number of rows.
+ // inRowCount: int
+ // Number of rows in the grid.
+ if(this.updating){
+ this.invalidated.rowCount = inRowCount;
+ }else{
+ this.rowCount = inRowCount;
+ this._setAutoHeightAttr(this.autoHeight, true);
+ if(this.layout.cells.length){
+ this.scroller.updateRowCount(inRowCount);
+ }
+ this._resize();
+ if(this.layout.cells.length){
+ this.setScrollTop(this.scrollTop);
+ }
+ }
+ },
+
+ updateRowStyles: function(inRowIndex){
+ // summary:
+ // Update the styles for a row after it's state has changed.
+ this.views.updateRowStyles(inRowIndex);
+ },
+ getRowNode: function(inRowIndex){
+ // summary:
+ // find the rowNode that is not a rowSelector
+ if (this.focus.focusView && !(this.focus.focusView instanceof dojox.grid._RowSelector)){
+ return this.focus.focusView.rowNodes[inRowIndex];
+ }else{ // search through views
+ for (var i = 0, cView; (cView = this.views.views[i]); i++) {
+ if (!(cView instanceof dojox.grid._RowSelector)) {
+ return cView.rowNodes[inRowIndex];
+ }
+ }
+ }
+ return null;
+ },
+ rowHeightChanged: function(inRowIndex){
+ // summary:
+ // Update grid when the height of a row has changed. Row height is handled automatically as rows
+ // are rendered. Use this function only to update a row's height outside the normal rendering process.
+ // inRowIndex: Integer
+ // index of the row that has changed height
+
+ this.views.renormalizeRow(inRowIndex);
+ this.scroller.rowHeightChanged(inRowIndex);
+ },
+
+ // fastScroll: Boolean
+ // flag modifies vertical scrolling behavior. Defaults to true but set to false for slower
+ // scroll performance but more immediate scrolling feedback
+ fastScroll: true,
+
+ delayScroll: false,
+
+ // scrollRedrawThreshold: int
+ // pixel distance a user must scroll vertically to trigger grid scrolling.
+ scrollRedrawThreshold: (dojo.isIE ? 100 : 50),
+
+ // scroll methods
+ scrollTo: function(inTop){
+ // summary:
+ // Vertically scroll the grid to a given pixel position
+ // inTop: Integer
+ // vertical position of the grid in pixels
+ if(!this.fastScroll){
+ this.setScrollTop(inTop);
+ return;
+ }
+ var delta = Math.abs(this.lastScrollTop - inTop);
+ this.lastScrollTop = inTop;
+ if(delta > this.scrollRedrawThreshold || this.delayScroll){
+ this.delayScroll = true;
+ this.scrollTop = inTop;
+ this.views.setScrollTop(inTop);
+ if(this._pendingScroll){
+ window.clearTimeout(this._pendingScroll);
+ }
+ var _this = this;
+ this._pendingScroll = window.setTimeout(function(){
+ delete _this._pendingScroll;
+ _this.finishScrollJob();
+ }, 200);
+ }else{
+ this.setScrollTop(inTop);
+ }
+ },
+
+ finishScrollJob: function(){
+ this.delayScroll = false;
+ this.setScrollTop(this.scrollTop);
+ },
+
+ setScrollTop: function(inTop){
+ this.scroller.scroll(this.views.setScrollTop(inTop));
+ },
+
+ scrollToRow: function(inRowIndex){
+ // summary:
+ // Scroll the grid to a specific row.
+ // inRowIndex: Integer
+ // grid row index
+ this.setScrollTop(this.scroller.findScrollTop(inRowIndex) + 1);
+ },
+
+ // styling (private, used internally to style individual parts of a row)
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ this.rows.styleRowNode(inRowIndex, inRowNode);
+ }
+ },
+
+ // called when the mouse leaves the grid so we can deselect all hover rows
+ _mouseOut: function(e){
+ this.rows.setOverRow(-2);
+ },
+
+ // cells
+ getCell: function(inIndex){
+ // summary:
+ // Retrieves the cell object for a given grid column.
+ // inIndex: Integer
+ // Grid column index of cell to retrieve
+ // returns:
+ // a grid cell
+ return this.layout.cells[inIndex];
+ },
+
+ setCellWidth: function(inIndex, inUnitWidth){
+ this.getCell(inIndex).unitWidth = inUnitWidth;
+ },
+
+ getCellName: function(inCell){
+ // summary: Returns the cell name of a passed cell
+ return "Cell " + inCell.index; // String
+ },
+
+ // sorting
+ canSort: function(inSortInfo){
+ // summary:
+ // Determines if the grid can be sorted
+ // inSortInfo: Integer
+ // Sort information, 1-based index of column on which to sort, positive for an ascending sort
+ // and negative for a descending sort
+ // returns: Boolean
+ // True if grid can be sorted on the given column in the given direction
+ },
+
+ sort: function(){
+ },
+
+ getSortAsc: function(inSortInfo){
+ // summary:
+ // Returns true if grid is sorted in an ascending direction.
+ inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo;
+ return Boolean(inSortInfo > 0); // Boolean
+ },
+
+ getSortIndex: function(inSortInfo){
+ // summary:
+ // Returns the index of the column on which the grid is sorted
+ inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo;
+ return Math.abs(inSortInfo) - 1; // Integer
+ },
+
+ setSortIndex: function(inIndex, inAsc){
+ // summary:
+ // Sort the grid on a column in a specified direction
+ // inIndex: Integer
+ // Column index on which to sort.
+ // inAsc: Boolean
+ // If true, sort the grid in ascending order, otherwise in descending order
+ var si = inIndex +1;
+ if(inAsc != undefined){
+ si *= (inAsc ? 1 : -1);
+ } else if(this.getSortIndex() == inIndex){
+ si = -this.sortInfo;
+ }
+ this.setSortInfo(si);
+ },
+
+ setSortInfo: function(inSortInfo){
+ if(this.canSort(inSortInfo)){
+ this.sortInfo = inSortInfo;
+ this.sort();
+ this.update();
+ }
+ },
+
+ // DOM event handler
+ doKeyEvent: function(e){
+ e.dispatch = 'do' + e.type;
+ this.onKeyEvent(e);
+ },
+
+ // event dispatch
+ //: protected
+ _dispatch: function(m, e){
+ if(m in this){
+ return this[m](e);
+ }
+ return false;
+ },
+
+ dispatchKeyEvent: function(e){
+ this._dispatch(e.dispatch, e);
+ },
+
+ dispatchContentEvent: function(e){
+ this.edit.dispatchEvent(e) || e.sourceView.dispatchContentEvent(e) || this._dispatch(e.dispatch, e);
+ },
+
+ dispatchHeaderEvent: function(e){
+ e.sourceView.dispatchHeaderEvent(e) || this._dispatch('doheader' + e.type, e);
+ },
+
+ dokeydown: function(e){
+ this.onKeyDown(e);
+ },
+
+ doclick: function(e){
+ if(e.cellNode){
+ this.onCellClick(e);
+ }else{
+ this.onRowClick(e);
+ }
+ },
+
+ dodblclick: function(e){
+ if(e.cellNode){
+ this.onCellDblClick(e);
+ }else{
+ this.onRowDblClick(e);
+ }
+ },
+
+ docontextmenu: function(e){
+ if(e.cellNode){
+ this.onCellContextMenu(e);
+ }else{
+ this.onRowContextMenu(e);
+ }
+ },
+
+ doheaderclick: function(e){
+ if(e.cellNode){
+ this.onHeaderCellClick(e);
+ }else{
+ this.onHeaderClick(e);
+ }
+ },
+
+ doheaderdblclick: function(e){
+ if(e.cellNode){
+ this.onHeaderCellDblClick(e);
+ }else{
+ this.onHeaderDblClick(e);
+ }
+ },
+
+ doheadercontextmenu: function(e){
+ if(e.cellNode){
+ this.onHeaderCellContextMenu(e);
+ }else{
+ this.onHeaderContextMenu(e);
+ }
+ },
+
+ // override to modify editing process
+ doStartEdit: function(inCell, inRowIndex){
+ this.onStartEdit(inCell, inRowIndex);
+ },
+
+ doApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
+ this.onApplyCellEdit(inValue, inRowIndex, inFieldIndex);
+ },
+
+ doCancelEdit: function(inRowIndex){
+ this.onCancelEdit(inRowIndex);
+ },
+
+ doApplyEdit: function(inRowIndex){
+ this.onApplyEdit(inRowIndex);
+ },
+
+ // row editing
+ addRow: function(){
+ // summary:
+ // Add a row to the grid.
+ this.updateRowCount(this.get('rowCount')+1);
+ },
+
+ removeSelectedRows: function(){
+ // summary:
+ // Remove the selected rows from the grid.
+ if(this.allItemsSelected){
+ this.updateRowCount(0);
+ }else{
+ this.updateRowCount(Math.max(0, this.get('rowCount') - this.selection.getSelected().length));
+ }
+ this.selection.clear();
+ }
+
+ });
+
+ dojox.grid._Grid.markupFactory = function(props, node, ctor, cellFunc){
+ var d = dojo;
+ var widthFromAttr = function(n){
+ var w = d.attr(n, "width")||"auto";
+ if((w != "auto")&&(w.slice(-2) != "em")&&(w.slice(-1) != "%")){
+ w = parseInt(w, 10)+"px";
+ }
+ return w;
+ };
+ // if(!props.store){ console.debug("no store!"); }
+ // if a structure isn't referenced, do we have enough
+ // data to try to build one automatically?
+ if( !props.structure &&
+ node.nodeName.toLowerCase() == "table"){
+
+ // try to discover a structure
+ props.structure = d.query("> colgroup", node).map(function(cg){
+ var sv = d.attr(cg, "span");
+ var v = {
+ noscroll: (d.attr(cg, "noscroll") == "true") ? true : false,
+ __span: (!!sv ? parseInt(sv, 10) : 1),
+ cells: []
+ };
+ if(d.hasAttr(cg, "width")){
+ v.width = widthFromAttr(cg);
+ }
+ return v; // for vendetta
+ });
+ if(!props.structure.length){
+ props.structure.push({
+ __span: Infinity,
+ cells: [] // catch-all view
+ });
+ }
+ // check to see if we're gonna have more than one view
+
+ // for each tr in our th, create a row of cells
+ d.query("thead > tr", node).forEach(function(tr, tr_idx){
+ var cellCount = 0;
+ var viewIdx = 0;
+ var lastViewIdx;
+ var cView = null;
+ d.query("> th", tr).map(function(th){
+ // what view will this cell go into?
+
+ // NOTE:
+ // to prevent extraneous iteration, we start counters over
+ // for each row, incrementing over the surface area of the
+ // structure that colgroup processing generates and
+ // creating cell objects for each <th> to place into those
+ // cell groups. There's a lot of state-keepking logic
+ // here, but it is what it has to be.
+ if(!cView){ // current view book keeping
+ lastViewIdx = 0;
+ cView = props.structure[0];
+ }else if(cellCount >= (lastViewIdx+cView.__span)){
+ viewIdx++;
+ // move to allocating things into the next view
+ lastViewIdx += cView.__span;
+ var lastView = cView;
+ cView = props.structure[viewIdx];
+ }
+
+ // actually define the cell from what markup hands us
+ var cell = {
+ name: d.trim(d.attr(th, "name")||th.innerHTML),
+ colSpan: parseInt(d.attr(th, "colspan")||1, 10),
+ type: d.trim(d.attr(th, "cellType")||""),
+ id: d.trim(d.attr(th,"id")||"")
+ };
+ cellCount += cell.colSpan;
+ var rowSpan = d.attr(th, "rowspan");
+ if(rowSpan){
+ cell.rowSpan = rowSpan;
+ }
+ if(d.hasAttr(th, "width")){
+ cell.width = widthFromAttr(th);
+ }
+ if(d.hasAttr(th, "relWidth")){
+ cell.relWidth = window.parseInt(dojo.attr(th, "relWidth"), 10);
+ }
+ if(d.hasAttr(th, "hidden")){
+ cell.hidden = (d.attr(th, "hidden") == "true" || d.attr(th, "hidden") === true/*always boolean true in Chrome*/);
+ }
+
+ if(cellFunc){
+ cellFunc(th, cell);
+ }
+
+ cell.type = cell.type ? dojo.getObject(cell.type) : dojox.grid.cells.Cell;
+
+ if(cell.type && cell.type.markupFactory){
+ cell.type.markupFactory(th, cell);
+ }
+
+ if(!cView.cells[tr_idx]){
+ cView.cells[tr_idx] = [];
+ }
+ cView.cells[tr_idx].push(cell);
+ });
+ });
+ }
+
+ return new ctor(props, node);
+ };
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/_Layout.js b/js/dojo-1.6/dojox/grid/_Layout.js
new file mode 100644
index 0000000..8be8ecc
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_Layout.js
@@ -0,0 +1,275 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid._Layout"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Layout"] = true;
+dojo.provide("dojox.grid._Layout");
+dojo.require("dojox.grid.cells");
+dojo.require("dojox.grid._RowSelector");
+
+dojo.declare("dojox.grid._Layout", null, {
+ // summary:
+ // Controls grid cell layout. Owned by grid and used internally.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+ // flat array of grid cells
+ cells: [],
+ // structured array of grid cells
+ structure: null,
+ // default cell width
+ defaultWidth: '6em',
+
+ // methods
+ moveColumn: function(sourceViewIndex, destViewIndex, cellIndex, targetIndex, before){
+ var source_cells = this.structure[sourceViewIndex].cells[0];
+ var dest_cells = this.structure[destViewIndex].cells[0];
+
+ var cell = null;
+ var cell_ri = 0;
+ var target_ri = 0;
+
+ for(var i=0, c; c=source_cells[i]; i++){
+ if(c.index == cellIndex){
+ cell_ri = i;
+ break;
+ }
+ }
+ cell = source_cells.splice(cell_ri, 1)[0];
+ cell.view = this.grid.views.views[destViewIndex];
+
+ for(i=0, c=null; c=dest_cells[i]; i++){
+ if(c.index == targetIndex){
+ target_ri = i;
+ break;
+ }
+ }
+ if(!before){
+ target_ri += 1;
+ }
+ dest_cells.splice(target_ri, 0, cell);
+
+ var sortedCell = this.grid.getCell(this.grid.getSortIndex());
+ if(sortedCell){
+ sortedCell._currentlySorted = this.grid.getSortAsc();
+ }
+
+ this.cells = [];
+ cellIndex = 0;
+ var v;
+ for(i=0; v=this.structure[i]; i++){
+ for(var j=0, cs; cs=v.cells[j]; j++){
+ for(var k=0; c=cs[k]; k++){
+ c.index = cellIndex;
+ this.cells.push(c);
+ if("_currentlySorted" in c){
+ var si = cellIndex + 1;
+ si *= c._currentlySorted ? 1 : -1;
+ this.grid.sortInfo = si;
+ delete c._currentlySorted;
+ }
+ cellIndex++;
+ }
+ }
+ }
+
+ //Fix #9481 - reset idx in cell markup
+ dojo.forEach(this.cells, function(c){
+ var marks = c.markup[2].split(" ");
+ var oldIdx = parseInt(marks[1].substring(5));//get old "idx"
+ if(oldIdx != c.index){
+ marks[1] = "idx=\"" + c.index + "\"";
+ c.markup[2] = marks.join(" ");
+ }
+ });
+
+ this.grid.setupHeaderMenu();
+ //this.grid.renderOnIdle();
+ },
+
+ setColumnVisibility: function(columnIndex, visible){
+ var cell = this.cells[columnIndex];
+ if(cell.hidden == visible){
+ cell.hidden = !visible;
+ var v = cell.view, w = v.viewWidth;
+ if(w && w != "auto"){
+ v._togglingColumn = dojo.marginBox(cell.getHeaderNode()).w || 0;
+ }
+ v.update();
+ return true;
+ }else{
+ return false;
+ }
+ },
+
+ addCellDef: function(inRowIndex, inCellIndex, inDef){
+ var self = this;
+ var getCellWidth = function(inDef){
+ var w = 0;
+ if(inDef.colSpan > 1){
+ w = 0;
+ }else{
+ w = inDef.width || self._defaultCellProps.width || self.defaultWidth;
+
+ if(!isNaN(w)){
+ w = w + "em";
+ }
+ }
+ return w;
+ };
+
+ var props = {
+ grid: this.grid,
+ subrow: inRowIndex,
+ layoutIndex: inCellIndex,
+ index: this.cells.length
+ };
+
+ if(inDef && inDef instanceof dojox.grid.cells._Base){
+ var new_cell = dojo.clone(inDef);
+ props.unitWidth = getCellWidth(new_cell._props);
+ new_cell = dojo.mixin(new_cell, this._defaultCellProps, inDef._props, props);
+ return new_cell;
+ }
+
+ var cell_type = inDef.type || inDef.cellType || this._defaultCellProps.type || this._defaultCellProps.cellType || dojox.grid.cells.Cell;
+
+ props.unitWidth = getCellWidth(inDef);
+ return new cell_type(dojo.mixin({}, this._defaultCellProps, inDef, props));
+ },
+
+ addRowDef: function(inRowIndex, inDef){
+ var result = [];
+ var relSum = 0, pctSum = 0, doRel = true;
+ for(var i=0, def, cell; (def=inDef[i]); i++){
+ cell = this.addCellDef(inRowIndex, i, def);
+ result.push(cell);
+ this.cells.push(cell);
+ // Check and calculate the sum of all relative widths
+ if(doRel && cell.relWidth){
+ relSum += cell.relWidth;
+ }else if(cell.width){
+ var w = cell.width;
+ if(typeof w == "string" && w.slice(-1) == "%"){
+ pctSum += window.parseInt(w, 10);
+ }else if(w == "auto"){
+ // relative widths doesn't play nice with auto - since we
+ // don't have a way of knowing how much space the auto is
+ // supposed to take up.
+ doRel = false;
+ }
+ }
+ }
+ if(relSum && doRel){
+ // We have some kind of relWidths specified - so change them to %
+ dojo.forEach(result, function(cell){
+ if(cell.relWidth){
+ cell.width = cell.unitWidth = ((cell.relWidth / relSum) * (100 - pctSum)) + "%";
+ }
+ });
+ }
+ return result;
+
+ },
+
+ addRowsDef: function(inDef){
+ var result = [];
+ if(dojo.isArray(inDef)){
+ if(dojo.isArray(inDef[0])){
+ for(var i=0, row; inDef && (row=inDef[i]); i++){
+ result.push(this.addRowDef(i, row));
+ }
+ }else{
+ result.push(this.addRowDef(0, inDef));
+ }
+ }
+ return result;
+ },
+
+ addViewDef: function(inDef){
+ this._defaultCellProps = inDef.defaultCell || {};
+ if(inDef.width && inDef.width == "auto"){
+ delete inDef.width;
+ }
+ return dojo.mixin({}, inDef, {cells: this.addRowsDef(inDef.rows || inDef.cells)});
+ },
+
+ setStructure: function(inStructure){
+ this.fieldIndex = 0;
+ this.cells = [];
+ var s = this.structure = [];
+
+ if(this.grid.rowSelector){
+ var sel = { type: dojox._scopeName + ".grid._RowSelector" };
+
+ if(dojo.isString(this.grid.rowSelector)){
+ var width = this.grid.rowSelector;
+
+ if(width == "false"){
+ sel = null;
+ }else if(width != "true"){
+ sel['width'] = width;
+ }
+ }else{
+ if(!this.grid.rowSelector){
+ sel = null;
+ }
+ }
+
+ if(sel){
+ s.push(this.addViewDef(sel));
+ }
+ }
+
+ var isCell = function(def){
+ return ("name" in def || "field" in def || "get" in def);
+ };
+
+ var isRowDef = function(def){
+ if(dojo.isArray(def)){
+ if(dojo.isArray(def[0]) || isCell(def[0])){
+ return true;
+ }
+ }
+ return false;
+ };
+
+ var isView = function(def){
+ return (def !== null && dojo.isObject(def) &&
+ ("cells" in def || "rows" in def || ("type" in def && !isCell(def))));
+ };
+
+ if(dojo.isArray(inStructure)){
+ var hasViews = false;
+ for(var i=0, st; (st=inStructure[i]); i++){
+ if(isView(st)){
+ hasViews = true;
+ break;
+ }
+ }
+ if(!hasViews){
+ s.push(this.addViewDef({ cells: inStructure }));
+ }else{
+ for(i=0; (st=inStructure[i]); i++){
+ if(isRowDef(st)){
+ s.push(this.addViewDef({ cells: st }));
+ }else if(isView(st)){
+ s.push(this.addViewDef(st));
+ }
+ }
+ }
+ }else if(isView(inStructure)){
+ // it's a view object
+ s.push(this.addViewDef(inStructure));
+ }
+
+ this.cellCount = this.cells.length;
+ this.grid.setupHeaderMenu();
+ }
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/_Layout.xd.js b/js/dojo-1.6/dojox/grid/_Layout.xd.js
new file mode 100644
index 0000000..b9525cb
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_Layout.xd.js
@@ -0,0 +1,281 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid._Layout"],
+["require", "dojox.grid.cells"],
+["require", "dojox.grid._RowSelector"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid._Layout"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Layout"] = true;
+dojo.provide("dojox.grid._Layout");
+dojo.require("dojox.grid.cells");
+dojo.require("dojox.grid._RowSelector");
+
+dojo.declare("dojox.grid._Layout", null, {
+ // summary:
+ // Controls grid cell layout. Owned by grid and used internally.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+ // flat array of grid cells
+ cells: [],
+ // structured array of grid cells
+ structure: null,
+ // default cell width
+ defaultWidth: '6em',
+
+ // methods
+ moveColumn: function(sourceViewIndex, destViewIndex, cellIndex, targetIndex, before){
+ var source_cells = this.structure[sourceViewIndex].cells[0];
+ var dest_cells = this.structure[destViewIndex].cells[0];
+
+ var cell = null;
+ var cell_ri = 0;
+ var target_ri = 0;
+
+ for(var i=0, c; c=source_cells[i]; i++){
+ if(c.index == cellIndex){
+ cell_ri = i;
+ break;
+ }
+ }
+ cell = source_cells.splice(cell_ri, 1)[0];
+ cell.view = this.grid.views.views[destViewIndex];
+
+ for(i=0, c=null; c=dest_cells[i]; i++){
+ if(c.index == targetIndex){
+ target_ri = i;
+ break;
+ }
+ }
+ if(!before){
+ target_ri += 1;
+ }
+ dest_cells.splice(target_ri, 0, cell);
+
+ var sortedCell = this.grid.getCell(this.grid.getSortIndex());
+ if(sortedCell){
+ sortedCell._currentlySorted = this.grid.getSortAsc();
+ }
+
+ this.cells = [];
+ cellIndex = 0;
+ var v;
+ for(i=0; v=this.structure[i]; i++){
+ for(var j=0, cs; cs=v.cells[j]; j++){
+ for(var k=0; c=cs[k]; k++){
+ c.index = cellIndex;
+ this.cells.push(c);
+ if("_currentlySorted" in c){
+ var si = cellIndex + 1;
+ si *= c._currentlySorted ? 1 : -1;
+ this.grid.sortInfo = si;
+ delete c._currentlySorted;
+ }
+ cellIndex++;
+ }
+ }
+ }
+
+ //Fix #9481 - reset idx in cell markup
+ dojo.forEach(this.cells, function(c){
+ var marks = c.markup[2].split(" ");
+ var oldIdx = parseInt(marks[1].substring(5));//get old "idx"
+ if(oldIdx != c.index){
+ marks[1] = "idx=\"" + c.index + "\"";
+ c.markup[2] = marks.join(" ");
+ }
+ });
+
+ this.grid.setupHeaderMenu();
+ //this.grid.renderOnIdle();
+ },
+
+ setColumnVisibility: function(columnIndex, visible){
+ var cell = this.cells[columnIndex];
+ if(cell.hidden == visible){
+ cell.hidden = !visible;
+ var v = cell.view, w = v.viewWidth;
+ if(w && w != "auto"){
+ v._togglingColumn = dojo.marginBox(cell.getHeaderNode()).w || 0;
+ }
+ v.update();
+ return true;
+ }else{
+ return false;
+ }
+ },
+
+ addCellDef: function(inRowIndex, inCellIndex, inDef){
+ var self = this;
+ var getCellWidth = function(inDef){
+ var w = 0;
+ if(inDef.colSpan > 1){
+ w = 0;
+ }else{
+ w = inDef.width || self._defaultCellProps.width || self.defaultWidth;
+
+ if(!isNaN(w)){
+ w = w + "em";
+ }
+ }
+ return w;
+ };
+
+ var props = {
+ grid: this.grid,
+ subrow: inRowIndex,
+ layoutIndex: inCellIndex,
+ index: this.cells.length
+ };
+
+ if(inDef && inDef instanceof dojox.grid.cells._Base){
+ var new_cell = dojo.clone(inDef);
+ props.unitWidth = getCellWidth(new_cell._props);
+ new_cell = dojo.mixin(new_cell, this._defaultCellProps, inDef._props, props);
+ return new_cell;
+ }
+
+ var cell_type = inDef.type || inDef.cellType || this._defaultCellProps.type || this._defaultCellProps.cellType || dojox.grid.cells.Cell;
+
+ props.unitWidth = getCellWidth(inDef);
+ return new cell_type(dojo.mixin({}, this._defaultCellProps, inDef, props));
+ },
+
+ addRowDef: function(inRowIndex, inDef){
+ var result = [];
+ var relSum = 0, pctSum = 0, doRel = true;
+ for(var i=0, def, cell; (def=inDef[i]); i++){
+ cell = this.addCellDef(inRowIndex, i, def);
+ result.push(cell);
+ this.cells.push(cell);
+ // Check and calculate the sum of all relative widths
+ if(doRel && cell.relWidth){
+ relSum += cell.relWidth;
+ }else if(cell.width){
+ var w = cell.width;
+ if(typeof w == "string" && w.slice(-1) == "%"){
+ pctSum += window.parseInt(w, 10);
+ }else if(w == "auto"){
+ // relative widths doesn't play nice with auto - since we
+ // don't have a way of knowing how much space the auto is
+ // supposed to take up.
+ doRel = false;
+ }
+ }
+ }
+ if(relSum && doRel){
+ // We have some kind of relWidths specified - so change them to %
+ dojo.forEach(result, function(cell){
+ if(cell.relWidth){
+ cell.width = cell.unitWidth = ((cell.relWidth / relSum) * (100 - pctSum)) + "%";
+ }
+ });
+ }
+ return result;
+
+ },
+
+ addRowsDef: function(inDef){
+ var result = [];
+ if(dojo.isArray(inDef)){
+ if(dojo.isArray(inDef[0])){
+ for(var i=0, row; inDef && (row=inDef[i]); i++){
+ result.push(this.addRowDef(i, row));
+ }
+ }else{
+ result.push(this.addRowDef(0, inDef));
+ }
+ }
+ return result;
+ },
+
+ addViewDef: function(inDef){
+ this._defaultCellProps = inDef.defaultCell || {};
+ if(inDef.width && inDef.width == "auto"){
+ delete inDef.width;
+ }
+ return dojo.mixin({}, inDef, {cells: this.addRowsDef(inDef.rows || inDef.cells)});
+ },
+
+ setStructure: function(inStructure){
+ this.fieldIndex = 0;
+ this.cells = [];
+ var s = this.structure = [];
+
+ if(this.grid.rowSelector){
+ var sel = { type: dojox._scopeName + ".grid._RowSelector" };
+
+ if(dojo.isString(this.grid.rowSelector)){
+ var width = this.grid.rowSelector;
+
+ if(width == "false"){
+ sel = null;
+ }else if(width != "true"){
+ sel['width'] = width;
+ }
+ }else{
+ if(!this.grid.rowSelector){
+ sel = null;
+ }
+ }
+
+ if(sel){
+ s.push(this.addViewDef(sel));
+ }
+ }
+
+ var isCell = function(def){
+ return ("name" in def || "field" in def || "get" in def);
+ };
+
+ var isRowDef = function(def){
+ if(dojo.isArray(def)){
+ if(dojo.isArray(def[0]) || isCell(def[0])){
+ return true;
+ }
+ }
+ return false;
+ };
+
+ var isView = function(def){
+ return (def !== null && dojo.isObject(def) &&
+ ("cells" in def || "rows" in def || ("type" in def && !isCell(def))));
+ };
+
+ if(dojo.isArray(inStructure)){
+ var hasViews = false;
+ for(var i=0, st; (st=inStructure[i]); i++){
+ if(isView(st)){
+ hasViews = true;
+ break;
+ }
+ }
+ if(!hasViews){
+ s.push(this.addViewDef({ cells: inStructure }));
+ }else{
+ for(i=0; (st=inStructure[i]); i++){
+ if(isRowDef(st)){
+ s.push(this.addViewDef({ cells: st }));
+ }else if(isView(st)){
+ s.push(this.addViewDef(st));
+ }
+ }
+ }
+ }else if(isView(inStructure)){
+ // it's a view object
+ s.push(this.addViewDef(inStructure));
+ }
+
+ this.cellCount = this.cells.length;
+ this.grid.setupHeaderMenu();
+ }
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/_RadioSelector.js b/js/dojo-1.6/dojox/grid/_RadioSelector.js
new file mode 100644
index 0000000..2b21fd5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_RadioSelector.js
@@ -0,0 +1,14 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid._RadioSelector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._RadioSelector"] = true;
+dojo.provide("dojox.grid._RadioSelector");
+
+dojo.require("dojox.grid._Selector");
+
+}
diff --git a/js/dojo-1.6/dojox/grid/_RadioSelector.xd.js b/js/dojo-1.6/dojox/grid/_RadioSelector.xd.js
new file mode 100644
index 0000000..0b5ac59
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_RadioSelector.xd.js
@@ -0,0 +1,19 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid._RadioSelector"],
+["require", "dojox.grid._Selector"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid._RadioSelector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._RadioSelector"] = true;
+dojo.provide("dojox.grid._RadioSelector");
+
+dojo.require("dojox.grid._Selector");
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/_RowManager.js b/js/dojo-1.6/dojox/grid/_RowManager.js
new file mode 100644
index 0000000..862746f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_RowManager.js
@@ -0,0 +1,71 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid._RowManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._RowManager"] = true;
+dojo.provide("dojox.grid._RowManager");
+
+(function(){
+ var setStyleText = function(inNode, inStyleText){
+ if(inNode.style.cssText == undefined){
+ inNode.setAttribute("style", inStyleText);
+ }else{
+ inNode.style.cssText = inStyleText;
+ }
+ };
+
+ dojo.declare("dojox.grid._RowManager", null, {
+ // Stores information about grid rows. Owned by grid and used internally.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+ linesToEms: 2,
+ overRow: -2,
+ // styles
+ prepareStylingRow: function(inRowIndex, inRowNode){
+ return {
+ index: inRowIndex,
+ node: inRowNode,
+ odd: Boolean(inRowIndex&1),
+ selected: !!this.grid.selection.isSelected(inRowIndex),
+ over: this.isOver(inRowIndex),
+ customStyles: "",
+ customClasses: "dojoxGridRow"
+ };
+ },
+ styleRowNode: function(inRowIndex, inRowNode){
+ var row = this.prepareStylingRow(inRowIndex, inRowNode);
+ this.grid.onStyleRow(row);
+ this.applyStyles(row);
+ },
+ applyStyles: function(inRow){
+ var i = inRow;
+
+ i.node.className = i.customClasses;
+ var h = i.node.style.height;
+ setStyleText(i.node, i.customStyles + ';' + (i.node._style||''));
+ i.node.style.height = h;
+ },
+ updateStyles: function(inRowIndex){
+ this.grid.updateRowStyles(inRowIndex);
+ },
+ // states and events
+ setOverRow: function(inRowIndex){
+ var last = this.overRow;
+ this.overRow = inRowIndex;
+ if((last!=this.overRow)&&(dojo.isString(last) || last >= 0)){
+ this.updateStyles(last);
+ }
+ this.updateStyles(this.overRow);
+ },
+ isOver: function(inRowIndex){
+ return (this.overRow == inRowIndex && !dojo.hasClass(this.grid.domNode, "dojoxGridColumnResizing"));
+ }
+ });
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/_RowManager.xd.js b/js/dojo-1.6/dojox/grid/_RowManager.xd.js
new file mode 100644
index 0000000..15e74a3
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_RowManager.xd.js
@@ -0,0 +1,75 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid._RowManager"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid._RowManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._RowManager"] = true;
+dojo.provide("dojox.grid._RowManager");
+
+(function(){
+ var setStyleText = function(inNode, inStyleText){
+ if(inNode.style.cssText == undefined){
+ inNode.setAttribute("style", inStyleText);
+ }else{
+ inNode.style.cssText = inStyleText;
+ }
+ };
+
+ dojo.declare("dojox.grid._RowManager", null, {
+ // Stores information about grid rows. Owned by grid and used internally.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+ linesToEms: 2,
+ overRow: -2,
+ // styles
+ prepareStylingRow: function(inRowIndex, inRowNode){
+ return {
+ index: inRowIndex,
+ node: inRowNode,
+ odd: Boolean(inRowIndex&1),
+ selected: !!this.grid.selection.isSelected(inRowIndex),
+ over: this.isOver(inRowIndex),
+ customStyles: "",
+ customClasses: "dojoxGridRow"
+ };
+ },
+ styleRowNode: function(inRowIndex, inRowNode){
+ var row = this.prepareStylingRow(inRowIndex, inRowNode);
+ this.grid.onStyleRow(row);
+ this.applyStyles(row);
+ },
+ applyStyles: function(inRow){
+ var i = inRow;
+
+ i.node.className = i.customClasses;
+ var h = i.node.style.height;
+ setStyleText(i.node, i.customStyles + ';' + (i.node._style||''));
+ i.node.style.height = h;
+ },
+ updateStyles: function(inRowIndex){
+ this.grid.updateRowStyles(inRowIndex);
+ },
+ // states and events
+ setOverRow: function(inRowIndex){
+ var last = this.overRow;
+ this.overRow = inRowIndex;
+ if((last!=this.overRow)&&(dojo.isString(last) || last >= 0)){
+ this.updateStyles(last);
+ }
+ this.updateStyles(this.overRow);
+ },
+ isOver: function(inRowIndex){
+ return (this.overRow == inRowIndex && !dojo.hasClass(this.grid.domNode, "dojoxGridColumnResizing"));
+ }
+ });
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/_RowSelector.js b/js/dojo-1.6/dojox/grid/_RowSelector.js
new file mode 100644
index 0000000..e04c1f5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_RowSelector.js
@@ -0,0 +1,66 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid._RowSelector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._RowSelector"] = true;
+dojo.provide("dojox.grid._RowSelector");
+dojo.require("dojox.grid._View");
+
+dojo.declare('dojox.grid._RowSelector', dojox.grid._View, {
+ // summary:
+ // Custom grid view. If used in a grid structure, provides a small selectable region for grid rows.
+ defaultWidth: "2em",
+ noscroll: true,
+ padBorderWidth: 2,
+ buildRendering: function(){
+ this.inherited('buildRendering', arguments);
+ this.scrollboxNode.style.overflow = "hidden";
+ this.headerNode.style.visibility = "hidden";
+ },
+ getWidth: function(){
+ return this.viewWidth || this.defaultWidth;
+ },
+ buildRowContent: function(inRowIndex, inRowNode){
+ var w = this.contentWidth || 0;
+ inRowNode.innerHTML = '<table class="dojoxGridRowbarTable" style="width:' + w + 'px;height:1px;" border="0" cellspacing="0" cellpadding="0" role="presentation"><tr><td class="dojoxGridRowbarInner">&nbsp;</td></tr></table>';
+ },
+ renderHeader: function(){
+ },
+ updateRow: function(){
+ },
+ resize: function(){
+ this.adaptHeight();
+ },
+ adaptWidth: function(){
+ // Only calculate this here - rather than every call to buildRowContent
+ if(!("contentWidth" in this) && this.contentNode){
+ this.contentWidth = this.contentNode.offsetWidth - this.padBorderWidth;
+ }
+ },
+ // styling
+ doStyleRowNode: function(inRowIndex, inRowNode){
+ var n = [ "dojoxGridRowbar dojoxGridNonNormalizedCell" ];
+ if(this.grid.rows.isOver(inRowIndex)){
+ n.push("dojoxGridRowbarOver");
+ }
+ if(this.grid.selection.isSelected(inRowIndex)){
+ n.push("dojoxGridRowbarSelected");
+ }
+ inRowNode.className = n.join(" ");
+ },
+ // event handlers
+ domouseover: function(e){
+ this.grid.onMouseOverRow(e);
+ },
+ domouseout: function(e){
+ if(!this.isIntraRowEvent(e)){
+ this.grid.onMouseOutRow(e);
+ }
+ }
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/_RowSelector.xd.js b/js/dojo-1.6/dojox/grid/_RowSelector.xd.js
new file mode 100644
index 0000000..d5a0022
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_RowSelector.xd.js
@@ -0,0 +1,71 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid._RowSelector"],
+["require", "dojox.grid._View"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid._RowSelector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._RowSelector"] = true;
+dojo.provide("dojox.grid._RowSelector");
+dojo.require("dojox.grid._View");
+
+dojo.declare('dojox.grid._RowSelector', dojox.grid._View, {
+ // summary:
+ // Custom grid view. If used in a grid structure, provides a small selectable region for grid rows.
+ defaultWidth: "2em",
+ noscroll: true,
+ padBorderWidth: 2,
+ buildRendering: function(){
+ this.inherited('buildRendering', arguments);
+ this.scrollboxNode.style.overflow = "hidden";
+ this.headerNode.style.visibility = "hidden";
+ },
+ getWidth: function(){
+ return this.viewWidth || this.defaultWidth;
+ },
+ buildRowContent: function(inRowIndex, inRowNode){
+ var w = this.contentWidth || 0;
+ inRowNode.innerHTML = '<table class="dojoxGridRowbarTable" style="width:' + w + 'px;height:1px;" border="0" cellspacing="0" cellpadding="0" role="presentation"><tr><td class="dojoxGridRowbarInner">&nbsp;</td></tr></table>';
+ },
+ renderHeader: function(){
+ },
+ updateRow: function(){
+ },
+ resize: function(){
+ this.adaptHeight();
+ },
+ adaptWidth: function(){
+ // Only calculate this here - rather than every call to buildRowContent
+ if(!("contentWidth" in this) && this.contentNode){
+ this.contentWidth = this.contentNode.offsetWidth - this.padBorderWidth;
+ }
+ },
+ // styling
+ doStyleRowNode: function(inRowIndex, inRowNode){
+ var n = [ "dojoxGridRowbar dojoxGridNonNormalizedCell" ];
+ if(this.grid.rows.isOver(inRowIndex)){
+ n.push("dojoxGridRowbarOver");
+ }
+ if(this.grid.selection.isSelected(inRowIndex)){
+ n.push("dojoxGridRowbarSelected");
+ }
+ inRowNode.className = n.join(" ");
+ },
+ // event handlers
+ domouseover: function(e){
+ this.grid.onMouseOverRow(e);
+ },
+ domouseout: function(e){
+ if(!this.isIntraRowEvent(e)){
+ this.grid.onMouseOutRow(e);
+ }
+ }
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/_Scroller.js b/js/dojo-1.6/dojox/grid/_Scroller.js
new file mode 100644
index 0000000..ea90d10
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_Scroller.js
@@ -0,0 +1,515 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid._Scroller"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Scroller"] = true;
+dojo.provide("dojox.grid._Scroller");
+
+(function(){
+ var indexInParent = function(inNode){
+ var i=0, n, p=inNode.parentNode;
+ while((n = p.childNodes[i++])){
+ if(n == inNode){
+ return i - 1;
+ }
+ }
+ return -1;
+ };
+
+ var cleanNode = function(inNode){
+ if(!inNode){
+ return;
+ }
+ var filter = function(inW){
+ return inW.domNode && dojo.isDescendant(inW.domNode, inNode, true);
+ };
+ var ws = dijit.registry.filter(filter);
+ for(var i=0, w; (w=ws[i]); i++){
+ w.destroy();
+ }
+ delete ws;
+ };
+
+ var getTagName = function(inNodeOrId){
+ var node = dojo.byId(inNodeOrId);
+ return (node && node.tagName ? node.tagName.toLowerCase() : '');
+ };
+
+ var nodeKids = function(inNode, inTag){
+ var result = [];
+ var i=0, n;
+ while((n = inNode.childNodes[i])){
+ i++;
+ if(getTagName(n) == inTag){
+ result.push(n);
+ }
+ }
+ return result;
+ };
+
+ var divkids = function(inNode){
+ return nodeKids(inNode, 'div');
+ };
+
+ dojo.declare("dojox.grid._Scroller", null, {
+ constructor: function(inContentNodes){
+ this.setContentNodes(inContentNodes);
+ this.pageHeights = [];
+ this.pageNodes = [];
+ this.stack = [];
+ },
+ // specified
+ rowCount: 0, // total number of rows to manage
+ defaultRowHeight: 32, // default height of a row
+ keepRows: 100, // maximum number of rows that should exist at one time
+ contentNode: null, // node to contain pages
+ scrollboxNode: null, // node that controls scrolling
+ // calculated
+ defaultPageHeight: 0, // default height of a page
+ keepPages: 10, // maximum number of pages that should exists at one time
+ pageCount: 0,
+ windowHeight: 0,
+ firstVisibleRow: 0,
+ lastVisibleRow: 0,
+ averageRowHeight: 0, // the average height of a row
+ // private
+ page: 0,
+ pageTop: 0,
+ // init
+ init: function(inRowCount, inKeepRows, inRowsPerPage){
+ switch(arguments.length){
+ case 3: this.rowsPerPage = inRowsPerPage;
+ case 2: this.keepRows = inKeepRows;
+ case 1: this.rowCount = inRowCount;
+ default: break;
+ }
+ this.defaultPageHeight = this.defaultRowHeight * this.rowsPerPage;
+ this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage);
+ this.setKeepInfo(this.keepRows);
+ this.invalidate();
+ if(this.scrollboxNode){
+ this.scrollboxNode.scrollTop = 0;
+ this.scroll(0);
+ this.scrollboxNode.onscroll = dojo.hitch(this, 'onscroll');
+ }
+ },
+ _getPageCount: function(rowCount, rowsPerPage){
+ return rowCount ? (Math.ceil(rowCount / rowsPerPage) || 1) : 0;
+ },
+ destroy: function(){
+ this.invalidateNodes();
+ delete this.contentNodes;
+ delete this.contentNode;
+ delete this.scrollboxNode;
+ },
+ setKeepInfo: function(inKeepRows){
+ this.keepRows = inKeepRows;
+ this.keepPages = !this.keepRows ? this.keepPages : Math.max(Math.ceil(this.keepRows / this.rowsPerPage), 2);
+ },
+ // nodes
+ setContentNodes: function(inNodes){
+ this.contentNodes = inNodes;
+ this.colCount = (this.contentNodes ? this.contentNodes.length : 0);
+ this.pageNodes = [];
+ for(var i=0; i<this.colCount; i++){
+ this.pageNodes[i] = [];
+ }
+ },
+ getDefaultNodes: function(){
+ return this.pageNodes[0] || [];
+ },
+ // updating
+ invalidate: function(){
+ this._invalidating = true;
+ this.invalidateNodes();
+ this.pageHeights = [];
+ this.height = (this.pageCount ? (this.pageCount - 1)* this.defaultPageHeight + this.calcLastPageHeight() : 0);
+ this.resize();
+ this._invalidating = false;
+ },
+ updateRowCount: function(inRowCount){
+ this.invalidateNodes();
+ this.rowCount = inRowCount;
+ // update page count, adjust document height
+ var oldPageCount = this.pageCount;
+ if(oldPageCount === 0){
+ //We want to have at least 1px in height to keep scroller. Otherwise with an
+ //empty grid you can't scroll to see the header.
+ this.height = 1;
+ }
+ this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage);
+ if(this.pageCount < oldPageCount){
+ for(var i=oldPageCount-1; i>=this.pageCount; i--){
+ this.height -= this.getPageHeight(i);
+ delete this.pageHeights[i];
+ }
+ }else if(this.pageCount > oldPageCount){
+ this.height += this.defaultPageHeight * (this.pageCount - oldPageCount - 1) + this.calcLastPageHeight();
+ }
+ this.resize();
+ },
+ // implementation for page manager
+ pageExists: function(inPageIndex){
+ return Boolean(this.getDefaultPageNode(inPageIndex));
+ },
+ measurePage: function(inPageIndex){
+ if(this.grid.rowHeight){
+ var height = this.grid.rowHeight + 1;
+ return ((inPageIndex + 1) * this.rowsPerPage > this.rowCount ?
+ this.rowCount - inPageIndex * this.rowsPerPage :
+ this.rowsPerPage) * height;
+
+ }
+ var n = this.getDefaultPageNode(inPageIndex);
+ return (n && n.innerHTML) ? n.offsetHeight : undefined;
+ },
+ positionPage: function(inPageIndex, inPos){
+ for(var i=0; i<this.colCount; i++){
+ this.pageNodes[i][inPageIndex].style.top = inPos + 'px';
+ }
+ },
+ repositionPages: function(inPageIndex){
+ var nodes = this.getDefaultNodes();
+ var last = 0;
+
+ for(var i=0; i<this.stack.length; i++){
+ last = Math.max(this.stack[i], last);
+ }
+ //
+ var n = nodes[inPageIndex];
+ var y = (n ? this.getPageNodePosition(n) + this.getPageHeight(inPageIndex) : 0);
+ for(var p=inPageIndex+1; p<=last; p++){
+ n = nodes[p];
+ if(n){
+ if(this.getPageNodePosition(n) == y){
+ return;
+ }
+ this.positionPage(p, y);
+ }
+ y += this.getPageHeight(p);
+ }
+ },
+ installPage: function(inPageIndex){
+ for(var i=0; i<this.colCount; i++){
+ this.contentNodes[i].appendChild(this.pageNodes[i][inPageIndex]);
+ }
+ },
+ preparePage: function(inPageIndex, inReuseNode){
+ var p = (inReuseNode ? this.popPage() : null);
+ for(var i=0; i<this.colCount; i++){
+ var nodes = this.pageNodes[i];
+ var new_p = (p === null ? this.createPageNode() : this.invalidatePageNode(p, nodes));
+ new_p.pageIndex = inPageIndex;
+ nodes[inPageIndex] = new_p;
+ }
+ },
+ // rendering implementation
+ renderPage: function(inPageIndex){
+ var nodes = [];
+ var i, j;
+ for(i=0; i<this.colCount; i++){
+ nodes[i] = this.pageNodes[i][inPageIndex];
+ }
+ for(i=0, j=inPageIndex*this.rowsPerPage; (i<this.rowsPerPage)&&(j<this.rowCount); i++, j++){
+ this.renderRow(j, nodes);
+ }
+ },
+ removePage: function(inPageIndex){
+ for(var i=0, j=inPageIndex*this.rowsPerPage; i<this.rowsPerPage; i++, j++){
+ this.removeRow(j);
+ }
+ },
+ destroyPage: function(inPageIndex){
+ for(var i=0; i<this.colCount; i++){
+ var n = this.invalidatePageNode(inPageIndex, this.pageNodes[i]);
+ if(n){
+ dojo.destroy(n);
+ }
+ }
+ },
+ pacify: function(inShouldPacify){
+ },
+ // pacification
+ pacifying: false,
+ pacifyTicks: 200,
+ setPacifying: function(inPacifying){
+ if(this.pacifying != inPacifying){
+ this.pacifying = inPacifying;
+ this.pacify(this.pacifying);
+ }
+ },
+ startPacify: function(){
+ this.startPacifyTicks = new Date().getTime();
+ },
+ doPacify: function(){
+ var result = (new Date().getTime() - this.startPacifyTicks) > this.pacifyTicks;
+ this.setPacifying(true);
+ this.startPacify();
+ return result;
+ },
+ endPacify: function(){
+ this.setPacifying(false);
+ },
+ // default sizing implementation
+ resize: function(){
+ if(this.scrollboxNode){
+ this.windowHeight = this.scrollboxNode.clientHeight;
+ }
+ for(var i=0; i<this.colCount; i++){
+ //We want to have 1px in height min to keep scroller. Otherwise can't scroll
+ //and see header in empty grid.
+ dojox.grid.util.setStyleHeightPx(this.contentNodes[i], Math.max(1,this.height));
+ }
+
+ // Calculate the average row height and update the defaults (row and page).
+ var needPage = (!this._invalidating);
+ if(!needPage){
+ var ah = this.grid.get("autoHeight");
+ if(typeof ah == "number" && ah <= Math.min(this.rowsPerPage, this.rowCount)){
+ needPage = true;
+ }
+ }
+ if(needPage){
+ this.needPage(this.page, this.pageTop);
+ }
+ var rowsOnPage = (this.page < this.pageCount - 1) ? this.rowsPerPage : ((this.rowCount % this.rowsPerPage) || this.rowsPerPage);
+ var pageHeight = this.getPageHeight(this.page);
+ this.averageRowHeight = (pageHeight > 0 && rowsOnPage > 0) ? (pageHeight / rowsOnPage) : 0;
+ },
+ calcLastPageHeight: function(){
+ if(!this.pageCount){
+ return 0;
+ }
+ var lastPage = this.pageCount - 1;
+ var lastPageHeight = ((this.rowCount % this.rowsPerPage)||(this.rowsPerPage)) * this.defaultRowHeight;
+ this.pageHeights[lastPage] = lastPageHeight;
+ return lastPageHeight;
+ },
+ updateContentHeight: function(inDh){
+ this.height += inDh;
+ this.resize();
+ },
+ updatePageHeight: function(inPageIndex, fromBuild, fromAsynRendering){
+ if(this.pageExists(inPageIndex)){
+ var oh = this.getPageHeight(inPageIndex);
+ var h = (this.measurePage(inPageIndex));
+ if(h === undefined){
+ h = oh;
+ }
+ this.pageHeights[inPageIndex] = h;
+ if(oh != h){
+ this.updateContentHeight(h - oh);
+ var ah = this.grid.get("autoHeight");
+ if((typeof ah == "number" && ah > this.rowCount)||(ah === true && !fromBuild)){
+ if(!fromAsynRendering){
+ this.grid.sizeChange();
+ }else{//fix #11101 by using fromAsynRendering to avoid deadlock
+ var ns = this.grid.viewsNode.style;
+ ns.height = parseInt(ns.height) + h - oh + 'px';
+ this.repositionPages(inPageIndex);
+ }
+ }else{
+ this.repositionPages(inPageIndex);
+ }
+ }
+ return h;
+ }
+ return 0;
+ },
+ rowHeightChanged: function(inRowIndex, fromAsynRendering){
+ this.updatePageHeight(Math.floor(inRowIndex / this.rowsPerPage), false, fromAsynRendering);
+ },
+ // scroller core
+ invalidateNodes: function(){
+ while(this.stack.length){
+ this.destroyPage(this.popPage());
+ }
+ },
+ createPageNode: function(){
+ var p = document.createElement('div');
+ dojo.attr(p,"role","presentation");
+ p.style.position = 'absolute';
+ //p.style.width = '100%';
+ p.style[dojo._isBodyLtr() ? "left" : "right"] = '0';
+ return p;
+ },
+ getPageHeight: function(inPageIndex){
+ var ph = this.pageHeights[inPageIndex];
+ return (ph !== undefined ? ph : this.defaultPageHeight);
+ },
+ // FIXME: this is not a stack, it's a FIFO list
+ pushPage: function(inPageIndex){
+ return this.stack.push(inPageIndex);
+ },
+ popPage: function(){
+ return this.stack.shift();
+ },
+ findPage: function(inTop){
+ var i = 0, h = 0;
+ for(var ph = 0; i<this.pageCount; i++, h += ph){
+ ph = this.getPageHeight(i);
+ if(h + ph >= inTop){
+ break;
+ }
+ }
+ this.page = i;
+ this.pageTop = h;
+ },
+ buildPage: function(inPageIndex, inReuseNode, inPos){
+ this.preparePage(inPageIndex, inReuseNode);
+ this.positionPage(inPageIndex, inPos);
+ // order of operations is key below
+ this.installPage(inPageIndex);
+ this.renderPage(inPageIndex);
+ // order of operations is key above
+ this.pushPage(inPageIndex);
+ },
+ needPage: function(inPageIndex, inPos){
+ var h = this.getPageHeight(inPageIndex), oh = h;
+ if(!this.pageExists(inPageIndex)){
+ this.buildPage(inPageIndex, (!this.grid._autoHeight/*fix #10543*/ && this.keepPages&&(this.stack.length >= this.keepPages)), inPos);
+ h = this.updatePageHeight(inPageIndex, true);
+ }else{
+ this.positionPage(inPageIndex, inPos);
+ }
+ return h;
+ },
+ onscroll: function(){
+ this.scroll(this.scrollboxNode.scrollTop);
+ },
+ scroll: function(inTop){
+ this.grid.scrollTop = inTop;
+ if(this.colCount){
+ this.startPacify();
+ this.findPage(inTop);
+ var h = this.height;
+ var b = this.getScrollBottom(inTop);
+ for(var p=this.page, y=this.pageTop; (p<this.pageCount)&&((b<0)||(y<b)); p++){
+ y += this.needPage(p, y);
+ }
+ this.firstVisibleRow = this.getFirstVisibleRow(this.page, this.pageTop, inTop);
+ this.lastVisibleRow = this.getLastVisibleRow(p - 1, y, b);
+ // indicates some page size has been updated
+ if(h != this.height){
+ this.repositionPages(p-1);
+ }
+ this.endPacify();
+ }
+ },
+ getScrollBottom: function(inTop){
+ return (this.windowHeight >= 0 ? inTop + this.windowHeight : -1);
+ },
+ // events
+ processNodeEvent: function(e, inNode){
+ var t = e.target;
+ while(t && (t != inNode) && t.parentNode && (t.parentNode.parentNode != inNode)){
+ t = t.parentNode;
+ }
+ if(!t || !t.parentNode || (t.parentNode.parentNode != inNode)){
+ return false;
+ }
+ var page = t.parentNode;
+ e.topRowIndex = page.pageIndex * this.rowsPerPage;
+ e.rowIndex = e.topRowIndex + indexInParent(t);
+ e.rowTarget = t;
+ return true;
+ },
+ processEvent: function(e){
+ return this.processNodeEvent(e, this.contentNode);
+ },
+ // virtual rendering interface
+ renderRow: function(inRowIndex, inPageNode){
+ },
+ removeRow: function(inRowIndex){
+ },
+ // page node operations
+ getDefaultPageNode: function(inPageIndex){
+ return this.getDefaultNodes()[inPageIndex];
+ },
+ positionPageNode: function(inNode, inPos){
+ },
+ getPageNodePosition: function(inNode){
+ return inNode.offsetTop;
+ },
+ invalidatePageNode: function(inPageIndex, inNodes){
+ var p = inNodes[inPageIndex];
+ if(p){
+ delete inNodes[inPageIndex];
+ this.removePage(inPageIndex, p);
+ cleanNode(p);
+ p.innerHTML = '';
+ }
+ return p;
+ },
+ // scroll control
+ getPageRow: function(inPage){
+ return inPage * this.rowsPerPage;
+ },
+ getLastPageRow: function(inPage){
+ return Math.min(this.rowCount, this.getPageRow(inPage + 1)) - 1;
+ },
+ getFirstVisibleRow: function(inPage, inPageTop, inScrollTop){
+ if(!this.pageExists(inPage)){
+ return 0;
+ }
+ var row = this.getPageRow(inPage);
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[inPage]);
+ for(var i=0,l=rows.length; i<l && inPageTop<inScrollTop; i++, row++){
+ inPageTop += rows[i].offsetHeight;
+ }
+ return (row ? row - 1 : row);
+ },
+ getLastVisibleRow: function(inPage, inBottom, inScrollBottom){
+ if(!this.pageExists(inPage)){
+ return 0;
+ }
+ var nodes = this.getDefaultNodes();
+ var row = this.getLastPageRow(inPage);
+ var rows = divkids(nodes[inPage]);
+ for(var i=rows.length-1; i>=0 && inBottom>inScrollBottom; i--, row--){
+ inBottom -= rows[i].offsetHeight;
+ }
+ return row + 1;
+ },
+ findTopRow: function(inScrollTop){
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[this.page]);
+ for(var i=0,l=rows.length,t=this.pageTop,h; i<l; i++){
+ h = rows[i].offsetHeight;
+ t += h;
+ if(t >= inScrollTop){
+ this.offset = h - (t - inScrollTop);
+ return i + this.page * this.rowsPerPage;
+ }
+ }
+ return -1;
+ },
+ findScrollTop: function(inRow){
+ var rowPage = Math.floor(inRow / this.rowsPerPage);
+ var t = 0;
+ var i, l;
+ for(i=0; i<rowPage; i++){
+ t += this.getPageHeight(i);
+ }
+ this.pageTop = t;
+ this.page = rowPage;//fix #10543
+ this.needPage(rowPage, this.pageTop);
+
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[rowPage]);
+ var r = inRow - this.rowsPerPage * rowPage;
+ for(i=0,l=rows.length; i<l && i<r; i++){
+ t += rows[i].offsetHeight;
+ }
+ return t;
+ },
+ dummy: 0
+ });
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/_Scroller.xd.js b/js/dojo-1.6/dojox/grid/_Scroller.xd.js
new file mode 100644
index 0000000..dcf6c63
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_Scroller.xd.js
@@ -0,0 +1,519 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid._Scroller"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid._Scroller"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Scroller"] = true;
+dojo.provide("dojox.grid._Scroller");
+
+(function(){
+ var indexInParent = function(inNode){
+ var i=0, n, p=inNode.parentNode;
+ while((n = p.childNodes[i++])){
+ if(n == inNode){
+ return i - 1;
+ }
+ }
+ return -1;
+ };
+
+ var cleanNode = function(inNode){
+ if(!inNode){
+ return;
+ }
+ var filter = function(inW){
+ return inW.domNode && dojo.isDescendant(inW.domNode, inNode, true);
+ };
+ var ws = dijit.registry.filter(filter);
+ for(var i=0, w; (w=ws[i]); i++){
+ w.destroy();
+ }
+ delete ws;
+ };
+
+ var getTagName = function(inNodeOrId){
+ var node = dojo.byId(inNodeOrId);
+ return (node && node.tagName ? node.tagName.toLowerCase() : '');
+ };
+
+ var nodeKids = function(inNode, inTag){
+ var result = [];
+ var i=0, n;
+ while((n = inNode.childNodes[i])){
+ i++;
+ if(getTagName(n) == inTag){
+ result.push(n);
+ }
+ }
+ return result;
+ };
+
+ var divkids = function(inNode){
+ return nodeKids(inNode, 'div');
+ };
+
+ dojo.declare("dojox.grid._Scroller", null, {
+ constructor: function(inContentNodes){
+ this.setContentNodes(inContentNodes);
+ this.pageHeights = [];
+ this.pageNodes = [];
+ this.stack = [];
+ },
+ // specified
+ rowCount: 0, // total number of rows to manage
+ defaultRowHeight: 32, // default height of a row
+ keepRows: 100, // maximum number of rows that should exist at one time
+ contentNode: null, // node to contain pages
+ scrollboxNode: null, // node that controls scrolling
+ // calculated
+ defaultPageHeight: 0, // default height of a page
+ keepPages: 10, // maximum number of pages that should exists at one time
+ pageCount: 0,
+ windowHeight: 0,
+ firstVisibleRow: 0,
+ lastVisibleRow: 0,
+ averageRowHeight: 0, // the average height of a row
+ // private
+ page: 0,
+ pageTop: 0,
+ // init
+ init: function(inRowCount, inKeepRows, inRowsPerPage){
+ switch(arguments.length){
+ case 3: this.rowsPerPage = inRowsPerPage;
+ case 2: this.keepRows = inKeepRows;
+ case 1: this.rowCount = inRowCount;
+ default: break;
+ }
+ this.defaultPageHeight = this.defaultRowHeight * this.rowsPerPage;
+ this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage);
+ this.setKeepInfo(this.keepRows);
+ this.invalidate();
+ if(this.scrollboxNode){
+ this.scrollboxNode.scrollTop = 0;
+ this.scroll(0);
+ this.scrollboxNode.onscroll = dojo.hitch(this, 'onscroll');
+ }
+ },
+ _getPageCount: function(rowCount, rowsPerPage){
+ return rowCount ? (Math.ceil(rowCount / rowsPerPage) || 1) : 0;
+ },
+ destroy: function(){
+ this.invalidateNodes();
+ delete this.contentNodes;
+ delete this.contentNode;
+ delete this.scrollboxNode;
+ },
+ setKeepInfo: function(inKeepRows){
+ this.keepRows = inKeepRows;
+ this.keepPages = !this.keepRows ? this.keepPages : Math.max(Math.ceil(this.keepRows / this.rowsPerPage), 2);
+ },
+ // nodes
+ setContentNodes: function(inNodes){
+ this.contentNodes = inNodes;
+ this.colCount = (this.contentNodes ? this.contentNodes.length : 0);
+ this.pageNodes = [];
+ for(var i=0; i<this.colCount; i++){
+ this.pageNodes[i] = [];
+ }
+ },
+ getDefaultNodes: function(){
+ return this.pageNodes[0] || [];
+ },
+ // updating
+ invalidate: function(){
+ this._invalidating = true;
+ this.invalidateNodes();
+ this.pageHeights = [];
+ this.height = (this.pageCount ? (this.pageCount - 1)* this.defaultPageHeight + this.calcLastPageHeight() : 0);
+ this.resize();
+ this._invalidating = false;
+ },
+ updateRowCount: function(inRowCount){
+ this.invalidateNodes();
+ this.rowCount = inRowCount;
+ // update page count, adjust document height
+ var oldPageCount = this.pageCount;
+ if(oldPageCount === 0){
+ //We want to have at least 1px in height to keep scroller. Otherwise with an
+ //empty grid you can't scroll to see the header.
+ this.height = 1;
+ }
+ this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage);
+ if(this.pageCount < oldPageCount){
+ for(var i=oldPageCount-1; i>=this.pageCount; i--){
+ this.height -= this.getPageHeight(i);
+ delete this.pageHeights[i];
+ }
+ }else if(this.pageCount > oldPageCount){
+ this.height += this.defaultPageHeight * (this.pageCount - oldPageCount - 1) + this.calcLastPageHeight();
+ }
+ this.resize();
+ },
+ // implementation for page manager
+ pageExists: function(inPageIndex){
+ return Boolean(this.getDefaultPageNode(inPageIndex));
+ },
+ measurePage: function(inPageIndex){
+ if(this.grid.rowHeight){
+ var height = this.grid.rowHeight + 1;
+ return ((inPageIndex + 1) * this.rowsPerPage > this.rowCount ?
+ this.rowCount - inPageIndex * this.rowsPerPage :
+ this.rowsPerPage) * height;
+
+ }
+ var n = this.getDefaultPageNode(inPageIndex);
+ return (n && n.innerHTML) ? n.offsetHeight : undefined;
+ },
+ positionPage: function(inPageIndex, inPos){
+ for(var i=0; i<this.colCount; i++){
+ this.pageNodes[i][inPageIndex].style.top = inPos + 'px';
+ }
+ },
+ repositionPages: function(inPageIndex){
+ var nodes = this.getDefaultNodes();
+ var last = 0;
+
+ for(var i=0; i<this.stack.length; i++){
+ last = Math.max(this.stack[i], last);
+ }
+ //
+ var n = nodes[inPageIndex];
+ var y = (n ? this.getPageNodePosition(n) + this.getPageHeight(inPageIndex) : 0);
+ for(var p=inPageIndex+1; p<=last; p++){
+ n = nodes[p];
+ if(n){
+ if(this.getPageNodePosition(n) == y){
+ return;
+ }
+ this.positionPage(p, y);
+ }
+ y += this.getPageHeight(p);
+ }
+ },
+ installPage: function(inPageIndex){
+ for(var i=0; i<this.colCount; i++){
+ this.contentNodes[i].appendChild(this.pageNodes[i][inPageIndex]);
+ }
+ },
+ preparePage: function(inPageIndex, inReuseNode){
+ var p = (inReuseNode ? this.popPage() : null);
+ for(var i=0; i<this.colCount; i++){
+ var nodes = this.pageNodes[i];
+ var new_p = (p === null ? this.createPageNode() : this.invalidatePageNode(p, nodes));
+ new_p.pageIndex = inPageIndex;
+ nodes[inPageIndex] = new_p;
+ }
+ },
+ // rendering implementation
+ renderPage: function(inPageIndex){
+ var nodes = [];
+ var i, j;
+ for(i=0; i<this.colCount; i++){
+ nodes[i] = this.pageNodes[i][inPageIndex];
+ }
+ for(i=0, j=inPageIndex*this.rowsPerPage; (i<this.rowsPerPage)&&(j<this.rowCount); i++, j++){
+ this.renderRow(j, nodes);
+ }
+ },
+ removePage: function(inPageIndex){
+ for(var i=0, j=inPageIndex*this.rowsPerPage; i<this.rowsPerPage; i++, j++){
+ this.removeRow(j);
+ }
+ },
+ destroyPage: function(inPageIndex){
+ for(var i=0; i<this.colCount; i++){
+ var n = this.invalidatePageNode(inPageIndex, this.pageNodes[i]);
+ if(n){
+ dojo.destroy(n);
+ }
+ }
+ },
+ pacify: function(inShouldPacify){
+ },
+ // pacification
+ pacifying: false,
+ pacifyTicks: 200,
+ setPacifying: function(inPacifying){
+ if(this.pacifying != inPacifying){
+ this.pacifying = inPacifying;
+ this.pacify(this.pacifying);
+ }
+ },
+ startPacify: function(){
+ this.startPacifyTicks = new Date().getTime();
+ },
+ doPacify: function(){
+ var result = (new Date().getTime() - this.startPacifyTicks) > this.pacifyTicks;
+ this.setPacifying(true);
+ this.startPacify();
+ return result;
+ },
+ endPacify: function(){
+ this.setPacifying(false);
+ },
+ // default sizing implementation
+ resize: function(){
+ if(this.scrollboxNode){
+ this.windowHeight = this.scrollboxNode.clientHeight;
+ }
+ for(var i=0; i<this.colCount; i++){
+ //We want to have 1px in height min to keep scroller. Otherwise can't scroll
+ //and see header in empty grid.
+ dojox.grid.util.setStyleHeightPx(this.contentNodes[i], Math.max(1,this.height));
+ }
+
+ // Calculate the average row height and update the defaults (row and page).
+ var needPage = (!this._invalidating);
+ if(!needPage){
+ var ah = this.grid.get("autoHeight");
+ if(typeof ah == "number" && ah <= Math.min(this.rowsPerPage, this.rowCount)){
+ needPage = true;
+ }
+ }
+ if(needPage){
+ this.needPage(this.page, this.pageTop);
+ }
+ var rowsOnPage = (this.page < this.pageCount - 1) ? this.rowsPerPage : ((this.rowCount % this.rowsPerPage) || this.rowsPerPage);
+ var pageHeight = this.getPageHeight(this.page);
+ this.averageRowHeight = (pageHeight > 0 && rowsOnPage > 0) ? (pageHeight / rowsOnPage) : 0;
+ },
+ calcLastPageHeight: function(){
+ if(!this.pageCount){
+ return 0;
+ }
+ var lastPage = this.pageCount - 1;
+ var lastPageHeight = ((this.rowCount % this.rowsPerPage)||(this.rowsPerPage)) * this.defaultRowHeight;
+ this.pageHeights[lastPage] = lastPageHeight;
+ return lastPageHeight;
+ },
+ updateContentHeight: function(inDh){
+ this.height += inDh;
+ this.resize();
+ },
+ updatePageHeight: function(inPageIndex, fromBuild, fromAsynRendering){
+ if(this.pageExists(inPageIndex)){
+ var oh = this.getPageHeight(inPageIndex);
+ var h = (this.measurePage(inPageIndex));
+ if(h === undefined){
+ h = oh;
+ }
+ this.pageHeights[inPageIndex] = h;
+ if(oh != h){
+ this.updateContentHeight(h - oh);
+ var ah = this.grid.get("autoHeight");
+ if((typeof ah == "number" && ah > this.rowCount)||(ah === true && !fromBuild)){
+ if(!fromAsynRendering){
+ this.grid.sizeChange();
+ }else{//fix #11101 by using fromAsynRendering to avoid deadlock
+ var ns = this.grid.viewsNode.style;
+ ns.height = parseInt(ns.height) + h - oh + 'px';
+ this.repositionPages(inPageIndex);
+ }
+ }else{
+ this.repositionPages(inPageIndex);
+ }
+ }
+ return h;
+ }
+ return 0;
+ },
+ rowHeightChanged: function(inRowIndex, fromAsynRendering){
+ this.updatePageHeight(Math.floor(inRowIndex / this.rowsPerPage), false, fromAsynRendering);
+ },
+ // scroller core
+ invalidateNodes: function(){
+ while(this.stack.length){
+ this.destroyPage(this.popPage());
+ }
+ },
+ createPageNode: function(){
+ var p = document.createElement('div');
+ dojo.attr(p,"role","presentation");
+ p.style.position = 'absolute';
+ //p.style.width = '100%';
+ p.style[dojo._isBodyLtr() ? "left" : "right"] = '0';
+ return p;
+ },
+ getPageHeight: function(inPageIndex){
+ var ph = this.pageHeights[inPageIndex];
+ return (ph !== undefined ? ph : this.defaultPageHeight);
+ },
+ // FIXME: this is not a stack, it's a FIFO list
+ pushPage: function(inPageIndex){
+ return this.stack.push(inPageIndex);
+ },
+ popPage: function(){
+ return this.stack.shift();
+ },
+ findPage: function(inTop){
+ var i = 0, h = 0;
+ for(var ph = 0; i<this.pageCount; i++, h += ph){
+ ph = this.getPageHeight(i);
+ if(h + ph >= inTop){
+ break;
+ }
+ }
+ this.page = i;
+ this.pageTop = h;
+ },
+ buildPage: function(inPageIndex, inReuseNode, inPos){
+ this.preparePage(inPageIndex, inReuseNode);
+ this.positionPage(inPageIndex, inPos);
+ // order of operations is key below
+ this.installPage(inPageIndex);
+ this.renderPage(inPageIndex);
+ // order of operations is key above
+ this.pushPage(inPageIndex);
+ },
+ needPage: function(inPageIndex, inPos){
+ var h = this.getPageHeight(inPageIndex), oh = h;
+ if(!this.pageExists(inPageIndex)){
+ this.buildPage(inPageIndex, (!this.grid._autoHeight/*fix #10543*/ && this.keepPages&&(this.stack.length >= this.keepPages)), inPos);
+ h = this.updatePageHeight(inPageIndex, true);
+ }else{
+ this.positionPage(inPageIndex, inPos);
+ }
+ return h;
+ },
+ onscroll: function(){
+ this.scroll(this.scrollboxNode.scrollTop);
+ },
+ scroll: function(inTop){
+ this.grid.scrollTop = inTop;
+ if(this.colCount){
+ this.startPacify();
+ this.findPage(inTop);
+ var h = this.height;
+ var b = this.getScrollBottom(inTop);
+ for(var p=this.page, y=this.pageTop; (p<this.pageCount)&&((b<0)||(y<b)); p++){
+ y += this.needPage(p, y);
+ }
+ this.firstVisibleRow = this.getFirstVisibleRow(this.page, this.pageTop, inTop);
+ this.lastVisibleRow = this.getLastVisibleRow(p - 1, y, b);
+ // indicates some page size has been updated
+ if(h != this.height){
+ this.repositionPages(p-1);
+ }
+ this.endPacify();
+ }
+ },
+ getScrollBottom: function(inTop){
+ return (this.windowHeight >= 0 ? inTop + this.windowHeight : -1);
+ },
+ // events
+ processNodeEvent: function(e, inNode){
+ var t = e.target;
+ while(t && (t != inNode) && t.parentNode && (t.parentNode.parentNode != inNode)){
+ t = t.parentNode;
+ }
+ if(!t || !t.parentNode || (t.parentNode.parentNode != inNode)){
+ return false;
+ }
+ var page = t.parentNode;
+ e.topRowIndex = page.pageIndex * this.rowsPerPage;
+ e.rowIndex = e.topRowIndex + indexInParent(t);
+ e.rowTarget = t;
+ return true;
+ },
+ processEvent: function(e){
+ return this.processNodeEvent(e, this.contentNode);
+ },
+ // virtual rendering interface
+ renderRow: function(inRowIndex, inPageNode){
+ },
+ removeRow: function(inRowIndex){
+ },
+ // page node operations
+ getDefaultPageNode: function(inPageIndex){
+ return this.getDefaultNodes()[inPageIndex];
+ },
+ positionPageNode: function(inNode, inPos){
+ },
+ getPageNodePosition: function(inNode){
+ return inNode.offsetTop;
+ },
+ invalidatePageNode: function(inPageIndex, inNodes){
+ var p = inNodes[inPageIndex];
+ if(p){
+ delete inNodes[inPageIndex];
+ this.removePage(inPageIndex, p);
+ cleanNode(p);
+ p.innerHTML = '';
+ }
+ return p;
+ },
+ // scroll control
+ getPageRow: function(inPage){
+ return inPage * this.rowsPerPage;
+ },
+ getLastPageRow: function(inPage){
+ return Math.min(this.rowCount, this.getPageRow(inPage + 1)) - 1;
+ },
+ getFirstVisibleRow: function(inPage, inPageTop, inScrollTop){
+ if(!this.pageExists(inPage)){
+ return 0;
+ }
+ var row = this.getPageRow(inPage);
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[inPage]);
+ for(var i=0,l=rows.length; i<l && inPageTop<inScrollTop; i++, row++){
+ inPageTop += rows[i].offsetHeight;
+ }
+ return (row ? row - 1 : row);
+ },
+ getLastVisibleRow: function(inPage, inBottom, inScrollBottom){
+ if(!this.pageExists(inPage)){
+ return 0;
+ }
+ var nodes = this.getDefaultNodes();
+ var row = this.getLastPageRow(inPage);
+ var rows = divkids(nodes[inPage]);
+ for(var i=rows.length-1; i>=0 && inBottom>inScrollBottom; i--, row--){
+ inBottom -= rows[i].offsetHeight;
+ }
+ return row + 1;
+ },
+ findTopRow: function(inScrollTop){
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[this.page]);
+ for(var i=0,l=rows.length,t=this.pageTop,h; i<l; i++){
+ h = rows[i].offsetHeight;
+ t += h;
+ if(t >= inScrollTop){
+ this.offset = h - (t - inScrollTop);
+ return i + this.page * this.rowsPerPage;
+ }
+ }
+ return -1;
+ },
+ findScrollTop: function(inRow){
+ var rowPage = Math.floor(inRow / this.rowsPerPage);
+ var t = 0;
+ var i, l;
+ for(i=0; i<rowPage; i++){
+ t += this.getPageHeight(i);
+ }
+ this.pageTop = t;
+ this.page = rowPage;//fix #10543
+ this.needPage(rowPage, this.pageTop);
+
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[rowPage]);
+ var r = inRow - this.rowsPerPage * rowPage;
+ for(i=0,l=rows.length; i<l && i<r; i++){
+ t += rows[i].offsetHeight;
+ }
+ return t;
+ },
+ dummy: 0
+ });
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/_Selector.js b/js/dojo-1.6/dojox/grid/_Selector.js
new file mode 100644
index 0000000..37880dd
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_Selector.js
@@ -0,0 +1,227 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid._Selector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Selector"] = true;
+dojo.provide("dojox.grid._Selector");
+
+dojo.require("dojox.grid.Selection");
+dojo.require("dojox.grid._View");
+dojo.require("dojox.grid._Builder");
+
+(function(){
+ dojox.grid._InputSelectorHeaderBuilder = dojo.extend(function(view){
+ dojox.grid._HeaderBuilder.call(this, view);
+ },dojox.grid._HeaderBuilder.prototype,{
+ generateHtml: function(){
+ var w = this.view.contentWidth || 0;
+ var selectedCount = this.view.grid.selection.getSelectedCount();
+ var checked = (selectedCount && selectedCount == this.view.grid.rowCount) ? ' dijitCheckBoxChecked dijitChecked' : '';
+ return '<table style="width:' + w + 'px;" ' +
+ 'border="0" cellspacing="0" cellpadding="0" ' +
+ 'role="presentation"><tr><th style="text-align: center;">' +
+ '<div class="dojoxGridCheckSelector dijitReset dijitInline dijitCheckBox' + checked + '"></div></th></tr></table>';
+ },
+ doclick: function(e){
+ var selectedCount = this.view.grid.selection.getSelectedCount();
+
+ this.view._selectionChanging = true;
+ if(selectedCount==this.view.grid.rowCount){
+ this.view.grid.selection.deselectAll();
+ }else{
+ this.view.grid.selection.selectRange(0, this.view.grid.rowCount-1);
+ }
+ this.view._selectionChanging = false;
+ this.view.onSelectionChanged();
+ return true;
+ }
+ });
+
+ dojox.grid._SelectorContentBuilder = dojo.extend(function(view){
+ dojox.grid._ContentBuilder.call(this, view);
+ },dojox.grid._ContentBuilder.prototype,{
+ generateHtml: function(inDataIndex, inRowIndex){
+ var w = this.view.contentWidth || 0;
+ return '<table class="dojoxGridRowbarTable" style="width:' + w + 'px;" border="0" ' +
+ 'cellspacing="0" cellpadding="0" role="presentation"><tr>' +
+ '<td style="text-align: center;" class="dojoxGridRowbarInner">' + this.getCellContent(inRowIndex) + '</td></tr></table>';
+ },
+ getCellContent: function(inRowIndex){
+ return '&nbsp;';
+ },
+ findTarget: function(){
+ var t = dojox.grid._ContentBuilder.prototype.findTarget.apply(this, arguments);
+ return t;
+ },
+ domouseover: function(e){
+ this.view.grid.onMouseOverRow(e);
+ },
+ domouseout: function(e){
+ if(!this.isIntraRowEvent(e)){
+ this.view.grid.onMouseOutRow(e);
+ }
+ },
+ doclick: function(e){
+ var idx = e.rowIndex;
+ var selected = this.view.grid.selection.isSelected(idx);
+ var mode = this.view.grid.selection.mode;
+
+ if(!selected){
+ if(mode == 'single'){
+ this.view.grid.selection.select(idx);
+ }else if(mode != 'none'){
+ this.view.grid.selection.addToSelection(idx);
+ }
+ }else{
+ this.view.grid.selection.deselect(idx);
+ }
+
+ return true;
+ }
+ });
+
+ dojox.grid._InputSelectorContentBuilder = dojo.extend(function(view){
+ dojox.grid._SelectorContentBuilder.call(this, view);
+ },dojox.grid._SelectorContentBuilder.prototype,{
+ getCellContent: function(rowIndex){
+ var v = this.view;
+ var type = v.inputType == "checkbox" ? "CheckBox" : "Radio";
+ var checked = !!v.grid.selection.isSelected(rowIndex) ? ' dijit' + type + 'Checked dijitChecked' : '';
+ return '<div class="dojoxGridCheckSelector dijitReset dijitInline dijit' + type + checked + '"></div>';
+ }
+ });
+
+ dojo.declare("dojox.grid._Selector", dojox.grid._View, {
+ inputType: '',
+ selectionMode: '',
+
+ // summary:
+ // Custom grid view. If used in a grid structure, provides a small selectable region for grid rows.
+ defaultWidth: "2em",
+ noscroll: true,
+ padBorderWidth: 2,
+
+ _contentBuilderClass: dojox.grid._SelectorContentBuilder,
+
+ postCreate: function(){
+ this.inherited(arguments);
+
+ if(this.selectionMode){
+ this.grid.selection.mode = this.selectionMode;
+ }
+ this.connect(this.grid.selection, 'onSelected', 'onSelected');
+ this.connect(this.grid.selection, 'onDeselected', 'onDeselected');
+ },
+ buildRendering: function(){
+ this.inherited(arguments);
+ this.scrollboxNode.style.overflow = "hidden";
+ },
+ getWidth: function(){
+ return this.viewWidth || this.defaultWidth;
+ },
+ resize: function(){
+ this.adaptHeight();
+ },
+ setStructure: function(s){
+ this.inherited(arguments);
+ if(s.defaultWidth){
+ this.defaultWidth = s.defaultWidth;
+ }
+ },
+ adaptWidth: function(){
+ // Only calculate this here - rather than every call to buildRowContent
+ if(!("contentWidth" in this) && this.contentNode){
+ this.contentWidth = this.contentNode.offsetWidth - this.padBorderWidth;
+ }
+ },
+ // styling
+ doStyleRowNode: function(inRowIndex, inRowNode){
+ var n = [ "dojoxGridRowbar dojoxGridNonNormalizedCell" ];
+ if(this.grid.rows.isOver(inRowIndex)){
+ n.push("dojoxGridRowbarOver");
+ }
+ if(this.grid.selection.isSelected(inRowIndex)){
+ n.push("dojoxGridRowbarSelected");
+ }
+ inRowNode.className = n.join(" ");
+ },
+ // event handlers
+ onSelected: function(inIndex){
+ this.grid.updateRow(inIndex);
+ },
+ onDeselected: function(inIndex){
+ this.grid.updateRow(inIndex);
+ }
+ });
+ if(!dojox.grid._View.prototype._headerBuilderClass &&
+ !dojox.grid._View.prototype._contentBuilderClass){
+ dojox.grid._Selector.prototype.postCreate = function(){
+ this.connect(this.scrollboxNode,"onscroll","doscroll");
+ dojox.grid.util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]);
+ dojox.grid.util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]);
+ if(this._contentBuilderClass){
+ this.content = new this._contentBuilderClass(this);
+ }else{
+ this.content = new dojox.grid._ContentBuilder(this);
+ }
+ if(this._headerBuilderClass){
+ this.header = new this._headerBuilderClass(this);
+ }else{
+ this.header = new dojox.grid._HeaderBuilder(this);
+ }
+ //BiDi: in RTL case, style width='9000em' causes scrolling problem in head node
+ if(!dojo._isBodyLtr()){
+ this.headerNodeContainer.style.width = "";
+ }
+ this.connect(this.grid.selection, 'onSelected', 'onSelected');
+ this.connect(this.grid.selection, 'onDeselected', 'onDeselected');
+ };
+ }
+
+ dojo.declare("dojox.grid._RadioSelector", dojox.grid._Selector, {
+ inputType: 'radio',
+ selectionMode: 'single',
+
+ _contentBuilderClass: dojox.grid._InputSelectorContentBuilder,
+
+ buildRendering: function(){
+ this.inherited(arguments);
+ this.headerNode.style.visibility = "hidden";
+ },
+
+ renderHeader: function(){}
+ });
+
+ dojo.declare("dojox.grid._CheckBoxSelector", dojox.grid._Selector, {
+ inputType: 'checkbox',
+ _headerBuilderClass: dojox.grid._InputSelectorHeaderBuilder,
+ _contentBuilderClass: dojox.grid._InputSelectorContentBuilder,
+ postCreate: function(){
+ this.inherited(arguments);
+ this.connect(this.grid, 'onSelectionChanged', 'onSelectionChanged');
+ this.connect(this.grid, 'updateRowCount', '_updateVisibility');
+ },
+ renderHeader: function(){
+ this.inherited(arguments);
+ this._updateVisibility(this.grid.rowCount);
+ },
+ _updateVisibility: function(rowCount){
+ this.headerNode.style.visibility = rowCount ? "" : "hidden";
+ },
+ onSelectionChanged: function(){
+ if(this._selectionChanging){ return; }
+ var inputDiv = dojo.query('.dojoxGridCheckSelector', this.headerNode)[0];
+ var g = this.grid;
+ var s = (g.rowCount && g.rowCount == g.selection.getSelectedCount());
+ g.allItemsSelected = s||false;
+ dojo.toggleClass(inputDiv, "dijitChecked", g.allItemsSelected);
+ dojo.toggleClass(inputDiv, "dijitCheckBoxChecked", g.allItemsSelected);
+ }
+ });
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/_Selector.xd.js b/js/dojo-1.6/dojox/grid/_Selector.xd.js
new file mode 100644
index 0000000..0d72a29
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_Selector.xd.js
@@ -0,0 +1,234 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid._Selector"],
+["require", "dojox.grid.Selection"],
+["require", "dojox.grid._View"],
+["require", "dojox.grid._Builder"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid._Selector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Selector"] = true;
+dojo.provide("dojox.grid._Selector");
+
+dojo.require("dojox.grid.Selection");
+dojo.require("dojox.grid._View");
+dojo.require("dojox.grid._Builder");
+
+(function(){
+ dojox.grid._InputSelectorHeaderBuilder = dojo.extend(function(view){
+ dojox.grid._HeaderBuilder.call(this, view);
+ },dojox.grid._HeaderBuilder.prototype,{
+ generateHtml: function(){
+ var w = this.view.contentWidth || 0;
+ var selectedCount = this.view.grid.selection.getSelectedCount();
+ var checked = (selectedCount && selectedCount == this.view.grid.rowCount) ? ' dijitCheckBoxChecked dijitChecked' : '';
+ return '<table style="width:' + w + 'px;" ' +
+ 'border="0" cellspacing="0" cellpadding="0" ' +
+ 'role="presentation"><tr><th style="text-align: center;">' +
+ '<div class="dojoxGridCheckSelector dijitReset dijitInline dijitCheckBox' + checked + '"></div></th></tr></table>';
+ },
+ doclick: function(e){
+ var selectedCount = this.view.grid.selection.getSelectedCount();
+
+ this.view._selectionChanging = true;
+ if(selectedCount==this.view.grid.rowCount){
+ this.view.grid.selection.deselectAll();
+ }else{
+ this.view.grid.selection.selectRange(0, this.view.grid.rowCount-1);
+ }
+ this.view._selectionChanging = false;
+ this.view.onSelectionChanged();
+ return true;
+ }
+ });
+
+ dojox.grid._SelectorContentBuilder = dojo.extend(function(view){
+ dojox.grid._ContentBuilder.call(this, view);
+ },dojox.grid._ContentBuilder.prototype,{
+ generateHtml: function(inDataIndex, inRowIndex){
+ var w = this.view.contentWidth || 0;
+ return '<table class="dojoxGridRowbarTable" style="width:' + w + 'px;" border="0" ' +
+ 'cellspacing="0" cellpadding="0" role="presentation"><tr>' +
+ '<td style="text-align: center;" class="dojoxGridRowbarInner">' + this.getCellContent(inRowIndex) + '</td></tr></table>';
+ },
+ getCellContent: function(inRowIndex){
+ return '&nbsp;';
+ },
+ findTarget: function(){
+ var t = dojox.grid._ContentBuilder.prototype.findTarget.apply(this, arguments);
+ return t;
+ },
+ domouseover: function(e){
+ this.view.grid.onMouseOverRow(e);
+ },
+ domouseout: function(e){
+ if(!this.isIntraRowEvent(e)){
+ this.view.grid.onMouseOutRow(e);
+ }
+ },
+ doclick: function(e){
+ var idx = e.rowIndex;
+ var selected = this.view.grid.selection.isSelected(idx);
+ var mode = this.view.grid.selection.mode;
+
+ if(!selected){
+ if(mode == 'single'){
+ this.view.grid.selection.select(idx);
+ }else if(mode != 'none'){
+ this.view.grid.selection.addToSelection(idx);
+ }
+ }else{
+ this.view.grid.selection.deselect(idx);
+ }
+
+ return true;
+ }
+ });
+
+ dojox.grid._InputSelectorContentBuilder = dojo.extend(function(view){
+ dojox.grid._SelectorContentBuilder.call(this, view);
+ },dojox.grid._SelectorContentBuilder.prototype,{
+ getCellContent: function(rowIndex){
+ var v = this.view;
+ var type = v.inputType == "checkbox" ? "CheckBox" : "Radio";
+ var checked = !!v.grid.selection.isSelected(rowIndex) ? ' dijit' + type + 'Checked dijitChecked' : '';
+ return '<div class="dojoxGridCheckSelector dijitReset dijitInline dijit' + type + checked + '"></div>';
+ }
+ });
+
+ dojo.declare("dojox.grid._Selector", dojox.grid._View, {
+ inputType: '',
+ selectionMode: '',
+
+ // summary:
+ // Custom grid view. If used in a grid structure, provides a small selectable region for grid rows.
+ defaultWidth: "2em",
+ noscroll: true,
+ padBorderWidth: 2,
+
+ _contentBuilderClass: dojox.grid._SelectorContentBuilder,
+
+ postCreate: function(){
+ this.inherited(arguments);
+
+ if(this.selectionMode){
+ this.grid.selection.mode = this.selectionMode;
+ }
+ this.connect(this.grid.selection, 'onSelected', 'onSelected');
+ this.connect(this.grid.selection, 'onDeselected', 'onDeselected');
+ },
+ buildRendering: function(){
+ this.inherited(arguments);
+ this.scrollboxNode.style.overflow = "hidden";
+ },
+ getWidth: function(){
+ return this.viewWidth || this.defaultWidth;
+ },
+ resize: function(){
+ this.adaptHeight();
+ },
+ setStructure: function(s){
+ this.inherited(arguments);
+ if(s.defaultWidth){
+ this.defaultWidth = s.defaultWidth;
+ }
+ },
+ adaptWidth: function(){
+ // Only calculate this here - rather than every call to buildRowContent
+ if(!("contentWidth" in this) && this.contentNode){
+ this.contentWidth = this.contentNode.offsetWidth - this.padBorderWidth;
+ }
+ },
+ // styling
+ doStyleRowNode: function(inRowIndex, inRowNode){
+ var n = [ "dojoxGridRowbar dojoxGridNonNormalizedCell" ];
+ if(this.grid.rows.isOver(inRowIndex)){
+ n.push("dojoxGridRowbarOver");
+ }
+ if(this.grid.selection.isSelected(inRowIndex)){
+ n.push("dojoxGridRowbarSelected");
+ }
+ inRowNode.className = n.join(" ");
+ },
+ // event handlers
+ onSelected: function(inIndex){
+ this.grid.updateRow(inIndex);
+ },
+ onDeselected: function(inIndex){
+ this.grid.updateRow(inIndex);
+ }
+ });
+ if(!dojox.grid._View.prototype._headerBuilderClass &&
+ !dojox.grid._View.prototype._contentBuilderClass){
+ dojox.grid._Selector.prototype.postCreate = function(){
+ this.connect(this.scrollboxNode,"onscroll","doscroll");
+ dojox.grid.util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]);
+ dojox.grid.util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]);
+ if(this._contentBuilderClass){
+ this.content = new this._contentBuilderClass(this);
+ }else{
+ this.content = new dojox.grid._ContentBuilder(this);
+ }
+ if(this._headerBuilderClass){
+ this.header = new this._headerBuilderClass(this);
+ }else{
+ this.header = new dojox.grid._HeaderBuilder(this);
+ }
+ //BiDi: in RTL case, style width='9000em' causes scrolling problem in head node
+ if(!dojo._isBodyLtr()){
+ this.headerNodeContainer.style.width = "";
+ }
+ this.connect(this.grid.selection, 'onSelected', 'onSelected');
+ this.connect(this.grid.selection, 'onDeselected', 'onDeselected');
+ };
+ }
+
+ dojo.declare("dojox.grid._RadioSelector", dojox.grid._Selector, {
+ inputType: 'radio',
+ selectionMode: 'single',
+
+ _contentBuilderClass: dojox.grid._InputSelectorContentBuilder,
+
+ buildRendering: function(){
+ this.inherited(arguments);
+ this.headerNode.style.visibility = "hidden";
+ },
+
+ renderHeader: function(){}
+ });
+
+ dojo.declare("dojox.grid._CheckBoxSelector", dojox.grid._Selector, {
+ inputType: 'checkbox',
+ _headerBuilderClass: dojox.grid._InputSelectorHeaderBuilder,
+ _contentBuilderClass: dojox.grid._InputSelectorContentBuilder,
+ postCreate: function(){
+ this.inherited(arguments);
+ this.connect(this.grid, 'onSelectionChanged', 'onSelectionChanged');
+ this.connect(this.grid, 'updateRowCount', '_updateVisibility');
+ },
+ renderHeader: function(){
+ this.inherited(arguments);
+ this._updateVisibility(this.grid.rowCount);
+ },
+ _updateVisibility: function(rowCount){
+ this.headerNode.style.visibility = rowCount ? "" : "hidden";
+ },
+ onSelectionChanged: function(){
+ if(this._selectionChanging){ return; }
+ var inputDiv = dojo.query('.dojoxGridCheckSelector', this.headerNode)[0];
+ var g = this.grid;
+ var s = (g.rowCount && g.rowCount == g.selection.getSelectedCount());
+ g.allItemsSelected = s||false;
+ dojo.toggleClass(inputDiv, "dijitChecked", g.allItemsSelected);
+ dojo.toggleClass(inputDiv, "dijitCheckBoxChecked", g.allItemsSelected);
+ }
+ });
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/_TreeView.js b/js/dojo-1.6/dojox/grid/_TreeView.js
new file mode 100644
index 0000000..18aaf9c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_TreeView.js
@@ -0,0 +1,454 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid._TreeView"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._TreeView"] = true;
+dojo.provide("dojox.grid._TreeView");
+
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojox.grid._View");
+
+dojo.declare("dojox.grid._Expando", [ dijit._Widget, dijit._Templated ], {
+ open: false,
+ toggleClass: "",
+ itemId: "",
+ cellIdx: -1,
+ view: null,
+ rowNode: null,
+ rowIdx: -1,
+ expandoCell: null,
+ level: 0,
+ templateString:"<div class=\"dojoxGridExpando\"\r\n\t><div class=\"dojoxGridExpandoNode\" dojoAttachEvent=\"onclick:onToggle\"\r\n\t\t><div class=\"dojoxGridExpandoNodeInner\" dojoAttachPoint=\"expandoInner\"></div\r\n\t></div\r\n></div>\r\n",
+ _toggleRows: function(toggleClass, open){
+ if(!toggleClass || !this.rowNode){ return; }
+ if(dojo.query("table.dojoxGridRowTableNeedsRowUpdate").length){
+ if(this._initialized){
+ this.view.grid.updateRow(this.rowIdx);
+ }
+ return;
+ }
+ var self = this;
+ var g = this.view.grid;
+ if(g.treeModel){
+ var p = this._tableRow ? dojo.attr(this._tableRow, "dojoxTreeGridPath") : "";
+ if(p){
+ dojo.query("tr[dojoxTreeGridPath^=\"" + p + "/\"]", this.rowNode).forEach(function(n){
+ var en = dojo.query(".dojoxGridExpando", n)[0];
+ if(en && en.parentNode && en.parentNode.parentNode &&
+ !dojo.hasClass(en.parentNode.parentNode, "dojoxGridNoChildren")){
+ var ew = dijit.byNode(en);
+ if(ew){
+ ew._toggleRows(toggleClass, ew.open&&open);
+ }
+ }
+ n.style.display = open ? "" : "none";
+ });
+ }
+ }else{
+ dojo.query("tr." + toggleClass, this.rowNode).forEach(function(n){
+ if(dojo.hasClass(n, "dojoxGridExpandoRow")){
+ var en = dojo.query(".dojoxGridExpando", n)[0];
+ if(en){
+ var ew = dijit.byNode(en);
+ var toggleClass = ew ? ew.toggleClass : en.getAttribute("toggleClass");
+ var wOpen = ew ? ew.open : self.expandoCell.getOpenState(en.getAttribute("itemId"));
+ self._toggleRows(toggleClass, wOpen&&open);
+ }
+ }
+ n.style.display = open ? "" : "none";
+ });
+ }
+ },
+ setOpen: function(open){
+ if(open && dojo.hasClass(this.domNode, "dojoxGridExpandoLoading")){
+ open = false;
+ }
+ var view = this.view;
+ var grid = view.grid;
+ var store = grid.store;
+ var treeModel = grid.treeModel;
+ var d = this;
+ var idx = this.rowIdx;
+ var me = grid._by_idx[idx];
+ if(!me){ return; }
+ if(treeModel && !this._loadedChildren){
+ if(open){
+ // Do this to make sure our children are fully-loaded
+ var itm = grid.getItem(dojo.attr(this._tableRow, "dojoxTreeGridPath"));
+ if(itm){
+ this.expandoInner.innerHTML = "o";
+ dojo.addClass(this.domNode, "dojoxGridExpandoLoading");
+ treeModel.getChildren(itm, function(items){
+ d._loadedChildren = true;
+ d._setOpen(open);
+ });
+ }else{
+ this._setOpen(open);
+ }
+ }else{
+ this._setOpen(open);
+ }
+ }else if(!treeModel && store){
+ if(open){
+ var data = grid._by_idx[this.rowIdx];
+ if(data&&!store.isItemLoaded(data.item)){
+ this.expandoInner.innerHTML = "o";
+ dojo.addClass(this.domNode, "dojoxGridExpandoLoading");
+ store.loadItem({
+ item: data.item,
+ onItem: dojo.hitch(this, function(i){
+ var idty = store.getIdentity(i);
+ grid._by_idty[idty] = grid._by_idx[this.rowIdx] = { idty: idty, item: i };
+ this._setOpen(open);
+ })
+ });
+ }else{
+ this._setOpen(open);
+ }
+ }else{
+ this._setOpen(open);
+ }
+ }else{
+ this._setOpen(open);
+ }
+ },
+ _setOpen: function(open){
+ if(open && this._tableRow && dojo.hasClass(this._tableRow, "dojoxGridNoChildren")){
+ this._setOpen(false);
+ return;
+ }
+ this.expandoInner.innerHTML = open ? "-" : "+";
+ dojo.removeClass(this.domNode, "dojoxGridExpandoLoading");
+ dojo.toggleClass(this.domNode, "dojoxGridExpandoOpened", open);
+ if(this._tableRow){
+ dojo.toggleClass(this._tableRow, "dojoxGridRowCollapsed", !open);
+ var base = dojo.attr(this._tableRow, "dojoxTreeGridBaseClasses");
+ var new_base = "";
+ if(open){
+ new_base = dojo.trim((" " + base + " ").replace(" dojoxGridRowCollapsed ", " "));
+ }else{
+ if((" " + base + " ").indexOf(' dojoxGridRowCollapsed ') < 0){
+ new_base = base + (base ? ' ' : '' ) + 'dojoxGridRowCollapsed';
+ }else{
+ new_base = base;
+ }
+ }
+ dojo.attr(this._tableRow, 'dojoxTreeGridBaseClasses', new_base);
+ }
+ var changed = (this.open !== open);
+ this.open = open;
+ if(this.expandoCell && this.itemId){
+ this.expandoCell.openStates[this.itemId] = open;
+ }
+ var v = this.view;
+ var g = v.grid;
+ if(this.toggleClass && changed){
+ if(!this._tableRow || !this._tableRow.style.display){
+ this._toggleRows(this.toggleClass, open);
+ }
+ }
+ if(v && this._initialized && this.rowIdx >= 0){
+ g.rowHeightChanged(this.rowIdx);
+ g.postresize();
+ v.hasVScrollbar(true);
+ }
+ this._initialized = true;
+ },
+ onToggle: function(e){
+ this.setOpen(!this.open);
+ dojo.stopEvent(e);
+ },
+ setRowNode: function(rowIdx, rowNode, view){
+ if(this.cellIdx < 0 || !this.itemId){ return false; }
+ this._initialized = false;
+ this.view = view;
+ this.rowNode = rowNode;
+ this.rowIdx = rowIdx;
+ this.expandoCell = view.structure.cells[0][this.cellIdx];
+ var d = this.domNode;
+ if(d && d.parentNode && d.parentNode.parentNode){
+ this._tableRow = d.parentNode.parentNode;
+ }
+ this.open = this.expandoCell.getOpenState(this.itemId);
+ if(view.grid.treeModel){
+ // TODO: Rather than hard-code the 18px and 3px, we should probably
+ // calculate them based off css or something... However, all the
+ // themes that we support use these values.
+ dojo.style(this.domNode , "marginLeft" , (this.level * 18) + "px");
+ if(this.domNode.parentNode){
+ dojo.style(this.domNode.parentNode, "backgroundPosition", ((this.level * 18) + (3)) + "px");
+ }
+ }
+ this.setOpen(this.open);
+ return true;
+ }
+});
+
+dojo.declare("dojox.grid._TreeContentBuilder", dojox.grid._ContentBuilder, {
+ generateHtml: function(inDataIndex, inRowIndex){
+ var
+ html = this.getTableArray(),
+ v = this.view,
+ row = v.structure.cells[0],
+ item = this.grid.getItem(inRowIndex),
+ grid = this.grid,
+ store = this.grid.store;
+
+ dojox.grid.util.fire(this.view, "onBeforeRow", [inRowIndex, [row]]);
+
+ var createRow = function(level, rowItem, summaryRow, toggleClasses, rowStack, shown){
+ if(!shown){
+ if(html[0].indexOf('dojoxGridRowTableNeedsRowUpdate') == -1){
+ html[0] = html[0].replace("dojoxGridRowTable", "dojoxGridRowTable dojoxGridRowTableNeedsRowUpdate");
+ }
+ return;
+ }
+ var rowNodeIdx = html.length;
+ toggleClasses = toggleClasses || [];
+ var tcJoin = toggleClasses.join('|');
+ var tcString = toggleClasses[toggleClasses.length - 1];
+ var clString = tcString + (summaryRow ? " dojoxGridSummaryRow" : "");
+ var sString = "";
+ if(grid.treeModel && rowItem && !grid.treeModel.mayHaveChildren(rowItem)){
+ clString += " dojoxGridNoChildren";
+ }
+ html.push('<tr style="' + sString + '" class="' + clString + '" dojoxTreeGridPath="' + rowStack.join('/') + '" dojoxTreeGridBaseClasses="' + clString + '">');
+ var nextLevel = level + 1;
+ var parentCell = null;
+ for(var i=0, cell; (cell=row[i]); i++){
+ var m = cell.markup, cc = cell.customClasses = [], cs = cell.customStyles = [];
+ // content (format can fill in cc and cs as side-effects)
+ m[5] = cell.formatAtLevel(rowStack, rowItem, level, summaryRow, tcString, cc);
+ // classes
+ m[1] = cc.join(' ');
+ // styles
+ m[3] = cs.join(';');
+ // in-place concat
+ html.push.apply(html, m);
+ if(!parentCell && cell.level === nextLevel && cell.parentCell){
+ parentCell = cell.parentCell;
+ }
+ }
+ html.push('</tr>');
+ if(rowItem && store && store.isItem(rowItem)){
+ var idty = store.getIdentity(rowItem);
+ if(typeof grid._by_idty_paths[idty] == "undefined"){
+ grid._by_idty_paths[idty] = rowStack.join('/');
+ }
+ }
+ var expandoCell;
+ var parentOpen;
+ var path;
+ var values;
+ var iStack = rowStack.concat([]);
+ if(grid.treeModel && rowItem){
+ if(grid.treeModel.mayHaveChildren(rowItem)){
+ expandoCell = v.structure.cells[0][grid.expandoCell||0];
+ parentOpen = expandoCell.getOpenState(rowItem) && shown;
+ path = new dojox.grid.TreePath(rowStack.join('/'), grid);
+ values = path.children(true)||[];
+ dojo.forEach(values, function(cItm, idx){
+ var nToggle = tcJoin.split('|');
+ nToggle.push(nToggle[nToggle.length - 1] + "-" + idx);
+ iStack.push(idx);
+ createRow(nextLevel, cItm, false, nToggle, iStack, parentOpen);
+ iStack.pop();
+ });
+ }
+ }else if(rowItem && parentCell && !summaryRow){
+ expandoCell = v.structure.cells[0][parentCell.level];
+ parentOpen = expandoCell.getOpenState(rowItem) && shown;
+ if(store.hasAttribute(rowItem, parentCell.field)){
+ var tToggle = tcJoin.split('|');
+ tToggle.pop();
+ path = new dojox.grid.TreePath(rowStack.join('/'), grid);
+ values = path.children(true)||[];
+ if(values.length){
+ html[rowNodeIdx] = '<tr class="' + tToggle.join(' ') +' dojoxGridExpandoRow" dojoxTreeGridPath="' + rowStack.join('/') + '">';
+ dojo.forEach(values, function(cItm, idx){
+ var nToggle = tcJoin.split('|');
+ nToggle.push(nToggle[nToggle.length - 1] + "-" + idx);
+ iStack.push(idx);
+ createRow(nextLevel, cItm, false, nToggle, iStack, parentOpen);
+ iStack.pop();
+ });
+ iStack.push(values.length);
+ createRow(level, rowItem, true, toggleClasses, iStack, parentOpen);
+ }else{
+ html[rowNodeIdx] = '<tr class="' + tcString + ' dojoxGridNoChildren" dojoxTreeGridPath="' + rowStack.join('/') + '">';
+ }
+ }else{
+ if(!store.isItemLoaded(rowItem)){
+ html[0] = html[0].replace("dojoxGridRowTable", "dojoxGridRowTable dojoxGridRowTableNeedsRowUpdate");
+ }else{
+ html[rowNodeIdx] = '<tr class="' + tcString + ' dojoxGridNoChildren" dojoxTreeGridPath="' + rowStack.join('/') + '">';
+ }
+ }
+ }else if(rowItem && !summaryRow && toggleClasses.length > 1){
+ html[rowNodeIdx] = '<tr class="' + toggleClasses[toggleClasses.length - 2] + '" dojoxTreeGridPath="' + rowStack.join('/') + '">';
+ }
+ };
+ createRow(0, item, false, ["dojoxGridRowToggle-" + inRowIndex], [inRowIndex], true);
+ html.push('</table>');
+ return html.join(''); // String
+ },
+ findTarget: function(inSource, inTag){
+ var n = inSource;
+ while(n && (n!=this.domNode)){
+ if(n.tagName && n.tagName.toLowerCase() == 'tr'){
+ break;
+ }
+ n = n.parentNode;
+ }
+ return (n != this.domNode) ? n : null;
+ },
+ getCellNode: function(inRowNode, inCellIndex){
+ var node = dojo.query("td[idx='" + inCellIndex + "']", inRowNode)[0];
+ if(node&&node.parentNode&&!dojo.hasClass(node.parentNode, "dojoxGridSummaryRow")){
+ return node;
+ }
+ },
+ decorateEvent: function(e){
+ e.rowNode = this.findRowTarget(e.target);
+ if(!e.rowNode){return false;}
+ e.rowIndex = dojo.attr(e.rowNode, 'dojoxTreeGridPath');
+ this.baseDecorateEvent(e);
+ e.cell = this.grid.getCell(e.cellIndex);
+ return true; // Boolean
+ }
+});
+
+dojo.declare("dojox.grid._TreeView", [dojox.grid._View], {
+ _contentBuilderClass: dojox.grid._TreeContentBuilder,
+ _onDndDrop: function(source, nodes, copy){
+ if(this.grid && this.grid.aggregator){
+ this.grid.aggregator.clearSubtotalCache();
+ }
+ this.inherited(arguments);
+ },
+ postCreate: function(){
+ this.inherited(arguments);
+ this.connect(this.grid, '_cleanupExpandoCache', '_cleanupExpandoCache');
+ },
+ _cleanupExpandoCache: function(index, identity, item){
+ if(index == -1){
+ return;
+ }
+ dojo.forEach(this.grid.layout.cells, function(cell){
+ if(typeof cell['openStates'] != 'undefined'){
+ if(identity in cell.openStates){
+ delete cell.openStates[identity];
+ }
+ }
+ });
+ if(typeof index == "string" && index.indexOf('/') > -1){
+ var path = new dojox.grid.TreePath(index, this.grid);
+ var ppath = path.parent();
+ while(ppath){
+ path = ppath;
+ ppath = path.parent();
+ }
+ var pitem = path.item();
+ if(!pitem){
+ return;
+ }
+ var idty = this.grid.store.getIdentity(pitem);
+ if(typeof this._expandos[idty] != 'undefined'){
+ for(var i in this._expandos[idty]){
+ var exp = this._expandos[idty][i];
+ if(exp){
+ exp.destroy();
+ }
+ delete this._expandos[idty][i];
+ }
+ delete this._expandos[idty];
+ }
+ }else{
+ for(var i in this._expandos){
+ if(typeof this._expandos[i] != 'undefined'){
+ for(var j in this._expandos[i]){
+ var exp = this._expandos[i][j];
+ if(exp){
+ exp.destroy();
+ }
+ }
+ }
+ }
+ this._expandos = {};
+ }
+ },
+ postMixInProperties: function(){
+ this.inherited(arguments);
+ this._expandos = {};
+ },
+ onBeforeRow: function(inRowIndex, cells){
+ // Save off our expando if we have one so we don't have to create it
+ // again
+ var g = this.grid;
+ if(g._by_idx && g._by_idx[inRowIndex] && g._by_idx[inRowIndex].idty){
+ var idty = g._by_idx[inRowIndex].idty;
+ this._expandos[idty] = this._expandos[idty] || {};
+ }
+ this.inherited(arguments);
+ },
+ onAfterRow: function(inRowIndex, cells, inRowNode){
+ dojo.forEach(dojo.query("span.dojoxGridExpando", inRowNode), function(n){
+ if(n && n.parentNode){
+ // Either create our expando or put the existing expando back
+ // into place
+ var tc = n.getAttribute("toggleClass");
+ var idty;
+ var expando;
+ var g = this.grid;
+ if(g._by_idx && g._by_idx[inRowIndex] && g._by_idx[inRowIndex].idty){
+ idty = g._by_idx[inRowIndex].idty;
+ expando = this._expandos[idty][tc];
+ }
+ if(expando){
+ dojo.place(expando.domNode, n, "replace");
+ expando.itemId = n.getAttribute("itemId");
+ expando.cellIdx = parseInt(n.getAttribute("cellIdx"), 10);
+ if(isNaN(expando.cellIdx)){
+ expando.cellIdx = -1;
+ }
+ }else{
+ expando = dojo.parser.parse(n.parentNode)[0];
+ if(idty){
+ this._expandos[idty][tc] = expando;
+ }
+ }
+ if(!expando.setRowNode(inRowIndex, inRowNode, this)){
+ expando.domNode.parentNode.removeChild(expando.domNode);
+ }
+ }
+ }, this);
+ var alt = false;
+ var self = this;
+ dojo.query("tr[dojoxTreeGridPath]", inRowNode).forEach(function(n){
+ dojo.toggleClass(n, "dojoxGridSubRowAlt", alt);
+ dojo.attr(n, "dojoxTreeGridBaseClasses", n.className);
+ alt = !alt;
+ self.grid.rows.styleRowNode(dojo.attr(n, 'dojoxTreeGridPath'), n);
+ });
+ this.inherited(arguments);
+ },
+ updateRowStyles: function(inRowIndex){
+ var rowNodes = dojo.query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode);
+ if(rowNodes.length){
+ this.styleRowNode(inRowIndex, rowNodes[0]);
+ }
+ },
+ getCellNode: function(inRowIndex, inCellIndex){
+ var row = dojo.query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode)[0];
+ if(row){
+ return this.content.getCellNode(row, inCellIndex);
+ }
+ }
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/_TreeView.xd.js b/js/dojo-1.6/dojox/grid/_TreeView.xd.js
new file mode 100644
index 0000000..e5ba531
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_TreeView.xd.js
@@ -0,0 +1,461 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid._TreeView"],
+["require", "dijit._Widget"],
+["require", "dijit._Templated"],
+["require", "dojox.grid._View"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid._TreeView"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._TreeView"] = true;
+dojo.provide("dojox.grid._TreeView");
+
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojox.grid._View");
+
+dojo.declare("dojox.grid._Expando", [ dijit._Widget, dijit._Templated ], {
+ open: false,
+ toggleClass: "",
+ itemId: "",
+ cellIdx: -1,
+ view: null,
+ rowNode: null,
+ rowIdx: -1,
+ expandoCell: null,
+ level: 0,
+ templateString:"<div class=\"dojoxGridExpando\"\r\n\t><div class=\"dojoxGridExpandoNode\" dojoAttachEvent=\"onclick:onToggle\"\r\n\t\t><div class=\"dojoxGridExpandoNodeInner\" dojoAttachPoint=\"expandoInner\"></div\r\n\t></div\r\n></div>\r\n",
+ _toggleRows: function(toggleClass, open){
+ if(!toggleClass || !this.rowNode){ return; }
+ if(dojo.query("table.dojoxGridRowTableNeedsRowUpdate").length){
+ if(this._initialized){
+ this.view.grid.updateRow(this.rowIdx);
+ }
+ return;
+ }
+ var self = this;
+ var g = this.view.grid;
+ if(g.treeModel){
+ var p = this._tableRow ? dojo.attr(this._tableRow, "dojoxTreeGridPath") : "";
+ if(p){
+ dojo.query("tr[dojoxTreeGridPath^=\"" + p + "/\"]", this.rowNode).forEach(function(n){
+ var en = dojo.query(".dojoxGridExpando", n)[0];
+ if(en && en.parentNode && en.parentNode.parentNode &&
+ !dojo.hasClass(en.parentNode.parentNode, "dojoxGridNoChildren")){
+ var ew = dijit.byNode(en);
+ if(ew){
+ ew._toggleRows(toggleClass, ew.open&&open);
+ }
+ }
+ n.style.display = open ? "" : "none";
+ });
+ }
+ }else{
+ dojo.query("tr." + toggleClass, this.rowNode).forEach(function(n){
+ if(dojo.hasClass(n, "dojoxGridExpandoRow")){
+ var en = dojo.query(".dojoxGridExpando", n)[0];
+ if(en){
+ var ew = dijit.byNode(en);
+ var toggleClass = ew ? ew.toggleClass : en.getAttribute("toggleClass");
+ var wOpen = ew ? ew.open : self.expandoCell.getOpenState(en.getAttribute("itemId"));
+ self._toggleRows(toggleClass, wOpen&&open);
+ }
+ }
+ n.style.display = open ? "" : "none";
+ });
+ }
+ },
+ setOpen: function(open){
+ if(open && dojo.hasClass(this.domNode, "dojoxGridExpandoLoading")){
+ open = false;
+ }
+ var view = this.view;
+ var grid = view.grid;
+ var store = grid.store;
+ var treeModel = grid.treeModel;
+ var d = this;
+ var idx = this.rowIdx;
+ var me = grid._by_idx[idx];
+ if(!me){ return; }
+ if(treeModel && !this._loadedChildren){
+ if(open){
+ // Do this to make sure our children are fully-loaded
+ var itm = grid.getItem(dojo.attr(this._tableRow, "dojoxTreeGridPath"));
+ if(itm){
+ this.expandoInner.innerHTML = "o";
+ dojo.addClass(this.domNode, "dojoxGridExpandoLoading");
+ treeModel.getChildren(itm, function(items){
+ d._loadedChildren = true;
+ d._setOpen(open);
+ });
+ }else{
+ this._setOpen(open);
+ }
+ }else{
+ this._setOpen(open);
+ }
+ }else if(!treeModel && store){
+ if(open){
+ var data = grid._by_idx[this.rowIdx];
+ if(data&&!store.isItemLoaded(data.item)){
+ this.expandoInner.innerHTML = "o";
+ dojo.addClass(this.domNode, "dojoxGridExpandoLoading");
+ store.loadItem({
+ item: data.item,
+ onItem: dojo.hitch(this, function(i){
+ var idty = store.getIdentity(i);
+ grid._by_idty[idty] = grid._by_idx[this.rowIdx] = { idty: idty, item: i };
+ this._setOpen(open);
+ })
+ });
+ }else{
+ this._setOpen(open);
+ }
+ }else{
+ this._setOpen(open);
+ }
+ }else{
+ this._setOpen(open);
+ }
+ },
+ _setOpen: function(open){
+ if(open && this._tableRow && dojo.hasClass(this._tableRow, "dojoxGridNoChildren")){
+ this._setOpen(false);
+ return;
+ }
+ this.expandoInner.innerHTML = open ? "-" : "+";
+ dojo.removeClass(this.domNode, "dojoxGridExpandoLoading");
+ dojo.toggleClass(this.domNode, "dojoxGridExpandoOpened", open);
+ if(this._tableRow){
+ dojo.toggleClass(this._tableRow, "dojoxGridRowCollapsed", !open);
+ var base = dojo.attr(this._tableRow, "dojoxTreeGridBaseClasses");
+ var new_base = "";
+ if(open){
+ new_base = dojo.trim((" " + base + " ").replace(" dojoxGridRowCollapsed ", " "));
+ }else{
+ if((" " + base + " ").indexOf(' dojoxGridRowCollapsed ') < 0){
+ new_base = base + (base ? ' ' : '' ) + 'dojoxGridRowCollapsed';
+ }else{
+ new_base = base;
+ }
+ }
+ dojo.attr(this._tableRow, 'dojoxTreeGridBaseClasses', new_base);
+ }
+ var changed = (this.open !== open);
+ this.open = open;
+ if(this.expandoCell && this.itemId){
+ this.expandoCell.openStates[this.itemId] = open;
+ }
+ var v = this.view;
+ var g = v.grid;
+ if(this.toggleClass && changed){
+ if(!this._tableRow || !this._tableRow.style.display){
+ this._toggleRows(this.toggleClass, open);
+ }
+ }
+ if(v && this._initialized && this.rowIdx >= 0){
+ g.rowHeightChanged(this.rowIdx);
+ g.postresize();
+ v.hasVScrollbar(true);
+ }
+ this._initialized = true;
+ },
+ onToggle: function(e){
+ this.setOpen(!this.open);
+ dojo.stopEvent(e);
+ },
+ setRowNode: function(rowIdx, rowNode, view){
+ if(this.cellIdx < 0 || !this.itemId){ return false; }
+ this._initialized = false;
+ this.view = view;
+ this.rowNode = rowNode;
+ this.rowIdx = rowIdx;
+ this.expandoCell = view.structure.cells[0][this.cellIdx];
+ var d = this.domNode;
+ if(d && d.parentNode && d.parentNode.parentNode){
+ this._tableRow = d.parentNode.parentNode;
+ }
+ this.open = this.expandoCell.getOpenState(this.itemId);
+ if(view.grid.treeModel){
+ // TODO: Rather than hard-code the 18px and 3px, we should probably
+ // calculate them based off css or something... However, all the
+ // themes that we support use these values.
+ dojo.style(this.domNode , "marginLeft" , (this.level * 18) + "px");
+ if(this.domNode.parentNode){
+ dojo.style(this.domNode.parentNode, "backgroundPosition", ((this.level * 18) + (3)) + "px");
+ }
+ }
+ this.setOpen(this.open);
+ return true;
+ }
+});
+
+dojo.declare("dojox.grid._TreeContentBuilder", dojox.grid._ContentBuilder, {
+ generateHtml: function(inDataIndex, inRowIndex){
+ var
+ html = this.getTableArray(),
+ v = this.view,
+ row = v.structure.cells[0],
+ item = this.grid.getItem(inRowIndex),
+ grid = this.grid,
+ store = this.grid.store;
+
+ dojox.grid.util.fire(this.view, "onBeforeRow", [inRowIndex, [row]]);
+
+ var createRow = function(level, rowItem, summaryRow, toggleClasses, rowStack, shown){
+ if(!shown){
+ if(html[0].indexOf('dojoxGridRowTableNeedsRowUpdate') == -1){
+ html[0] = html[0].replace("dojoxGridRowTable", "dojoxGridRowTable dojoxGridRowTableNeedsRowUpdate");
+ }
+ return;
+ }
+ var rowNodeIdx = html.length;
+ toggleClasses = toggleClasses || [];
+ var tcJoin = toggleClasses.join('|');
+ var tcString = toggleClasses[toggleClasses.length - 1];
+ var clString = tcString + (summaryRow ? " dojoxGridSummaryRow" : "");
+ var sString = "";
+ if(grid.treeModel && rowItem && !grid.treeModel.mayHaveChildren(rowItem)){
+ clString += " dojoxGridNoChildren";
+ }
+ html.push('<tr style="' + sString + '" class="' + clString + '" dojoxTreeGridPath="' + rowStack.join('/') + '" dojoxTreeGridBaseClasses="' + clString + '">');
+ var nextLevel = level + 1;
+ var parentCell = null;
+ for(var i=0, cell; (cell=row[i]); i++){
+ var m = cell.markup, cc = cell.customClasses = [], cs = cell.customStyles = [];
+ // content (format can fill in cc and cs as side-effects)
+ m[5] = cell.formatAtLevel(rowStack, rowItem, level, summaryRow, tcString, cc);
+ // classes
+ m[1] = cc.join(' ');
+ // styles
+ m[3] = cs.join(';');
+ // in-place concat
+ html.push.apply(html, m);
+ if(!parentCell && cell.level === nextLevel && cell.parentCell){
+ parentCell = cell.parentCell;
+ }
+ }
+ html.push('</tr>');
+ if(rowItem && store && store.isItem(rowItem)){
+ var idty = store.getIdentity(rowItem);
+ if(typeof grid._by_idty_paths[idty] == "undefined"){
+ grid._by_idty_paths[idty] = rowStack.join('/');
+ }
+ }
+ var expandoCell;
+ var parentOpen;
+ var path;
+ var values;
+ var iStack = rowStack.concat([]);
+ if(grid.treeModel && rowItem){
+ if(grid.treeModel.mayHaveChildren(rowItem)){
+ expandoCell = v.structure.cells[0][grid.expandoCell||0];
+ parentOpen = expandoCell.getOpenState(rowItem) && shown;
+ path = new dojox.grid.TreePath(rowStack.join('/'), grid);
+ values = path.children(true)||[];
+ dojo.forEach(values, function(cItm, idx){
+ var nToggle = tcJoin.split('|');
+ nToggle.push(nToggle[nToggle.length - 1] + "-" + idx);
+ iStack.push(idx);
+ createRow(nextLevel, cItm, false, nToggle, iStack, parentOpen);
+ iStack.pop();
+ });
+ }
+ }else if(rowItem && parentCell && !summaryRow){
+ expandoCell = v.structure.cells[0][parentCell.level];
+ parentOpen = expandoCell.getOpenState(rowItem) && shown;
+ if(store.hasAttribute(rowItem, parentCell.field)){
+ var tToggle = tcJoin.split('|');
+ tToggle.pop();
+ path = new dojox.grid.TreePath(rowStack.join('/'), grid);
+ values = path.children(true)||[];
+ if(values.length){
+ html[rowNodeIdx] = '<tr class="' + tToggle.join(' ') +' dojoxGridExpandoRow" dojoxTreeGridPath="' + rowStack.join('/') + '">';
+ dojo.forEach(values, function(cItm, idx){
+ var nToggle = tcJoin.split('|');
+ nToggle.push(nToggle[nToggle.length - 1] + "-" + idx);
+ iStack.push(idx);
+ createRow(nextLevel, cItm, false, nToggle, iStack, parentOpen);
+ iStack.pop();
+ });
+ iStack.push(values.length);
+ createRow(level, rowItem, true, toggleClasses, iStack, parentOpen);
+ }else{
+ html[rowNodeIdx] = '<tr class="' + tcString + ' dojoxGridNoChildren" dojoxTreeGridPath="' + rowStack.join('/') + '">';
+ }
+ }else{
+ if(!store.isItemLoaded(rowItem)){
+ html[0] = html[0].replace("dojoxGridRowTable", "dojoxGridRowTable dojoxGridRowTableNeedsRowUpdate");
+ }else{
+ html[rowNodeIdx] = '<tr class="' + tcString + ' dojoxGridNoChildren" dojoxTreeGridPath="' + rowStack.join('/') + '">';
+ }
+ }
+ }else if(rowItem && !summaryRow && toggleClasses.length > 1){
+ html[rowNodeIdx] = '<tr class="' + toggleClasses[toggleClasses.length - 2] + '" dojoxTreeGridPath="' + rowStack.join('/') + '">';
+ }
+ };
+ createRow(0, item, false, ["dojoxGridRowToggle-" + inRowIndex], [inRowIndex], true);
+ html.push('</table>');
+ return html.join(''); // String
+ },
+ findTarget: function(inSource, inTag){
+ var n = inSource;
+ while(n && (n!=this.domNode)){
+ if(n.tagName && n.tagName.toLowerCase() == 'tr'){
+ break;
+ }
+ n = n.parentNode;
+ }
+ return (n != this.domNode) ? n : null;
+ },
+ getCellNode: function(inRowNode, inCellIndex){
+ var node = dojo.query("td[idx='" + inCellIndex + "']", inRowNode)[0];
+ if(node&&node.parentNode&&!dojo.hasClass(node.parentNode, "dojoxGridSummaryRow")){
+ return node;
+ }
+ },
+ decorateEvent: function(e){
+ e.rowNode = this.findRowTarget(e.target);
+ if(!e.rowNode){return false;}
+ e.rowIndex = dojo.attr(e.rowNode, 'dojoxTreeGridPath');
+ this.baseDecorateEvent(e);
+ e.cell = this.grid.getCell(e.cellIndex);
+ return true; // Boolean
+ }
+});
+
+dojo.declare("dojox.grid._TreeView", [dojox.grid._View], {
+ _contentBuilderClass: dojox.grid._TreeContentBuilder,
+ _onDndDrop: function(source, nodes, copy){
+ if(this.grid && this.grid.aggregator){
+ this.grid.aggregator.clearSubtotalCache();
+ }
+ this.inherited(arguments);
+ },
+ postCreate: function(){
+ this.inherited(arguments);
+ this.connect(this.grid, '_cleanupExpandoCache', '_cleanupExpandoCache');
+ },
+ _cleanupExpandoCache: function(index, identity, item){
+ if(index == -1){
+ return;
+ }
+ dojo.forEach(this.grid.layout.cells, function(cell){
+ if(typeof cell['openStates'] != 'undefined'){
+ if(identity in cell.openStates){
+ delete cell.openStates[identity];
+ }
+ }
+ });
+ if(typeof index == "string" && index.indexOf('/') > -1){
+ var path = new dojox.grid.TreePath(index, this.grid);
+ var ppath = path.parent();
+ while(ppath){
+ path = ppath;
+ ppath = path.parent();
+ }
+ var pitem = path.item();
+ if(!pitem){
+ return;
+ }
+ var idty = this.grid.store.getIdentity(pitem);
+ if(typeof this._expandos[idty] != 'undefined'){
+ for(var i in this._expandos[idty]){
+ var exp = this._expandos[idty][i];
+ if(exp){
+ exp.destroy();
+ }
+ delete this._expandos[idty][i];
+ }
+ delete this._expandos[idty];
+ }
+ }else{
+ for(var i in this._expandos){
+ if(typeof this._expandos[i] != 'undefined'){
+ for(var j in this._expandos[i]){
+ var exp = this._expandos[i][j];
+ if(exp){
+ exp.destroy();
+ }
+ }
+ }
+ }
+ this._expandos = {};
+ }
+ },
+ postMixInProperties: function(){
+ this.inherited(arguments);
+ this._expandos = {};
+ },
+ onBeforeRow: function(inRowIndex, cells){
+ // Save off our expando if we have one so we don't have to create it
+ // again
+ var g = this.grid;
+ if(g._by_idx && g._by_idx[inRowIndex] && g._by_idx[inRowIndex].idty){
+ var idty = g._by_idx[inRowIndex].idty;
+ this._expandos[idty] = this._expandos[idty] || {};
+ }
+ this.inherited(arguments);
+ },
+ onAfterRow: function(inRowIndex, cells, inRowNode){
+ dojo.forEach(dojo.query("span.dojoxGridExpando", inRowNode), function(n){
+ if(n && n.parentNode){
+ // Either create our expando or put the existing expando back
+ // into place
+ var tc = n.getAttribute("toggleClass");
+ var idty;
+ var expando;
+ var g = this.grid;
+ if(g._by_idx && g._by_idx[inRowIndex] && g._by_idx[inRowIndex].idty){
+ idty = g._by_idx[inRowIndex].idty;
+ expando = this._expandos[idty][tc];
+ }
+ if(expando){
+ dojo.place(expando.domNode, n, "replace");
+ expando.itemId = n.getAttribute("itemId");
+ expando.cellIdx = parseInt(n.getAttribute("cellIdx"), 10);
+ if(isNaN(expando.cellIdx)){
+ expando.cellIdx = -1;
+ }
+ }else{
+ expando = dojo.parser.parse(n.parentNode)[0];
+ if(idty){
+ this._expandos[idty][tc] = expando;
+ }
+ }
+ if(!expando.setRowNode(inRowIndex, inRowNode, this)){
+ expando.domNode.parentNode.removeChild(expando.domNode);
+ }
+ }
+ }, this);
+ var alt = false;
+ var self = this;
+ dojo.query("tr[dojoxTreeGridPath]", inRowNode).forEach(function(n){
+ dojo.toggleClass(n, "dojoxGridSubRowAlt", alt);
+ dojo.attr(n, "dojoxTreeGridBaseClasses", n.className);
+ alt = !alt;
+ self.grid.rows.styleRowNode(dojo.attr(n, 'dojoxTreeGridPath'), n);
+ });
+ this.inherited(arguments);
+ },
+ updateRowStyles: function(inRowIndex){
+ var rowNodes = dojo.query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode);
+ if(rowNodes.length){
+ this.styleRowNode(inRowIndex, rowNodes[0]);
+ }
+ },
+ getCellNode: function(inRowIndex, inCellIndex){
+ var row = dojo.query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode)[0];
+ if(row){
+ return this.content.getCellNode(row, inCellIndex);
+ }
+ }
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/_View.js b/js/dojo-1.6/dojox/grid/_View.js
new file mode 100644
index 0000000..8d52d8e
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_View.js
@@ -0,0 +1,844 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid._View"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._View"] = true;
+dojo.provide("dojox.grid._View");
+
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojox.grid._Builder");
+dojo.require("dojox.html.metrics");
+dojo.require("dojox.grid.util");
+
+dojo.require("dojo.dnd.Source");
+dojo.require("dojo.dnd.Manager");
+
+(function(){
+ // a private function
+ var getStyleText = function(inNode, inStyleText){
+ return inNode.style.cssText == undefined ? inNode.getAttribute("style") : inNode.style.cssText;
+ };
+
+ // some public functions
+ dojo.declare('dojox.grid._View', [dijit._Widget, dijit._Templated], {
+ // summary:
+ // A collection of grid columns. A grid is comprised of a set of views that stack horizontally.
+ // Grid creates views automatically based on grid's layout structure.
+ // Users should typically not need to access individual views directly.
+ //
+ // defaultWidth: String
+ // Default width of the view
+ defaultWidth: "18em",
+
+ // viewWidth: String
+ // Width for the view, in valid css unit
+ viewWidth: "",
+
+ templateString:"<div class=\"dojoxGridView\" role=\"presentation\">\r\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" role=\"presentation\">\r\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" role=\"presentation\">\r\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" role=\"row\"></div>\r\n\t\t</div>\r\n\t</div>\r\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" role=\"presentation\" />\r\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" role=\"presentation\" />\r\n\t<div class=\"dojoxGridScrollbox\" dojoAttachPoint=\"scrollboxNode\" role=\"presentation\">\r\n\t\t<div class=\"dojoxGridContent\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\" role=\"presentation\"></div>\r\n\t</div>\r\n</div>\r\n",
+
+ themeable: false,
+ classTag: 'dojoxGrid',
+ marginBottom: 0,
+ rowPad: 2,
+
+ // _togglingColumn: int
+ // Width of the column being toggled (-1 for none)
+ _togglingColumn: -1,
+
+ // _headerBuilderClass: Object
+ // The class to use for our header builder
+ _headerBuilderClass: dojox.grid._HeaderBuilder,
+
+ // _contentBuilderClass: Object
+ // The class to use for our content builder
+ _contentBuilderClass: dojox.grid._ContentBuilder,
+
+ postMixInProperties: function(){
+ this.rowNodes = {};
+ },
+
+ postCreate: function(){
+ this.connect(this.scrollboxNode,"onscroll","doscroll");
+ dojox.grid.util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]);
+ dojox.grid.util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]);
+ this.content = new this._contentBuilderClass(this);
+ this.header = new this._headerBuilderClass(this);
+ //BiDi: in RTL case, style width='9000em' causes scrolling problem in head node
+ if(!dojo._isBodyLtr()){
+ this.headerNodeContainer.style.width = "";
+ }
+ },
+
+ destroy: function(){
+ dojo.destroy(this.headerNode);
+ delete this.headerNode;
+ for(var i in this.rowNodes){
+ dojo.destroy(this.rowNodes[i]);
+ }
+ this.rowNodes = {};
+ if(this.source){
+ this.source.destroy();
+ }
+ this.inherited(arguments);
+ },
+
+ // focus
+ focus: function(){
+ if(dojo.isIE || dojo.isWebKit || dojo.isOpera){
+ this.hiddenFocusNode.focus();
+ }else{
+ this.scrollboxNode.focus();
+ }
+ },
+
+ setStructure: function(inStructure){
+ var vs = (this.structure = inStructure);
+ // FIXME: similar logic is duplicated in layout
+ if(vs.width && !isNaN(vs.width)){
+ this.viewWidth = vs.width + 'em';
+ }else{
+ this.viewWidth = vs.width || (vs.noscroll ? 'auto' : this.viewWidth); //|| this.defaultWidth;
+ }
+ this._onBeforeRow = vs.onBeforeRow||function(){};
+ this._onAfterRow = vs.onAfterRow||function(){};
+ this.noscroll = vs.noscroll;
+ if(this.noscroll){
+ this.scrollboxNode.style.overflow = "hidden";
+ }
+ this.simpleStructure = Boolean(vs.cells.length == 1);
+ // bookkeeping
+ this.testFlexCells();
+ // accomodate new structure
+ this.updateStructure();
+ },
+
+ _cleanupRowWidgets: function(inRowNode){
+ // Summary:
+ // Cleans up the widgets for the given row node so that
+ // we can reattach them if needed
+ if(inRowNode){
+ dojo.forEach(dojo.query("[widgetId]", inRowNode).map(dijit.byNode), function(w){
+ if(w._destroyOnRemove){
+ w.destroy();
+ delete w;
+ }else if(w.domNode && w.domNode.parentNode){
+ w.domNode.parentNode.removeChild(w.domNode);
+ }
+ });
+ }
+ },
+
+ onBeforeRow: function(inRowIndex, cells){
+ this._onBeforeRow(inRowIndex, cells);
+ if(inRowIndex >= 0){
+ this._cleanupRowWidgets(this.getRowNode(inRowIndex));
+ }
+ },
+
+ onAfterRow: function(inRowIndex, cells, inRowNode){
+ this._onAfterRow(inRowIndex, cells, inRowNode);
+ var g = this.grid;
+ dojo.forEach(dojo.query(".dojoxGridStubNode", inRowNode), function(n){
+ if(n && n.parentNode){
+ var lw = n.getAttribute("linkWidget");
+ var cellIdx = window.parseInt(dojo.attr(n, "cellIdx"), 10);
+ var cellDef = g.getCell(cellIdx);
+ var w = dijit.byId(lw);
+ if(w){
+ n.parentNode.replaceChild(w.domNode, n);
+ if(!w._started){
+ w.startup();
+ }
+ }else{
+ n.innerHTML = "";
+ }
+ }
+ }, this);
+ },
+
+ testFlexCells: function(){
+ // FIXME: cheater, this function does double duty as initializer and tester
+ this.flexCells = false;
+ for(var j=0, row; (row=this.structure.cells[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ cell.view = this;
+ this.flexCells = this.flexCells || cell.isFlex();
+ }
+ }
+ return this.flexCells;
+ },
+
+ updateStructure: function(){
+ // header builder needs to update table map
+ this.header.update();
+ // content builder needs to update markup cache
+ this.content.update();
+ },
+
+ getScrollbarWidth: function(){
+ var hasScrollSpace = this.hasVScrollbar();
+ var overflow = dojo.style(this.scrollboxNode, "overflow");
+ if(this.noscroll || !overflow || overflow == "hidden"){
+ hasScrollSpace = false;
+ }else if(overflow == "scroll"){
+ hasScrollSpace = true;
+ }
+ return (hasScrollSpace ? dojox.html.metrics.getScrollbar().w : 0); // Integer
+ },
+
+ getColumnsWidth: function(){
+ var h = this.headerContentNode;
+ return h && h.firstChild ? h.firstChild.offsetWidth : 0; // Integer
+ },
+
+ setColumnsWidth: function(width){
+ this.headerContentNode.firstChild.style.width = width + 'px';
+ if(this.viewWidth){
+ this.viewWidth = width + 'px';
+ }
+ },
+
+ getWidth: function(){
+ return this.viewWidth || (this.getColumnsWidth()+this.getScrollbarWidth()) +'px'; // String
+ },
+
+ getContentWidth: function(){
+ return Math.max(0, dojo._getContentBox(this.domNode).w - this.getScrollbarWidth()) + 'px'; // String
+ },
+
+ render: function(){
+ this.scrollboxNode.style.height = '';
+ this.renderHeader();
+ if(this._togglingColumn >= 0){
+ this.setColumnsWidth(this.getColumnsWidth() - this._togglingColumn);
+ this._togglingColumn = -1;
+ }
+ var cells = this.grid.layout.cells;
+ var getSibling = dojo.hitch(this, function(node, before){
+ !dojo._isBodyLtr() && (before = !before);
+ var inc = before?-1:1;
+ var idx = this.header.getCellNodeIndex(node) + inc;
+ var cell = cells[idx];
+ while(cell && cell.getHeaderNode() && cell.getHeaderNode().style.display == "none"){
+ idx += inc;
+ cell = cells[idx];
+ }
+ if(cell){
+ return cell.getHeaderNode();
+ }
+ return null;
+ });
+ if(this.grid.columnReordering && this.simpleStructure){
+ if(this.source){
+ this.source.destroy();
+ }
+
+ // Create the top and bottom markers
+ var bottomMarkerId = "dojoxGrid_bottomMarker";
+ var topMarkerId = "dojoxGrid_topMarker";
+ if(this.bottomMarker){
+ dojo.destroy(this.bottomMarker);
+ }
+ this.bottomMarker = dojo.byId(bottomMarkerId);
+ if(this.topMarker){
+ dojo.destroy(this.topMarker);
+ }
+ this.topMarker = dojo.byId(topMarkerId);
+ if (!this.bottomMarker) {
+ this.bottomMarker = dojo.create("div", {
+ "id": bottomMarkerId,
+ "class": "dojoxGridColPlaceBottom"
+ }, dojo.body());
+ this._hide(this.bottomMarker);
+
+
+ this.topMarker = dojo.create("div", {
+ "id": topMarkerId,
+ "class": "dojoxGridColPlaceTop"
+ }, dojo.body());
+ this._hide(this.topMarker);
+ }
+ this.arrowDim = dojo.contentBox(this.bottomMarker);
+
+ var headerHeight = dojo.contentBox(this.headerContentNode.firstChild.rows[0]).h;
+
+ this.source = new dojo.dnd.Source(this.headerContentNode.firstChild.rows[0], {
+ horizontal: true,
+ accept: [ "gridColumn_" + this.grid.id ],
+ viewIndex: this.index,
+ generateText: false,
+ onMouseDown: dojo.hitch(this, function(e){
+ this.header.decorateEvent(e);
+ if((this.header.overRightResizeArea(e) || this.header.overLeftResizeArea(e)) &&
+ this.header.canResize(e) && !this.header.moveable){
+ this.header.beginColumnResize(e);
+ }else{
+ if(this.grid.headerMenu){
+ this.grid.headerMenu.onCancel(true);
+ }
+ // IE reports a left click as 1, where everything else reports 0
+ if(e.button === (dojo.isIE ? 1 : 0)){
+ dojo.dnd.Source.prototype.onMouseDown.call(this.source, e);
+ }
+ }
+ }),
+ onMouseOver: dojo.hitch(this, function(e){
+ var src = this.source;
+ if(src._getChildByEvent(e)){
+ dojo.dnd.Source.prototype.onMouseOver.apply(src, arguments);
+ }
+ }),
+ _markTargetAnchor: dojo.hitch(this, function(before){
+ var src = this.source;
+ if(src.current == src.targetAnchor && src.before == before){ return; }
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ dojo.dnd.Source.prototype._markTargetAnchor.call(src, before);
+
+ var target = before ? src.targetAnchor : getSibling(src.targetAnchor, src.before);
+ var endAdd = 0;
+
+ if (!target) {
+ target = src.targetAnchor;
+ endAdd = dojo.contentBox(target).w + this.arrowDim.w/2 + 2;
+ }
+
+ // NOTE: this is for backwards compatibility with Dojo 1.3
+ var pos = (dojo.position||dojo._abs)(target, true);
+ var left = Math.floor(pos.x - this.arrowDim.w/2 + endAdd);
+
+ dojo.style(this.bottomMarker, "visibility", "visible");
+ dojo.style(this.topMarker, "visibility", "visible");
+ dojo.style(this.bottomMarker, {
+ "left": left + "px",
+ "top" : (headerHeight + pos.y) + "px"
+ });
+
+ dojo.style(this.topMarker, {
+ "left": left + "px",
+ "top" : (pos.y - this.arrowDim.h) + "px"
+ });
+
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._addItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ }),
+ _unmarkTargetAnchor: dojo.hitch(this, function(){
+ var src = this.source;
+ if(!src.targetAnchor){ return; }
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+ dojo.dnd.Source.prototype._unmarkTargetAnchor.call(src);
+ }),
+ destroy: dojo.hitch(this, function(){
+ dojo.disconnect(this._source_conn);
+ dojo.unsubscribe(this._source_sub);
+ dojo.dnd.Source.prototype.destroy.call(this.source);
+ if(this.bottomMarker){
+ dojo.destroy(this.bottomMarker);
+ delete this.bottomMarker;
+ }
+ if(this.topMarker){
+ dojo.destroy(this.topMarker);
+ delete this.topMarker;
+ }
+ }),
+ onDndCancel: dojo.hitch(this, function(){
+ dojo.dnd.Source.prototype.onDndCancel.call(this.source);
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+ })
+ });
+
+ this._source_conn = dojo.connect(this.source, "onDndDrop", this, "_onDndDrop");
+ this._source_sub = dojo.subscribe("/dnd/drop/before", this, "_onDndDropBefore");
+ this.source.startup();
+ }
+ },
+
+ _hide: function(node){
+ dojo.style(node, {
+ left: "-10000px",
+ top: "-10000px",
+ "visibility": "hidden"
+ });
+ },
+
+ _onDndDropBefore: function(source, nodes, copy){
+ if(dojo.dnd.manager().target !== this.source){
+ return;
+ }
+ this.source._targetNode = this.source.targetAnchor;
+ this.source._beforeTarget = this.source.before;
+ var views = this.grid.views.views;
+ var srcView = views[source.viewIndex];
+ var tgtView = views[this.index];
+ if(tgtView != srcView){
+ srcView.convertColPctToFixed();
+ tgtView.convertColPctToFixed();
+ }
+ },
+
+ _onDndDrop: function(source, nodes, copy){
+ if(dojo.dnd.manager().target !== this.source){
+ if(dojo.dnd.manager().source === this.source){
+ this._removingColumn = true;
+ }
+ return;
+ }
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+
+ var getIdx = function(n){
+ return n ? dojo.attr(n, "idx") : null;
+ };
+ var w = dojo.marginBox(nodes[0]).w;
+ if(source.viewIndex !== this.index){
+ var views = this.grid.views.views;
+ var srcView = views[source.viewIndex];
+ var tgtView = views[this.index];
+ if(srcView.viewWidth && srcView.viewWidth != "auto"){
+ srcView.setColumnsWidth(srcView.getColumnsWidth() - w);
+ }
+ if(tgtView.viewWidth && tgtView.viewWidth != "auto"){
+ tgtView.setColumnsWidth(tgtView.getColumnsWidth());
+ }
+ }
+ var stn = this.source._targetNode;
+ var stb = this.source._beforeTarget;
+ !dojo._isBodyLtr() && (stb = !stb);
+ var layout = this.grid.layout;
+ var idx = this.index;
+ delete this.source._targetNode;
+ delete this.source._beforeTarget;
+
+ layout.moveColumn(
+ source.viewIndex,
+ idx,
+ getIdx(nodes[0]),
+ getIdx(stn),
+ stb);
+ },
+
+ renderHeader: function(){
+ this.headerContentNode.innerHTML = this.header.generateHtml(this._getHeaderContent);
+ if(this.flexCells){
+ this.contentWidth = this.getContentWidth();
+ this.headerContentNode.firstChild.style.width = this.contentWidth;
+ }
+ dojox.grid.util.fire(this, "onAfterRow", [-1, this.structure.cells, this.headerContentNode]);
+ },
+
+ // note: not called in 'view' context
+ _getHeaderContent: function(inCell){
+ var n = inCell.name || inCell.grid.getCellName(inCell);
+ var ret = [ '<div class="dojoxGridSortNode' ];
+
+ if(inCell.index != inCell.grid.getSortIndex()){
+ ret.push('">');
+ }else{
+ ret = ret.concat([ ' ',
+ inCell.grid.sortInfo > 0 ? 'dojoxGridSortUp' : 'dojoxGridSortDown',
+ '"><div class="dojoxGridArrowButtonChar">',
+ inCell.grid.sortInfo > 0 ? '&#9650;' : '&#9660;',
+ '</div><div class="dojoxGridArrowButtonNode" role="presentation"></div>',
+ '<div class="dojoxGridColCaption">']);
+ }
+ ret = ret.concat([n, '</div></div>']);
+ return ret.join('');
+ },
+
+ resize: function(){
+ this.adaptHeight();
+ this.adaptWidth();
+ },
+
+ hasHScrollbar: function(reset){
+ var hadScroll = this._hasHScroll||false;
+ if(this._hasHScroll == undefined || reset){
+ if(this.noscroll){
+ this._hasHScroll = false;
+ }else{
+ var style = dojo.style(this.scrollboxNode, "overflow");
+ if(style == "hidden"){
+ this._hasHScroll = false;
+ }else if(style == "scroll"){
+ this._hasHScroll = true;
+ }else{
+ this._hasHScroll = (this.scrollboxNode.offsetWidth - this.getScrollbarWidth() < this.contentNode.offsetWidth );
+ }
+ }
+ }
+ if(hadScroll !== this._hasHScroll){
+ this.grid.update();
+ }
+ return this._hasHScroll; // Boolean
+ },
+
+ hasVScrollbar: function(reset){
+ var hadScroll = this._hasVScroll||false;
+ if(this._hasVScroll == undefined || reset){
+ if(this.noscroll){
+ this._hasVScroll = false;
+ }else{
+ var style = dojo.style(this.scrollboxNode, "overflow");
+ if(style == "hidden"){
+ this._hasVScroll = false;
+ }else if(style == "scroll"){
+ this._hasVScroll = true;
+ }else{
+ this._hasVScroll = (this.scrollboxNode.scrollHeight > this.scrollboxNode.clientHeight);
+ }
+ }
+ }
+ if(hadScroll !== this._hasVScroll){
+ this.grid.update();
+ }
+ return this._hasVScroll; // Boolean
+ },
+
+ convertColPctToFixed: function(){
+ // Fix any percentage widths to be pixel values
+ var hasPct = false;
+ this.grid.initialWidth = "";
+ var cellNodes = dojo.query("th", this.headerContentNode);
+ var fixedWidths = dojo.map(cellNodes, function(c, vIdx){
+ var w = c.style.width;
+ dojo.attr(c, "vIdx", vIdx);
+ if(w && w.slice(-1) == "%"){
+ hasPct = true;
+ }else if(w && w.slice(-2) == "px"){
+ return window.parseInt(w, 10);
+ }
+ return dojo.contentBox(c).w;
+ });
+ if(hasPct){
+ dojo.forEach(this.grid.layout.cells, function(cell, idx){
+ if(cell.view == this){
+ var cellNode = cell.view.getHeaderCellNode(cell.index);
+ if(cellNode && dojo.hasAttr(cellNode, "vIdx")){
+ var vIdx = window.parseInt(dojo.attr(cellNode, "vIdx"));
+ this.setColWidth(idx, fixedWidths[vIdx]);
+ dojo.removeAttr(cellNode, "vIdx");
+ }
+ }
+ }, this);
+ return true;
+ }
+ return false;
+ },
+
+ adaptHeight: function(minusScroll){
+ if(!this.grid._autoHeight){
+ var h = (this.domNode.style.height && parseInt(this.domNode.style.height.replace(/px/,''), 10)) || this.domNode.clientHeight;
+ var self = this;
+ var checkOtherViewScrollers = function(){
+ var v;
+ for(var i in self.grid.views.views){
+ v = self.grid.views.views[i];
+ if(v !== self && v.hasHScrollbar()){
+ return true;
+ }
+ }
+ return false;
+ };
+ if(minusScroll || (this.noscroll && checkOtherViewScrollers())){
+ h -= dojox.html.metrics.getScrollbar().h;
+ }
+ dojox.grid.util.setStyleHeightPx(this.scrollboxNode, h);
+ }
+ this.hasVScrollbar(true);
+ },
+
+ adaptWidth: function(){
+ if(this.flexCells){
+ // the view content width
+ this.contentWidth = this.getContentWidth();
+ this.headerContentNode.firstChild.style.width = this.contentWidth;
+ }
+ // FIXME: it should be easier to get w from this.scrollboxNode.clientWidth,
+ // but clientWidth seemingly does not include scrollbar width in some cases
+ var w = this.scrollboxNode.offsetWidth - this.getScrollbarWidth();
+ if(!this._removingColumn){
+ w = Math.max(w, this.getColumnsWidth()) + 'px';
+ }else{
+ w = Math.min(w, this.getColumnsWidth()) + 'px';
+ this._removingColumn = false;
+ }
+ var cn = this.contentNode;
+ cn.style.width = w;
+ this.hasHScrollbar(true);
+ },
+
+ setSize: function(w, h){
+ var ds = this.domNode.style;
+ var hs = this.headerNode.style;
+
+ if(w){
+ ds.width = w;
+ hs.width = w;
+ }
+ ds.height = (h >= 0 ? h + 'px' : '');
+ },
+
+ renderRow: function(inRowIndex){
+ var rowNode = this.createRowNode(inRowIndex);
+ this.buildRow(inRowIndex, rowNode);
+ this.grid.edit.restore(this, inRowIndex);
+ return rowNode;
+ },
+
+ createRowNode: function(inRowIndex){
+ var node = document.createElement("div");
+ node.className = this.classTag + 'Row';
+ if (this instanceof dojox.grid._RowSelector){
+ dojo.attr(node,"role","presentation");
+ }else{
+ dojo.attr(node,"role","row");
+ if (this.grid.selectionMode != "none") {
+ dojo.attr(node, "aria-selected", "false"); //rows can be selected so add aria-selected prop
+ }
+ }
+ node[dojox.grid.util.gridViewTag] = this.id;
+ node[dojox.grid.util.rowIndexTag] = inRowIndex;
+ this.rowNodes[inRowIndex] = node;
+ return node;
+ },
+
+ buildRow: function(inRowIndex, inRowNode){
+
+ this.buildRowContent(inRowIndex, inRowNode);
+
+ this.styleRow(inRowIndex, inRowNode);
+
+
+ },
+
+ buildRowContent: function(inRowIndex, inRowNode){
+ inRowNode.innerHTML = this.content.generateHtml(inRowIndex, inRowIndex);
+ if(this.flexCells && this.contentWidth){
+ // FIXME: accessing firstChild here breaks encapsulation
+ inRowNode.firstChild.style.width = this.contentWidth;
+ }
+ dojox.grid.util.fire(this, "onAfterRow", [inRowIndex, this.structure.cells, inRowNode]);
+ },
+
+ rowRemoved:function(inRowIndex){
+ if(inRowIndex >= 0){
+ this._cleanupRowWidgets(this.getRowNode(inRowIndex));
+ }
+ this.grid.edit.save(this, inRowIndex);
+ delete this.rowNodes[inRowIndex];
+ },
+
+ getRowNode: function(inRowIndex){
+ return this.rowNodes[inRowIndex];
+ },
+
+ getCellNode: function(inRowIndex, inCellIndex){
+ var row = this.getRowNode(inRowIndex);
+ if(row){
+ return this.content.getCellNode(row, inCellIndex);
+ }
+ },
+
+ getHeaderCellNode: function(inCellIndex){
+ if(this.headerContentNode){
+ return this.header.getCellNode(this.headerContentNode, inCellIndex);
+ }
+ },
+
+ // styling
+ styleRow: function(inRowIndex, inRowNode){
+ inRowNode._style = getStyleText(inRowNode);
+ this.styleRowNode(inRowIndex, inRowNode);
+ },
+
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ this.doStyleRowNode(inRowIndex, inRowNode);
+ }
+ },
+
+ doStyleRowNode: function(inRowIndex, inRowNode){
+ this.grid.styleRowNode(inRowIndex, inRowNode);
+ },
+
+ // updating
+ updateRow: function(inRowIndex){
+ var rowNode = this.getRowNode(inRowIndex);
+ if(rowNode){
+ rowNode.style.height = '';
+ this.buildRow(inRowIndex, rowNode);
+ }
+ return rowNode;
+ },
+
+ updateRowStyles: function(inRowIndex){
+ this.styleRowNode(inRowIndex, this.getRowNode(inRowIndex));
+ },
+
+ // scrolling
+ lastTop: 0,
+ firstScroll:0,
+
+ doscroll: function(inEvent){
+ //var s = dojo.marginBox(this.headerContentNode.firstChild);
+ var isLtr = dojo._isBodyLtr();
+ if(this.firstScroll < 2){
+ if((!isLtr && this.firstScroll == 1) || (isLtr && this.firstScroll === 0)){
+ var s = dojo.marginBox(this.headerNodeContainer);
+ if(dojo.isIE){
+ this.headerNodeContainer.style.width = s.w + this.getScrollbarWidth() + 'px';
+ }else if(dojo.isMoz){
+ //TODO currently only for FF, not sure for safari and opera
+ this.headerNodeContainer.style.width = s.w - this.getScrollbarWidth() + 'px';
+ //this.headerNodeContainer.style.width = s.w + 'px';
+ //set scroll to right in FF
+ this.scrollboxNode.scrollLeft = isLtr ?
+ this.scrollboxNode.clientWidth - this.scrollboxNode.scrollWidth :
+ this.scrollboxNode.scrollWidth - this.scrollboxNode.clientWidth;
+ }
+ }
+ this.firstScroll++;
+ }
+ this.headerNode.scrollLeft = this.scrollboxNode.scrollLeft;
+ // 'lastTop' is a semaphore to prevent feedback-loop with setScrollTop below
+ var top = this.scrollboxNode.scrollTop;
+ if(top !== this.lastTop){
+ this.grid.scrollTo(top);
+ }
+ },
+
+ setScrollTop: function(inTop){
+ // 'lastTop' is a semaphore to prevent feedback-loop with doScroll above
+ this.lastTop = inTop;
+ this.scrollboxNode.scrollTop = inTop;
+ return this.scrollboxNode.scrollTop;
+ },
+
+ // event handlers (direct from DOM)
+ doContentEvent: function(e){
+ if(this.content.decorateEvent(e)){
+ this.grid.onContentEvent(e);
+ }
+ },
+
+ doHeaderEvent: function(e){
+ if(this.header.decorateEvent(e)){
+ this.grid.onHeaderEvent(e);
+ }
+ },
+
+ // event dispatch(from Grid)
+ dispatchContentEvent: function(e){
+ return this.content.dispatchEvent(e);
+ },
+
+ dispatchHeaderEvent: function(e){
+ return this.header.dispatchEvent(e);
+ },
+
+ // column resizing
+ setColWidth: function(inIndex, inWidth){
+ this.grid.setCellWidth(inIndex, inWidth + 'px');
+ },
+
+ update: function(){
+ if(!this.domNode){
+ return;
+ }
+ this.content.update();
+ this.grid.update();
+ //get scroll after update or scroll left setting goes wrong on IE.
+ //See trac: #8040
+ var left = this.scrollboxNode.scrollLeft;
+ this.scrollboxNode.scrollLeft = left;
+ this.headerNode.scrollLeft = left;
+ }
+ });
+
+ dojo.declare("dojox.grid._GridAvatar", dojo.dnd.Avatar, {
+ construct: function(){
+ var dd = dojo.doc;
+
+ var a = dd.createElement("table");
+ a.cellPadding = a.cellSpacing = "0";
+ a.className = "dojoxGridDndAvatar";
+ a.style.position = "absolute";
+ a.style.zIndex = 1999;
+ a.style.margin = "0px"; // to avoid dojo.marginBox() problems with table's margins
+ var b = dd.createElement("tbody");
+ var tr = dd.createElement("tr");
+ var td = dd.createElement("td");
+ var img = dd.createElement("td");
+ tr.className = "dojoxGridDndAvatarItem";
+ img.className = "dojoxGridDndAvatarItemImage";
+ img.style.width = "16px";
+ var source = this.manager.source, node;
+ if(source.creator){
+ // create an avatar representation of the node
+ node = source._normalizedCreator(source.getItem(this.manager.nodes[0].id).data, "avatar").node;
+ }else{
+ // or just clone the node and hope it works
+ node = this.manager.nodes[0].cloneNode(true);
+ var table, tbody;
+ if(node.tagName.toLowerCase() == "tr"){
+ // insert extra table nodes
+ table = dd.createElement("table");
+ tbody = dd.createElement("tbody");
+ tbody.appendChild(node);
+ table.appendChild(tbody);
+ node = table;
+ }else if(node.tagName.toLowerCase() == "th"){
+ // insert extra table nodes
+ table = dd.createElement("table");
+ tbody = dd.createElement("tbody");
+ var r = dd.createElement("tr");
+ table.cellPadding = table.cellSpacing = "0";
+ r.appendChild(node);
+ tbody.appendChild(r);
+ table.appendChild(tbody);
+ node = table;
+ }
+ }
+ node.id = "";
+ td.appendChild(node);
+ tr.appendChild(img);
+ tr.appendChild(td);
+ dojo.style(tr, "opacity", 0.9);
+ b.appendChild(tr);
+
+ a.appendChild(b);
+ this.node = a;
+
+ var m = dojo.dnd.manager();
+ this.oldOffsetY = m.OFFSET_Y;
+ m.OFFSET_Y = 1;
+ },
+ destroy: function(){
+ dojo.dnd.manager().OFFSET_Y = this.oldOffsetY;
+ this.inherited(arguments);
+ }
+ });
+
+ var oldMakeAvatar = dojo.dnd.manager().makeAvatar;
+ dojo.dnd.manager().makeAvatar = function(){
+ var src = this.source;
+ if(src.viewIndex !== undefined && !dojo.hasClass(dojo.body(),"dijit_a11y")){
+ return new dojox.grid._GridAvatar(this);
+ }
+ return oldMakeAvatar.call(dojo.dnd.manager());
+ };
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/_View.xd.js b/js/dojo-1.6/dojox/grid/_View.xd.js
new file mode 100644
index 0000000..4c429f7
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_View.xd.js
@@ -0,0 +1,855 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid._View"],
+["require", "dijit._Widget"],
+["require", "dijit._Templated"],
+["require", "dojox.grid._Builder"],
+["require", "dojox.html.metrics"],
+["require", "dojox.grid.util"],
+["require", "dojo.dnd.Source"],
+["require", "dojo.dnd.Manager"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid._View"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._View"] = true;
+dojo.provide("dojox.grid._View");
+
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojox.grid._Builder");
+dojo.require("dojox.html.metrics");
+dojo.require("dojox.grid.util");
+
+dojo.require("dojo.dnd.Source");
+dojo.require("dojo.dnd.Manager");
+
+(function(){
+ // a private function
+ var getStyleText = function(inNode, inStyleText){
+ return inNode.style.cssText == undefined ? inNode.getAttribute("style") : inNode.style.cssText;
+ };
+
+ // some public functions
+ dojo.declare('dojox.grid._View', [dijit._Widget, dijit._Templated], {
+ // summary:
+ // A collection of grid columns. A grid is comprised of a set of views that stack horizontally.
+ // Grid creates views automatically based on grid's layout structure.
+ // Users should typically not need to access individual views directly.
+ //
+ // defaultWidth: String
+ // Default width of the view
+ defaultWidth: "18em",
+
+ // viewWidth: String
+ // Width for the view, in valid css unit
+ viewWidth: "",
+
+ templateString:"<div class=\"dojoxGridView\" role=\"presentation\">\r\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" role=\"presentation\">\r\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" role=\"presentation\">\r\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" role=\"row\"></div>\r\n\t\t</div>\r\n\t</div>\r\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" role=\"presentation\" />\r\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" role=\"presentation\" />\r\n\t<div class=\"dojoxGridScrollbox\" dojoAttachPoint=\"scrollboxNode\" role=\"presentation\">\r\n\t\t<div class=\"dojoxGridContent\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\" role=\"presentation\"></div>\r\n\t</div>\r\n</div>\r\n",
+
+ themeable: false,
+ classTag: 'dojoxGrid',
+ marginBottom: 0,
+ rowPad: 2,
+
+ // _togglingColumn: int
+ // Width of the column being toggled (-1 for none)
+ _togglingColumn: -1,
+
+ // _headerBuilderClass: Object
+ // The class to use for our header builder
+ _headerBuilderClass: dojox.grid._HeaderBuilder,
+
+ // _contentBuilderClass: Object
+ // The class to use for our content builder
+ _contentBuilderClass: dojox.grid._ContentBuilder,
+
+ postMixInProperties: function(){
+ this.rowNodes = {};
+ },
+
+ postCreate: function(){
+ this.connect(this.scrollboxNode,"onscroll","doscroll");
+ dojox.grid.util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]);
+ dojox.grid.util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]);
+ this.content = new this._contentBuilderClass(this);
+ this.header = new this._headerBuilderClass(this);
+ //BiDi: in RTL case, style width='9000em' causes scrolling problem in head node
+ if(!dojo._isBodyLtr()){
+ this.headerNodeContainer.style.width = "";
+ }
+ },
+
+ destroy: function(){
+ dojo.destroy(this.headerNode);
+ delete this.headerNode;
+ for(var i in this.rowNodes){
+ dojo.destroy(this.rowNodes[i]);
+ }
+ this.rowNodes = {};
+ if(this.source){
+ this.source.destroy();
+ }
+ this.inherited(arguments);
+ },
+
+ // focus
+ focus: function(){
+ if(dojo.isIE || dojo.isWebKit || dojo.isOpera){
+ this.hiddenFocusNode.focus();
+ }else{
+ this.scrollboxNode.focus();
+ }
+ },
+
+ setStructure: function(inStructure){
+ var vs = (this.structure = inStructure);
+ // FIXME: similar logic is duplicated in layout
+ if(vs.width && !isNaN(vs.width)){
+ this.viewWidth = vs.width + 'em';
+ }else{
+ this.viewWidth = vs.width || (vs.noscroll ? 'auto' : this.viewWidth); //|| this.defaultWidth;
+ }
+ this._onBeforeRow = vs.onBeforeRow||function(){};
+ this._onAfterRow = vs.onAfterRow||function(){};
+ this.noscroll = vs.noscroll;
+ if(this.noscroll){
+ this.scrollboxNode.style.overflow = "hidden";
+ }
+ this.simpleStructure = Boolean(vs.cells.length == 1);
+ // bookkeeping
+ this.testFlexCells();
+ // accomodate new structure
+ this.updateStructure();
+ },
+
+ _cleanupRowWidgets: function(inRowNode){
+ // Summary:
+ // Cleans up the widgets for the given row node so that
+ // we can reattach them if needed
+ if(inRowNode){
+ dojo.forEach(dojo.query("[widgetId]", inRowNode).map(dijit.byNode), function(w){
+ if(w._destroyOnRemove){
+ w.destroy();
+ delete w;
+ }else if(w.domNode && w.domNode.parentNode){
+ w.domNode.parentNode.removeChild(w.domNode);
+ }
+ });
+ }
+ },
+
+ onBeforeRow: function(inRowIndex, cells){
+ this._onBeforeRow(inRowIndex, cells);
+ if(inRowIndex >= 0){
+ this._cleanupRowWidgets(this.getRowNode(inRowIndex));
+ }
+ },
+
+ onAfterRow: function(inRowIndex, cells, inRowNode){
+ this._onAfterRow(inRowIndex, cells, inRowNode);
+ var g = this.grid;
+ dojo.forEach(dojo.query(".dojoxGridStubNode", inRowNode), function(n){
+ if(n && n.parentNode){
+ var lw = n.getAttribute("linkWidget");
+ var cellIdx = window.parseInt(dojo.attr(n, "cellIdx"), 10);
+ var cellDef = g.getCell(cellIdx);
+ var w = dijit.byId(lw);
+ if(w){
+ n.parentNode.replaceChild(w.domNode, n);
+ if(!w._started){
+ w.startup();
+ }
+ }else{
+ n.innerHTML = "";
+ }
+ }
+ }, this);
+ },
+
+ testFlexCells: function(){
+ // FIXME: cheater, this function does double duty as initializer and tester
+ this.flexCells = false;
+ for(var j=0, row; (row=this.structure.cells[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ cell.view = this;
+ this.flexCells = this.flexCells || cell.isFlex();
+ }
+ }
+ return this.flexCells;
+ },
+
+ updateStructure: function(){
+ // header builder needs to update table map
+ this.header.update();
+ // content builder needs to update markup cache
+ this.content.update();
+ },
+
+ getScrollbarWidth: function(){
+ var hasScrollSpace = this.hasVScrollbar();
+ var overflow = dojo.style(this.scrollboxNode, "overflow");
+ if(this.noscroll || !overflow || overflow == "hidden"){
+ hasScrollSpace = false;
+ }else if(overflow == "scroll"){
+ hasScrollSpace = true;
+ }
+ return (hasScrollSpace ? dojox.html.metrics.getScrollbar().w : 0); // Integer
+ },
+
+ getColumnsWidth: function(){
+ var h = this.headerContentNode;
+ return h && h.firstChild ? h.firstChild.offsetWidth : 0; // Integer
+ },
+
+ setColumnsWidth: function(width){
+ this.headerContentNode.firstChild.style.width = width + 'px';
+ if(this.viewWidth){
+ this.viewWidth = width + 'px';
+ }
+ },
+
+ getWidth: function(){
+ return this.viewWidth || (this.getColumnsWidth()+this.getScrollbarWidth()) +'px'; // String
+ },
+
+ getContentWidth: function(){
+ return Math.max(0, dojo._getContentBox(this.domNode).w - this.getScrollbarWidth()) + 'px'; // String
+ },
+
+ render: function(){
+ this.scrollboxNode.style.height = '';
+ this.renderHeader();
+ if(this._togglingColumn >= 0){
+ this.setColumnsWidth(this.getColumnsWidth() - this._togglingColumn);
+ this._togglingColumn = -1;
+ }
+ var cells = this.grid.layout.cells;
+ var getSibling = dojo.hitch(this, function(node, before){
+ !dojo._isBodyLtr() && (before = !before);
+ var inc = before?-1:1;
+ var idx = this.header.getCellNodeIndex(node) + inc;
+ var cell = cells[idx];
+ while(cell && cell.getHeaderNode() && cell.getHeaderNode().style.display == "none"){
+ idx += inc;
+ cell = cells[idx];
+ }
+ if(cell){
+ return cell.getHeaderNode();
+ }
+ return null;
+ });
+ if(this.grid.columnReordering && this.simpleStructure){
+ if(this.source){
+ this.source.destroy();
+ }
+
+ // Create the top and bottom markers
+ var bottomMarkerId = "dojoxGrid_bottomMarker";
+ var topMarkerId = "dojoxGrid_topMarker";
+ if(this.bottomMarker){
+ dojo.destroy(this.bottomMarker);
+ }
+ this.bottomMarker = dojo.byId(bottomMarkerId);
+ if(this.topMarker){
+ dojo.destroy(this.topMarker);
+ }
+ this.topMarker = dojo.byId(topMarkerId);
+ if (!this.bottomMarker) {
+ this.bottomMarker = dojo.create("div", {
+ "id": bottomMarkerId,
+ "class": "dojoxGridColPlaceBottom"
+ }, dojo.body());
+ this._hide(this.bottomMarker);
+
+
+ this.topMarker = dojo.create("div", {
+ "id": topMarkerId,
+ "class": "dojoxGridColPlaceTop"
+ }, dojo.body());
+ this._hide(this.topMarker);
+ }
+ this.arrowDim = dojo.contentBox(this.bottomMarker);
+
+ var headerHeight = dojo.contentBox(this.headerContentNode.firstChild.rows[0]).h;
+
+ this.source = new dojo.dnd.Source(this.headerContentNode.firstChild.rows[0], {
+ horizontal: true,
+ accept: [ "gridColumn_" + this.grid.id ],
+ viewIndex: this.index,
+ generateText: false,
+ onMouseDown: dojo.hitch(this, function(e){
+ this.header.decorateEvent(e);
+ if((this.header.overRightResizeArea(e) || this.header.overLeftResizeArea(e)) &&
+ this.header.canResize(e) && !this.header.moveable){
+ this.header.beginColumnResize(e);
+ }else{
+ if(this.grid.headerMenu){
+ this.grid.headerMenu.onCancel(true);
+ }
+ // IE reports a left click as 1, where everything else reports 0
+ if(e.button === (dojo.isIE ? 1 : 0)){
+ dojo.dnd.Source.prototype.onMouseDown.call(this.source, e);
+ }
+ }
+ }),
+ onMouseOver: dojo.hitch(this, function(e){
+ var src = this.source;
+ if(src._getChildByEvent(e)){
+ dojo.dnd.Source.prototype.onMouseOver.apply(src, arguments);
+ }
+ }),
+ _markTargetAnchor: dojo.hitch(this, function(before){
+ var src = this.source;
+ if(src.current == src.targetAnchor && src.before == before){ return; }
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ dojo.dnd.Source.prototype._markTargetAnchor.call(src, before);
+
+ var target = before ? src.targetAnchor : getSibling(src.targetAnchor, src.before);
+ var endAdd = 0;
+
+ if (!target) {
+ target = src.targetAnchor;
+ endAdd = dojo.contentBox(target).w + this.arrowDim.w/2 + 2;
+ }
+
+ // NOTE: this is for backwards compatibility with Dojo 1.3
+ var pos = (dojo.position||dojo._abs)(target, true);
+ var left = Math.floor(pos.x - this.arrowDim.w/2 + endAdd);
+
+ dojo.style(this.bottomMarker, "visibility", "visible");
+ dojo.style(this.topMarker, "visibility", "visible");
+ dojo.style(this.bottomMarker, {
+ "left": left + "px",
+ "top" : (headerHeight + pos.y) + "px"
+ });
+
+ dojo.style(this.topMarker, {
+ "left": left + "px",
+ "top" : (pos.y - this.arrowDim.h) + "px"
+ });
+
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._addItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ }),
+ _unmarkTargetAnchor: dojo.hitch(this, function(){
+ var src = this.source;
+ if(!src.targetAnchor){ return; }
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+ dojo.dnd.Source.prototype._unmarkTargetAnchor.call(src);
+ }),
+ destroy: dojo.hitch(this, function(){
+ dojo.disconnect(this._source_conn);
+ dojo.unsubscribe(this._source_sub);
+ dojo.dnd.Source.prototype.destroy.call(this.source);
+ if(this.bottomMarker){
+ dojo.destroy(this.bottomMarker);
+ delete this.bottomMarker;
+ }
+ if(this.topMarker){
+ dojo.destroy(this.topMarker);
+ delete this.topMarker;
+ }
+ }),
+ onDndCancel: dojo.hitch(this, function(){
+ dojo.dnd.Source.prototype.onDndCancel.call(this.source);
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+ })
+ });
+
+ this._source_conn = dojo.connect(this.source, "onDndDrop", this, "_onDndDrop");
+ this._source_sub = dojo.subscribe("/dnd/drop/before", this, "_onDndDropBefore");
+ this.source.startup();
+ }
+ },
+
+ _hide: function(node){
+ dojo.style(node, {
+ left: "-10000px",
+ top: "-10000px",
+ "visibility": "hidden"
+ });
+ },
+
+ _onDndDropBefore: function(source, nodes, copy){
+ if(dojo.dnd.manager().target !== this.source){
+ return;
+ }
+ this.source._targetNode = this.source.targetAnchor;
+ this.source._beforeTarget = this.source.before;
+ var views = this.grid.views.views;
+ var srcView = views[source.viewIndex];
+ var tgtView = views[this.index];
+ if(tgtView != srcView){
+ srcView.convertColPctToFixed();
+ tgtView.convertColPctToFixed();
+ }
+ },
+
+ _onDndDrop: function(source, nodes, copy){
+ if(dojo.dnd.manager().target !== this.source){
+ if(dojo.dnd.manager().source === this.source){
+ this._removingColumn = true;
+ }
+ return;
+ }
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+
+ var getIdx = function(n){
+ return n ? dojo.attr(n, "idx") : null;
+ };
+ var w = dojo.marginBox(nodes[0]).w;
+ if(source.viewIndex !== this.index){
+ var views = this.grid.views.views;
+ var srcView = views[source.viewIndex];
+ var tgtView = views[this.index];
+ if(srcView.viewWidth && srcView.viewWidth != "auto"){
+ srcView.setColumnsWidth(srcView.getColumnsWidth() - w);
+ }
+ if(tgtView.viewWidth && tgtView.viewWidth != "auto"){
+ tgtView.setColumnsWidth(tgtView.getColumnsWidth());
+ }
+ }
+ var stn = this.source._targetNode;
+ var stb = this.source._beforeTarget;
+ !dojo._isBodyLtr() && (stb = !stb);
+ var layout = this.grid.layout;
+ var idx = this.index;
+ delete this.source._targetNode;
+ delete this.source._beforeTarget;
+
+ layout.moveColumn(
+ source.viewIndex,
+ idx,
+ getIdx(nodes[0]),
+ getIdx(stn),
+ stb);
+ },
+
+ renderHeader: function(){
+ this.headerContentNode.innerHTML = this.header.generateHtml(this._getHeaderContent);
+ if(this.flexCells){
+ this.contentWidth = this.getContentWidth();
+ this.headerContentNode.firstChild.style.width = this.contentWidth;
+ }
+ dojox.grid.util.fire(this, "onAfterRow", [-1, this.structure.cells, this.headerContentNode]);
+ },
+
+ // note: not called in 'view' context
+ _getHeaderContent: function(inCell){
+ var n = inCell.name || inCell.grid.getCellName(inCell);
+ var ret = [ '<div class="dojoxGridSortNode' ];
+
+ if(inCell.index != inCell.grid.getSortIndex()){
+ ret.push('">');
+ }else{
+ ret = ret.concat([ ' ',
+ inCell.grid.sortInfo > 0 ? 'dojoxGridSortUp' : 'dojoxGridSortDown',
+ '"><div class="dojoxGridArrowButtonChar">',
+ inCell.grid.sortInfo > 0 ? '&#9650;' : '&#9660;',
+ '</div><div class="dojoxGridArrowButtonNode" role="presentation"></div>',
+ '<div class="dojoxGridColCaption">']);
+ }
+ ret = ret.concat([n, '</div></div>']);
+ return ret.join('');
+ },
+
+ resize: function(){
+ this.adaptHeight();
+ this.adaptWidth();
+ },
+
+ hasHScrollbar: function(reset){
+ var hadScroll = this._hasHScroll||false;
+ if(this._hasHScroll == undefined || reset){
+ if(this.noscroll){
+ this._hasHScroll = false;
+ }else{
+ var style = dojo.style(this.scrollboxNode, "overflow");
+ if(style == "hidden"){
+ this._hasHScroll = false;
+ }else if(style == "scroll"){
+ this._hasHScroll = true;
+ }else{
+ this._hasHScroll = (this.scrollboxNode.offsetWidth - this.getScrollbarWidth() < this.contentNode.offsetWidth );
+ }
+ }
+ }
+ if(hadScroll !== this._hasHScroll){
+ this.grid.update();
+ }
+ return this._hasHScroll; // Boolean
+ },
+
+ hasVScrollbar: function(reset){
+ var hadScroll = this._hasVScroll||false;
+ if(this._hasVScroll == undefined || reset){
+ if(this.noscroll){
+ this._hasVScroll = false;
+ }else{
+ var style = dojo.style(this.scrollboxNode, "overflow");
+ if(style == "hidden"){
+ this._hasVScroll = false;
+ }else if(style == "scroll"){
+ this._hasVScroll = true;
+ }else{
+ this._hasVScroll = (this.scrollboxNode.scrollHeight > this.scrollboxNode.clientHeight);
+ }
+ }
+ }
+ if(hadScroll !== this._hasVScroll){
+ this.grid.update();
+ }
+ return this._hasVScroll; // Boolean
+ },
+
+ convertColPctToFixed: function(){
+ // Fix any percentage widths to be pixel values
+ var hasPct = false;
+ this.grid.initialWidth = "";
+ var cellNodes = dojo.query("th", this.headerContentNode);
+ var fixedWidths = dojo.map(cellNodes, function(c, vIdx){
+ var w = c.style.width;
+ dojo.attr(c, "vIdx", vIdx);
+ if(w && w.slice(-1) == "%"){
+ hasPct = true;
+ }else if(w && w.slice(-2) == "px"){
+ return window.parseInt(w, 10);
+ }
+ return dojo.contentBox(c).w;
+ });
+ if(hasPct){
+ dojo.forEach(this.grid.layout.cells, function(cell, idx){
+ if(cell.view == this){
+ var cellNode = cell.view.getHeaderCellNode(cell.index);
+ if(cellNode && dojo.hasAttr(cellNode, "vIdx")){
+ var vIdx = window.parseInt(dojo.attr(cellNode, "vIdx"));
+ this.setColWidth(idx, fixedWidths[vIdx]);
+ dojo.removeAttr(cellNode, "vIdx");
+ }
+ }
+ }, this);
+ return true;
+ }
+ return false;
+ },
+
+ adaptHeight: function(minusScroll){
+ if(!this.grid._autoHeight){
+ var h = (this.domNode.style.height && parseInt(this.domNode.style.height.replace(/px/,''), 10)) || this.domNode.clientHeight;
+ var self = this;
+ var checkOtherViewScrollers = function(){
+ var v;
+ for(var i in self.grid.views.views){
+ v = self.grid.views.views[i];
+ if(v !== self && v.hasHScrollbar()){
+ return true;
+ }
+ }
+ return false;
+ };
+ if(minusScroll || (this.noscroll && checkOtherViewScrollers())){
+ h -= dojox.html.metrics.getScrollbar().h;
+ }
+ dojox.grid.util.setStyleHeightPx(this.scrollboxNode, h);
+ }
+ this.hasVScrollbar(true);
+ },
+
+ adaptWidth: function(){
+ if(this.flexCells){
+ // the view content width
+ this.contentWidth = this.getContentWidth();
+ this.headerContentNode.firstChild.style.width = this.contentWidth;
+ }
+ // FIXME: it should be easier to get w from this.scrollboxNode.clientWidth,
+ // but clientWidth seemingly does not include scrollbar width in some cases
+ var w = this.scrollboxNode.offsetWidth - this.getScrollbarWidth();
+ if(!this._removingColumn){
+ w = Math.max(w, this.getColumnsWidth()) + 'px';
+ }else{
+ w = Math.min(w, this.getColumnsWidth()) + 'px';
+ this._removingColumn = false;
+ }
+ var cn = this.contentNode;
+ cn.style.width = w;
+ this.hasHScrollbar(true);
+ },
+
+ setSize: function(w, h){
+ var ds = this.domNode.style;
+ var hs = this.headerNode.style;
+
+ if(w){
+ ds.width = w;
+ hs.width = w;
+ }
+ ds.height = (h >= 0 ? h + 'px' : '');
+ },
+
+ renderRow: function(inRowIndex){
+ var rowNode = this.createRowNode(inRowIndex);
+ this.buildRow(inRowIndex, rowNode);
+ this.grid.edit.restore(this, inRowIndex);
+ return rowNode;
+ },
+
+ createRowNode: function(inRowIndex){
+ var node = document.createElement("div");
+ node.className = this.classTag + 'Row';
+ if (this instanceof dojox.grid._RowSelector){
+ dojo.attr(node,"role","presentation");
+ }else{
+ dojo.attr(node,"role","row");
+ if (this.grid.selectionMode != "none") {
+ dojo.attr(node, "aria-selected", "false"); //rows can be selected so add aria-selected prop
+ }
+ }
+ node[dojox.grid.util.gridViewTag] = this.id;
+ node[dojox.grid.util.rowIndexTag] = inRowIndex;
+ this.rowNodes[inRowIndex] = node;
+ return node;
+ },
+
+ buildRow: function(inRowIndex, inRowNode){
+
+ this.buildRowContent(inRowIndex, inRowNode);
+
+ this.styleRow(inRowIndex, inRowNode);
+
+
+ },
+
+ buildRowContent: function(inRowIndex, inRowNode){
+ inRowNode.innerHTML = this.content.generateHtml(inRowIndex, inRowIndex);
+ if(this.flexCells && this.contentWidth){
+ // FIXME: accessing firstChild here breaks encapsulation
+ inRowNode.firstChild.style.width = this.contentWidth;
+ }
+ dojox.grid.util.fire(this, "onAfterRow", [inRowIndex, this.structure.cells, inRowNode]);
+ },
+
+ rowRemoved:function(inRowIndex){
+ if(inRowIndex >= 0){
+ this._cleanupRowWidgets(this.getRowNode(inRowIndex));
+ }
+ this.grid.edit.save(this, inRowIndex);
+ delete this.rowNodes[inRowIndex];
+ },
+
+ getRowNode: function(inRowIndex){
+ return this.rowNodes[inRowIndex];
+ },
+
+ getCellNode: function(inRowIndex, inCellIndex){
+ var row = this.getRowNode(inRowIndex);
+ if(row){
+ return this.content.getCellNode(row, inCellIndex);
+ }
+ },
+
+ getHeaderCellNode: function(inCellIndex){
+ if(this.headerContentNode){
+ return this.header.getCellNode(this.headerContentNode, inCellIndex);
+ }
+ },
+
+ // styling
+ styleRow: function(inRowIndex, inRowNode){
+ inRowNode._style = getStyleText(inRowNode);
+ this.styleRowNode(inRowIndex, inRowNode);
+ },
+
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ this.doStyleRowNode(inRowIndex, inRowNode);
+ }
+ },
+
+ doStyleRowNode: function(inRowIndex, inRowNode){
+ this.grid.styleRowNode(inRowIndex, inRowNode);
+ },
+
+ // updating
+ updateRow: function(inRowIndex){
+ var rowNode = this.getRowNode(inRowIndex);
+ if(rowNode){
+ rowNode.style.height = '';
+ this.buildRow(inRowIndex, rowNode);
+ }
+ return rowNode;
+ },
+
+ updateRowStyles: function(inRowIndex){
+ this.styleRowNode(inRowIndex, this.getRowNode(inRowIndex));
+ },
+
+ // scrolling
+ lastTop: 0,
+ firstScroll:0,
+
+ doscroll: function(inEvent){
+ //var s = dojo.marginBox(this.headerContentNode.firstChild);
+ var isLtr = dojo._isBodyLtr();
+ if(this.firstScroll < 2){
+ if((!isLtr && this.firstScroll == 1) || (isLtr && this.firstScroll === 0)){
+ var s = dojo.marginBox(this.headerNodeContainer);
+ if(dojo.isIE){
+ this.headerNodeContainer.style.width = s.w + this.getScrollbarWidth() + 'px';
+ }else if(dojo.isMoz){
+ //TODO currently only for FF, not sure for safari and opera
+ this.headerNodeContainer.style.width = s.w - this.getScrollbarWidth() + 'px';
+ //this.headerNodeContainer.style.width = s.w + 'px';
+ //set scroll to right in FF
+ this.scrollboxNode.scrollLeft = isLtr ?
+ this.scrollboxNode.clientWidth - this.scrollboxNode.scrollWidth :
+ this.scrollboxNode.scrollWidth - this.scrollboxNode.clientWidth;
+ }
+ }
+ this.firstScroll++;
+ }
+ this.headerNode.scrollLeft = this.scrollboxNode.scrollLeft;
+ // 'lastTop' is a semaphore to prevent feedback-loop with setScrollTop below
+ var top = this.scrollboxNode.scrollTop;
+ if(top !== this.lastTop){
+ this.grid.scrollTo(top);
+ }
+ },
+
+ setScrollTop: function(inTop){
+ // 'lastTop' is a semaphore to prevent feedback-loop with doScroll above
+ this.lastTop = inTop;
+ this.scrollboxNode.scrollTop = inTop;
+ return this.scrollboxNode.scrollTop;
+ },
+
+ // event handlers (direct from DOM)
+ doContentEvent: function(e){
+ if(this.content.decorateEvent(e)){
+ this.grid.onContentEvent(e);
+ }
+ },
+
+ doHeaderEvent: function(e){
+ if(this.header.decorateEvent(e)){
+ this.grid.onHeaderEvent(e);
+ }
+ },
+
+ // event dispatch(from Grid)
+ dispatchContentEvent: function(e){
+ return this.content.dispatchEvent(e);
+ },
+
+ dispatchHeaderEvent: function(e){
+ return this.header.dispatchEvent(e);
+ },
+
+ // column resizing
+ setColWidth: function(inIndex, inWidth){
+ this.grid.setCellWidth(inIndex, inWidth + 'px');
+ },
+
+ update: function(){
+ if(!this.domNode){
+ return;
+ }
+ this.content.update();
+ this.grid.update();
+ //get scroll after update or scroll left setting goes wrong on IE.
+ //See trac: #8040
+ var left = this.scrollboxNode.scrollLeft;
+ this.scrollboxNode.scrollLeft = left;
+ this.headerNode.scrollLeft = left;
+ }
+ });
+
+ dojo.declare("dojox.grid._GridAvatar", dojo.dnd.Avatar, {
+ construct: function(){
+ var dd = dojo.doc;
+
+ var a = dd.createElement("table");
+ a.cellPadding = a.cellSpacing = "0";
+ a.className = "dojoxGridDndAvatar";
+ a.style.position = "absolute";
+ a.style.zIndex = 1999;
+ a.style.margin = "0px"; // to avoid dojo.marginBox() problems with table's margins
+ var b = dd.createElement("tbody");
+ var tr = dd.createElement("tr");
+ var td = dd.createElement("td");
+ var img = dd.createElement("td");
+ tr.className = "dojoxGridDndAvatarItem";
+ img.className = "dojoxGridDndAvatarItemImage";
+ img.style.width = "16px";
+ var source = this.manager.source, node;
+ if(source.creator){
+ // create an avatar representation of the node
+ node = source._normalizedCreator(source.getItem(this.manager.nodes[0].id).data, "avatar").node;
+ }else{
+ // or just clone the node and hope it works
+ node = this.manager.nodes[0].cloneNode(true);
+ var table, tbody;
+ if(node.tagName.toLowerCase() == "tr"){
+ // insert extra table nodes
+ table = dd.createElement("table");
+ tbody = dd.createElement("tbody");
+ tbody.appendChild(node);
+ table.appendChild(tbody);
+ node = table;
+ }else if(node.tagName.toLowerCase() == "th"){
+ // insert extra table nodes
+ table = dd.createElement("table");
+ tbody = dd.createElement("tbody");
+ var r = dd.createElement("tr");
+ table.cellPadding = table.cellSpacing = "0";
+ r.appendChild(node);
+ tbody.appendChild(r);
+ table.appendChild(tbody);
+ node = table;
+ }
+ }
+ node.id = "";
+ td.appendChild(node);
+ tr.appendChild(img);
+ tr.appendChild(td);
+ dojo.style(tr, "opacity", 0.9);
+ b.appendChild(tr);
+
+ a.appendChild(b);
+ this.node = a;
+
+ var m = dojo.dnd.manager();
+ this.oldOffsetY = m.OFFSET_Y;
+ m.OFFSET_Y = 1;
+ },
+ destroy: function(){
+ dojo.dnd.manager().OFFSET_Y = this.oldOffsetY;
+ this.inherited(arguments);
+ }
+ });
+
+ var oldMakeAvatar = dojo.dnd.manager().makeAvatar;
+ dojo.dnd.manager().makeAvatar = function(){
+ var src = this.source;
+ if(src.viewIndex !== undefined && !dojo.hasClass(dojo.body(),"dijit_a11y")){
+ return new dojox.grid._GridAvatar(this);
+ }
+ return oldMakeAvatar.call(dojo.dnd.manager());
+ };
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/_ViewManager.js b/js/dojo-1.6/dojox/grid/_ViewManager.js
new file mode 100644
index 0000000..8d2f815
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_ViewManager.js
@@ -0,0 +1,313 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid._ViewManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._ViewManager"] = true;
+dojo.provide("dojox.grid._ViewManager");
+
+dojo.declare('dojox.grid._ViewManager', null, {
+ // summary:
+ // A collection of grid views. Owned by grid and used internally for managing grid views.
+ // description:
+ // Grid creates views automatically based on grid's layout structure.
+ // Users should typically not need to access individual views or the views collection directly.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+
+ defaultWidth: 200,
+
+ views: [],
+
+ // operations
+ resize: function(){
+ this.onEach("resize");
+ },
+
+ render: function(){
+ this.onEach("render");
+ },
+
+ // views
+ addView: function(inView){
+ inView.idx = this.views.length;
+ this.views.push(inView);
+ },
+
+ destroyViews: function(){
+ for(var i=0, v; v=this.views[i]; i++){
+ v.destroy();
+ }
+ this.views = [];
+ },
+
+ getContentNodes: function(){
+ var nodes = [];
+ for(var i=0, v; v=this.views[i]; i++){
+ nodes.push(v.contentNode);
+ }
+ return nodes;
+ },
+
+ forEach: function(inCallback){
+ for(var i=0, v; v=this.views[i]; i++){
+ inCallback(v, i);
+ }
+ },
+
+ onEach: function(inMethod, inArgs){
+ inArgs = inArgs || [];
+ for(var i=0, v; v=this.views[i]; i++){
+ if(inMethod in v){
+ v[inMethod].apply(v, inArgs);
+ }
+ }
+ },
+
+ // layout
+ normalizeHeaderNodeHeight: function(){
+ var rowNodes = [];
+ for(var i=0, v; (v=this.views[i]); i++){
+ if(v.headerContentNode.firstChild){
+ rowNodes.push(v.headerContentNode);
+ }
+ }
+ this.normalizeRowNodeHeights(rowNodes);
+ },
+
+ normalizeRowNodeHeights: function(inRowNodes){
+ var h = 0;
+ var currHeights = [];
+ if(this.grid.rowHeight){
+ h = this.grid.rowHeight;
+ }else{
+ if(inRowNodes.length <= 1){
+ // no need to normalize if we are the only one...
+ return;
+ }
+ for(var i=0, n; (n=inRowNodes[i]); i++){
+ // We only care about the height - so don't use marginBox. This
+ // depends on the container not having any margin (which it shouldn't)
+ // Also - we only look up the height if the cell doesn't have the
+ // dojoxGridNonNormalizedCell class (like for row selectors)
+ if(!dojo.hasClass(n, "dojoxGridNonNormalizedCell")){
+ currHeights[i] = n.firstChild.offsetHeight;
+ h = Math.max(h, currHeights[i]);
+ }
+ }
+ h = (h >= 0 ? h : 0);
+
+ //Work around odd FF3 rendering bug: #8864.
+ //A one px increase fixes FireFox 3's rounding bug for fractional font sizes.
+ if(dojo.isMoz && h){h++;}
+ }
+ for(i=0; (n=inRowNodes[i]); i++){
+ if(currHeights[i] != h){
+ n.firstChild.style.height = h + "px";
+ }
+ }
+ },
+
+ resetHeaderNodeHeight: function(){
+ for(var i=0, v, n; (v=this.views[i]); i++){
+ n = v.headerContentNode.firstChild;
+ if(n){
+ n.style.height = "";
+ }
+ }
+ },
+
+ renormalizeRow: function(inRowIndex){
+ var rowNodes = [];
+ for(var i=0, v, n; (v=this.views[i])&&(n=v.getRowNode(inRowIndex)); i++){
+ n.firstChild.style.height = '';
+ rowNodes.push(n);
+ }
+ this.normalizeRowNodeHeights(rowNodes);
+ },
+
+ getViewWidth: function(inIndex){
+ return this.views[inIndex].getWidth() || this.defaultWidth;
+ },
+
+ // must be called after view widths are properly set or height can be miscalculated
+ // if there are flex columns
+ measureHeader: function(){
+ // need to reset view header heights so they are properly measured.
+ this.resetHeaderNodeHeight();
+ this.forEach(function(inView){
+ inView.headerContentNode.style.height = '';
+ });
+ var h = 0;
+ // calculate maximum view header height
+ this.forEach(function(inView){
+ h = Math.max(inView.headerNode.offsetHeight, h);
+ });
+ return h;
+ },
+
+ measureContent: function(){
+ var h = 0;
+ this.forEach(function(inView){
+ h = Math.max(inView.domNode.offsetHeight, h);
+ });
+ return h;
+ },
+
+ findClient: function(inAutoWidth){
+ // try to use user defined client
+ var c = this.grid.elasticView || -1;
+ // attempt to find implicit client
+ if(c < 0){
+ for(var i=1, v; (v=this.views[i]); i++){
+ if(v.viewWidth){
+ for(i=1; (v=this.views[i]); i++){
+ if(!v.viewWidth){
+ c = i;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ // client is in the middle by default
+ if(c < 0){
+ c = Math.floor(this.views.length / 2);
+ }
+ return c;
+ },
+
+ arrange: function(l, w){
+ var i, v, vw, len = this.views.length;
+ // find the client
+ var c = (w <= 0 ? len : this.findClient());
+ // layout views
+ var setPosition = function(v, l){
+ var ds = v.domNode.style;
+ var hs = v.headerNode.style;
+
+ if(!dojo._isBodyLtr()){
+ ds.right = l + 'px';
+ // fixed rtl, the scrollbar is on the right side in FF
+ if (dojo.isMoz) {
+ hs.right = l + v.getScrollbarWidth() + 'px';
+ hs.width = parseInt(hs.width, 10) - v.getScrollbarWidth() + 'px';
+ }else{
+ hs.right = l + 'px';
+ }
+ }else{
+ ds.left = l + 'px';
+ hs.left = l + 'px';
+ }
+ ds.top = 0 + 'px';
+ hs.top = 0;
+ };
+ // for views left of the client
+ //BiDi TODO: The left and right should not appear in BIDI environment. Should be replaced with
+ //leading and tailing concept.
+ for(i=0; (v=this.views[i])&&(i<c); i++){
+ // get width
+ vw = this.getViewWidth(i);
+ // process boxes
+ v.setSize(vw, 0);
+ setPosition(v, l);
+ if(v.headerContentNode && v.headerContentNode.firstChild){
+ vw = v.getColumnsWidth()+v.getScrollbarWidth();
+ }else{
+ vw = v.domNode.offsetWidth;
+ }
+ // update position
+ l += vw;
+ }
+ // next view (is the client, i++ == c)
+ i++;
+ // start from the right edge
+ var r = w;
+ // for views right of the client (iterated from the right)
+ for(var j=len-1; (v=this.views[j])&&(i<=j); j--){
+ // get width
+ vw = this.getViewWidth(j);
+ // set size
+ v.setSize(vw, 0);
+ // measure in pixels
+ vw = v.domNode.offsetWidth;
+ // update position
+ r -= vw;
+ // set position
+ setPosition(v, r);
+ }
+ if(c<len){
+ v = this.views[c];
+ // position the client box between left and right boxes
+ vw = Math.max(1, r-l);
+ // set size
+ v.setSize(vw + 'px', 0);
+ setPosition(v, l);
+ }
+ return l;
+ },
+
+ // rendering
+ renderRow: function(inRowIndex, inNodes, skipRenorm){
+ var rowNodes = [];
+ for(var i=0, v, n, rowNode; (v=this.views[i])&&(n=inNodes[i]); i++){
+ rowNode = v.renderRow(inRowIndex);
+ n.appendChild(rowNode);
+ rowNodes.push(rowNode);
+ }
+ if(!skipRenorm){
+ this.normalizeRowNodeHeights(rowNodes);
+ }
+ },
+
+ rowRemoved: function(inRowIndex){
+ this.onEach("rowRemoved", [ inRowIndex ]);
+ },
+
+ // updating
+ updateRow: function(inRowIndex, skipRenorm){
+ for(var i=0, v; v=this.views[i]; i++){
+ v.updateRow(inRowIndex);
+ }
+ if(!skipRenorm){
+ this.renormalizeRow(inRowIndex);
+ }
+ },
+
+ updateRowStyles: function(inRowIndex){
+ this.onEach("updateRowStyles", [ inRowIndex ]);
+ },
+
+ // scrolling
+ setScrollTop: function(inTop){
+ var top = inTop;
+ for(var i=0, v; v=this.views[i]; i++){
+ top = v.setScrollTop(inTop);
+ // Work around IE not firing scroll events that cause header offset
+ // issues to occur.
+ if(dojo.isIE && v.headerNode && v.scrollboxNode){
+ v.headerNode.scrollLeft = v.scrollboxNode.scrollLeft;
+ }
+ }
+ return top;
+ //this.onEach("setScrollTop", [ inTop ]);
+ },
+
+ getFirstScrollingView: function(){
+ // summary: Returns the first grid view with a scroll bar
+ for(var i=0, v; (v=this.views[i]); i++){
+ if(v.hasHScrollbar() || v.hasVScrollbar()){
+ return v;
+ }
+ }
+ return null;
+ }
+
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/_ViewManager.xd.js b/js/dojo-1.6/dojox/grid/_ViewManager.xd.js
new file mode 100644
index 0000000..bfb851c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/_ViewManager.xd.js
@@ -0,0 +1,317 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid._ViewManager"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid._ViewManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._ViewManager"] = true;
+dojo.provide("dojox.grid._ViewManager");
+
+dojo.declare('dojox.grid._ViewManager', null, {
+ // summary:
+ // A collection of grid views. Owned by grid and used internally for managing grid views.
+ // description:
+ // Grid creates views automatically based on grid's layout structure.
+ // Users should typically not need to access individual views or the views collection directly.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+
+ defaultWidth: 200,
+
+ views: [],
+
+ // operations
+ resize: function(){
+ this.onEach("resize");
+ },
+
+ render: function(){
+ this.onEach("render");
+ },
+
+ // views
+ addView: function(inView){
+ inView.idx = this.views.length;
+ this.views.push(inView);
+ },
+
+ destroyViews: function(){
+ for(var i=0, v; v=this.views[i]; i++){
+ v.destroy();
+ }
+ this.views = [];
+ },
+
+ getContentNodes: function(){
+ var nodes = [];
+ for(var i=0, v; v=this.views[i]; i++){
+ nodes.push(v.contentNode);
+ }
+ return nodes;
+ },
+
+ forEach: function(inCallback){
+ for(var i=0, v; v=this.views[i]; i++){
+ inCallback(v, i);
+ }
+ },
+
+ onEach: function(inMethod, inArgs){
+ inArgs = inArgs || [];
+ for(var i=0, v; v=this.views[i]; i++){
+ if(inMethod in v){
+ v[inMethod].apply(v, inArgs);
+ }
+ }
+ },
+
+ // layout
+ normalizeHeaderNodeHeight: function(){
+ var rowNodes = [];
+ for(var i=0, v; (v=this.views[i]); i++){
+ if(v.headerContentNode.firstChild){
+ rowNodes.push(v.headerContentNode);
+ }
+ }
+ this.normalizeRowNodeHeights(rowNodes);
+ },
+
+ normalizeRowNodeHeights: function(inRowNodes){
+ var h = 0;
+ var currHeights = [];
+ if(this.grid.rowHeight){
+ h = this.grid.rowHeight;
+ }else{
+ if(inRowNodes.length <= 1){
+ // no need to normalize if we are the only one...
+ return;
+ }
+ for(var i=0, n; (n=inRowNodes[i]); i++){
+ // We only care about the height - so don't use marginBox. This
+ // depends on the container not having any margin (which it shouldn't)
+ // Also - we only look up the height if the cell doesn't have the
+ // dojoxGridNonNormalizedCell class (like for row selectors)
+ if(!dojo.hasClass(n, "dojoxGridNonNormalizedCell")){
+ currHeights[i] = n.firstChild.offsetHeight;
+ h = Math.max(h, currHeights[i]);
+ }
+ }
+ h = (h >= 0 ? h : 0);
+
+ //Work around odd FF3 rendering bug: #8864.
+ //A one px increase fixes FireFox 3's rounding bug for fractional font sizes.
+ if(dojo.isMoz && h){h++;}
+ }
+ for(i=0; (n=inRowNodes[i]); i++){
+ if(currHeights[i] != h){
+ n.firstChild.style.height = h + "px";
+ }
+ }
+ },
+
+ resetHeaderNodeHeight: function(){
+ for(var i=0, v, n; (v=this.views[i]); i++){
+ n = v.headerContentNode.firstChild;
+ if(n){
+ n.style.height = "";
+ }
+ }
+ },
+
+ renormalizeRow: function(inRowIndex){
+ var rowNodes = [];
+ for(var i=0, v, n; (v=this.views[i])&&(n=v.getRowNode(inRowIndex)); i++){
+ n.firstChild.style.height = '';
+ rowNodes.push(n);
+ }
+ this.normalizeRowNodeHeights(rowNodes);
+ },
+
+ getViewWidth: function(inIndex){
+ return this.views[inIndex].getWidth() || this.defaultWidth;
+ },
+
+ // must be called after view widths are properly set or height can be miscalculated
+ // if there are flex columns
+ measureHeader: function(){
+ // need to reset view header heights so they are properly measured.
+ this.resetHeaderNodeHeight();
+ this.forEach(function(inView){
+ inView.headerContentNode.style.height = '';
+ });
+ var h = 0;
+ // calculate maximum view header height
+ this.forEach(function(inView){
+ h = Math.max(inView.headerNode.offsetHeight, h);
+ });
+ return h;
+ },
+
+ measureContent: function(){
+ var h = 0;
+ this.forEach(function(inView){
+ h = Math.max(inView.domNode.offsetHeight, h);
+ });
+ return h;
+ },
+
+ findClient: function(inAutoWidth){
+ // try to use user defined client
+ var c = this.grid.elasticView || -1;
+ // attempt to find implicit client
+ if(c < 0){
+ for(var i=1, v; (v=this.views[i]); i++){
+ if(v.viewWidth){
+ for(i=1; (v=this.views[i]); i++){
+ if(!v.viewWidth){
+ c = i;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ // client is in the middle by default
+ if(c < 0){
+ c = Math.floor(this.views.length / 2);
+ }
+ return c;
+ },
+
+ arrange: function(l, w){
+ var i, v, vw, len = this.views.length;
+ // find the client
+ var c = (w <= 0 ? len : this.findClient());
+ // layout views
+ var setPosition = function(v, l){
+ var ds = v.domNode.style;
+ var hs = v.headerNode.style;
+
+ if(!dojo._isBodyLtr()){
+ ds.right = l + 'px';
+ // fixed rtl, the scrollbar is on the right side in FF
+ if (dojo.isMoz) {
+ hs.right = l + v.getScrollbarWidth() + 'px';
+ hs.width = parseInt(hs.width, 10) - v.getScrollbarWidth() + 'px';
+ }else{
+ hs.right = l + 'px';
+ }
+ }else{
+ ds.left = l + 'px';
+ hs.left = l + 'px';
+ }
+ ds.top = 0 + 'px';
+ hs.top = 0;
+ };
+ // for views left of the client
+ //BiDi TODO: The left and right should not appear in BIDI environment. Should be replaced with
+ //leading and tailing concept.
+ for(i=0; (v=this.views[i])&&(i<c); i++){
+ // get width
+ vw = this.getViewWidth(i);
+ // process boxes
+ v.setSize(vw, 0);
+ setPosition(v, l);
+ if(v.headerContentNode && v.headerContentNode.firstChild){
+ vw = v.getColumnsWidth()+v.getScrollbarWidth();
+ }else{
+ vw = v.domNode.offsetWidth;
+ }
+ // update position
+ l += vw;
+ }
+ // next view (is the client, i++ == c)
+ i++;
+ // start from the right edge
+ var r = w;
+ // for views right of the client (iterated from the right)
+ for(var j=len-1; (v=this.views[j])&&(i<=j); j--){
+ // get width
+ vw = this.getViewWidth(j);
+ // set size
+ v.setSize(vw, 0);
+ // measure in pixels
+ vw = v.domNode.offsetWidth;
+ // update position
+ r -= vw;
+ // set position
+ setPosition(v, r);
+ }
+ if(c<len){
+ v = this.views[c];
+ // position the client box between left and right boxes
+ vw = Math.max(1, r-l);
+ // set size
+ v.setSize(vw + 'px', 0);
+ setPosition(v, l);
+ }
+ return l;
+ },
+
+ // rendering
+ renderRow: function(inRowIndex, inNodes, skipRenorm){
+ var rowNodes = [];
+ for(var i=0, v, n, rowNode; (v=this.views[i])&&(n=inNodes[i]); i++){
+ rowNode = v.renderRow(inRowIndex);
+ n.appendChild(rowNode);
+ rowNodes.push(rowNode);
+ }
+ if(!skipRenorm){
+ this.normalizeRowNodeHeights(rowNodes);
+ }
+ },
+
+ rowRemoved: function(inRowIndex){
+ this.onEach("rowRemoved", [ inRowIndex ]);
+ },
+
+ // updating
+ updateRow: function(inRowIndex, skipRenorm){
+ for(var i=0, v; v=this.views[i]; i++){
+ v.updateRow(inRowIndex);
+ }
+ if(!skipRenorm){
+ this.renormalizeRow(inRowIndex);
+ }
+ },
+
+ updateRowStyles: function(inRowIndex){
+ this.onEach("updateRowStyles", [ inRowIndex ]);
+ },
+
+ // scrolling
+ setScrollTop: function(inTop){
+ var top = inTop;
+ for(var i=0, v; v=this.views[i]; i++){
+ top = v.setScrollTop(inTop);
+ // Work around IE not firing scroll events that cause header offset
+ // issues to occur.
+ if(dojo.isIE && v.headerNode && v.scrollboxNode){
+ v.headerNode.scrollLeft = v.scrollboxNode.scrollLeft;
+ }
+ }
+ return top;
+ //this.onEach("setScrollTop", [ inTop ]);
+ },
+
+ getFirstScrollingView: function(){
+ // summary: Returns the first grid view with a scroll bar
+ for(var i=0, v; (v=this.views[i]); i++){
+ if(v.hasHScrollbar() || v.hasVScrollbar()){
+ return v;
+ }
+ }
+ return null;
+ }
+
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/cells.js b/js/dojo-1.6/dojox/grid/cells.js
new file mode 100644
index 0000000..ee4adee
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/cells.js
@@ -0,0 +1,13 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.cells"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.cells"] = true;
+dojo.provide("dojox.grid.cells");
+dojo.require("dojox.grid.cells._base");
+
+}
diff --git a/js/dojo-1.6/dojox/grid/cells.xd.js b/js/dojo-1.6/dojox/grid/cells.xd.js
new file mode 100644
index 0000000..9686d51
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/cells.xd.js
@@ -0,0 +1,18 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.cells"],
+["require", "dojox.grid.cells._base"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.cells"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.cells"] = true;
+dojo.provide("dojox.grid.cells");
+dojo.require("dojox.grid.cells._base");
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/cells/_base.js b/js/dojo-1.6/dojox/grid/cells/_base.js
new file mode 100644
index 0000000..298c000
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/cells/_base.js
@@ -0,0 +1,464 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.cells._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.cells._base"] = true;
+dojo.provide("dojox.grid.cells._base");
+
+dojo.require("dojox.grid.util");
+dojo.require("dijit._Widget");
+
+dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
+ deferred: null,
+ _destroyOnRemove: true,
+ postCreate: function(){
+ if(this.deferred){
+ this.deferred.addBoth(dojo.hitch(this, function(text){
+ if(this.domNode){
+ this.domNode.innerHTML = text;
+ }
+ }));
+ }
+ }
+});
+
+(function(){
+ var focusSelectNode = function(inNode){
+ try{
+ dojox.grid.util.fire(inNode, "focus");
+ dojox.grid.util.fire(inNode, "select");
+ }catch(e){// IE sux bad
+ }
+ };
+
+ var whenIdle = function(/*inContext, inMethod, args ...*/){
+ setTimeout(dojo.hitch.apply(dojo, arguments), 0);
+ };
+
+ var dgc = dojox.grid.cells;
+
+ dojo.declare("dojox.grid.cells._Base", null, {
+ // summary:
+ // Respresents a grid cell and contains information about column options and methods
+ // for retrieving cell related information.
+ // Each column in a grid layout has a cell object and most events and many methods
+ // provide access to these objects.
+ styles: '',
+ classes: '',
+ editable: false,
+ alwaysEditing: false,
+ formatter: null,
+ defaultValue: '...',
+ value: null,
+ hidden: false,
+ noresize: false,
+ draggable: true,
+ //private
+ _valueProp: "value",
+ _formatPending: false,
+
+ constructor: function(inProps){
+ this._props = inProps || {};
+ dojo.mixin(this, inProps);
+ if(this.draggable === undefined){
+ this.draggable = true;
+ }
+ },
+
+ _defaultFormat: function(inValue, callArgs){
+ var s = this.grid.formatterScope || this;
+ var f = this.formatter;
+ if(f && s && typeof f == "string"){
+ f = this.formatter = s[f];
+ }
+ var v = (inValue != this.defaultValue && f) ? f.apply(s, callArgs) : inValue;
+ if(typeof v == "undefined"){
+ return this.defaultValue;
+ }
+ if(v && v.addBoth){
+ // Check if it's a deferred
+ v = new dojox.grid._DeferredTextWidget({deferred: v},
+ dojo.create("span", {innerHTML: this.defaultValue}));
+ }
+ if(v && v.declaredClass && v.startup){
+ return "<div class='dojoxGridStubNode' linkWidget='" +
+ v.id +
+ "' cellIdx='" +
+ this.index +
+ "'>" +
+ this.defaultValue +
+ "</div>";
+ }
+ return v;
+ },
+
+ // data source
+ format: function(inRowIndex, inItem){
+ // summary:
+ // provides the html for a given grid cell.
+ // inRowIndex: int
+ // grid row index
+ // returns: html for a given grid cell
+ var f, i=this.grid.edit.info, d=this.get ? this.get(inRowIndex, inItem) : (this.value || this.defaultValue);
+ d = (d && d.replace && this.grid.escapeHTMLInData) ? d.replace(/&/g, '&amp;').replace(/</g, '&lt;') : d;
+ if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndex && i.cell==this))){
+ return this.formatEditing(d, inRowIndex);
+ }else{
+ return this._defaultFormat(d, [d, inRowIndex, this]);
+ }
+ },
+ formatEditing: function(inDatum, inRowIndex){
+ // summary:
+ // formats the cell for editing
+ // inDatum: anything
+ // cell data to edit
+ // inRowIndex: int
+ // grid row index
+ // returns: string of html to place in grid cell
+ },
+ // utility
+ getNode: function(inRowIndex){
+ // summary:
+ // gets the dom node for a given grid cell.
+ // inRowIndex: int
+ // grid row index
+ // returns: dom node for a given grid cell
+ return this.view.getCellNode(inRowIndex, this.index);
+ },
+ getHeaderNode: function(){
+ return this.view.getHeaderCellNode(this.index);
+ },
+ getEditNode: function(inRowIndex){
+ return (this.getNode(inRowIndex) || 0).firstChild || 0;
+ },
+ canResize: function(){
+ var uw = this.unitWidth;
+ return uw && (uw!=='auto');
+ },
+ isFlex: function(){
+ var uw = this.unitWidth;
+ return uw && dojo.isString(uw) && (uw=='auto' || uw.slice(-1)=='%');
+ },
+ // edit support
+ applyEdit: function(inValue, inRowIndex){
+ this.grid.edit.applyCellEdit(inValue, this, inRowIndex);
+ },
+ cancelEdit: function(inRowIndex){
+ this.grid.doCancelEdit(inRowIndex);
+ },
+ _onEditBlur: function(inRowIndex){
+ if(this.grid.edit.isEditCell(inRowIndex, this.index)){
+ //console.log('editor onblur', e);
+ this.grid.edit.apply();
+ }
+ },
+ registerOnBlur: function(inNode, inRowIndex){
+ if(this.commitOnBlur){
+ dojo.connect(inNode, "onblur", function(e){
+ // hack: if editor still thinks this editor is current some ms after it blurs, assume we've focused away from grid
+ setTimeout(dojo.hitch(this, "_onEditBlur", inRowIndex), 250);
+ });
+ }
+ },
+ //protected
+ needFormatNode: function(inDatum, inRowIndex){
+ this._formatPending = true;
+ whenIdle(this, "_formatNode", inDatum, inRowIndex);
+ },
+ cancelFormatNode: function(){
+ this._formatPending = false;
+ },
+ //private
+ _formatNode: function(inDatum, inRowIndex){
+ if(this._formatPending){
+ this._formatPending = false;
+ // make cell selectable
+ dojo.setSelectable(this.grid.domNode, true);
+ this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex);
+ }
+ },
+ //protected
+ formatNode: function(inNode, inDatum, inRowIndex){
+ // summary:
+ // format the editing dom node. Use when editor is a widget.
+ // inNode: dom node
+ // dom node for the editor
+ // inDatum: anything
+ // cell data to edit
+ // inRowIndex: int
+ // grid row index
+ if(dojo.isIE){
+ // IE sux bad
+ whenIdle(this, "focus", inRowIndex, inNode);
+ }else{
+ this.focus(inRowIndex, inNode);
+ }
+ },
+ dispatchEvent: function(m, e){
+ if(m in this){
+ return this[m](e);
+ }
+ },
+ //public
+ getValue: function(inRowIndex){
+ // summary:
+ // returns value entered into editor
+ // inRowIndex: int
+ // grid row index
+ // returns:
+ // value of editor
+ return this.getEditNode(inRowIndex)[this._valueProp];
+ },
+ setValue: function(inRowIndex, inValue){
+ // summary:
+ // set the value of the grid editor
+ // inRowIndex: int
+ // grid row index
+ // inValue: anything
+ // value of editor
+ var n = this.getEditNode(inRowIndex);
+ if(n){
+ n[this._valueProp] = inValue;
+ }
+ },
+ focus: function(inRowIndex, inNode){
+ // summary:
+ // focus the grid editor
+ // inRowIndex: int
+ // grid row index
+ // inNode: dom node
+ // editor node
+ focusSelectNode(inNode || this.getEditNode(inRowIndex));
+ },
+ save: function(inRowIndex){
+ // summary:
+ // save editor state
+ // inRowIndex: int
+ // grid row index
+ this.value = this.value || this.getValue(inRowIndex);
+ //console.log("save", this.value, inCell.index, inRowIndex);
+ },
+ restore: function(inRowIndex){
+ // summary:
+ // restore editor state
+ // inRowIndex: int
+ // grid row index
+ this.setValue(inRowIndex, this.value);
+ //console.log("restore", this.value, inCell.index, inRowIndex);
+ },
+ //protected
+ _finish: function(inRowIndex){
+ // summary:
+ // called when editing is completed to clean up editor
+ // inRowIndex: int
+ // grid row index
+ dojo.setSelectable(this.grid.domNode, false);
+ this.cancelFormatNode();
+ },
+ //public
+ apply: function(inRowIndex){
+ // summary:
+ // apply edit from cell editor
+ // inRowIndex: int
+ // grid row index
+ this.applyEdit(this.getValue(inRowIndex), inRowIndex);
+ this._finish(inRowIndex);
+ },
+ cancel: function(inRowIndex){
+ // summary:
+ // cancel cell edit
+ // inRowIndex: int
+ // grid row index
+ this.cancelEdit(inRowIndex);
+ this._finish(inRowIndex);
+ }
+ });
+ dgc._Base.markupFactory = function(node, cellDef){
+ var d = dojo;
+ var formatter = d.trim(d.attr(node, "formatter")||"");
+ if(formatter){
+ cellDef.formatter = dojo.getObject(formatter)||formatter;
+ }
+ var get = d.trim(d.attr(node, "get")||"");
+ if(get){
+ cellDef.get = dojo.getObject(get);
+ }
+ var getBoolAttr = function(attr, cell, cellAttr){
+ var value = d.trim(d.attr(node, attr)||"");
+ if(value){ cell[cellAttr||attr] = !(value.toLowerCase()=="false"); }
+ };
+ getBoolAttr("sortDesc", cellDef);
+ getBoolAttr("editable", cellDef);
+ getBoolAttr("alwaysEditing", cellDef);
+ getBoolAttr("noresize", cellDef);
+ getBoolAttr("draggable", cellDef);
+
+ var value = d.trim(d.attr(node, "loadingText")||d.attr(node, "defaultValue")||"");
+ if(value){
+ cellDef.defaultValue = value;
+ }
+
+ var getStrAttr = function(attr, cell, cellAttr){
+ var value = d.trim(d.attr(node, attr)||"")||undefined;
+ if(value){ cell[cellAttr||attr] = value; }
+ };
+ getStrAttr("styles", cellDef);
+ getStrAttr("headerStyles", cellDef);
+ getStrAttr("cellStyles", cellDef);
+ getStrAttr("classes", cellDef);
+ getStrAttr("headerClasses", cellDef);
+ getStrAttr("cellClasses", cellDef);
+ };
+
+ dojo.declare("dojox.grid.cells.Cell", dgc._Base, {
+ // summary
+ // grid cell that provides a standard text input box upon editing
+ constructor: function(){
+ this.keyFilter = this.keyFilter;
+ },
+ // keyFilter: RegExp
+ // optional regex for disallowing keypresses
+ keyFilter: null,
+ formatEditing: function(inDatum, inRowIndex){
+ this.needFormatNode(inDatum, inRowIndex);
+ return '<input class="dojoxGridInput" type="text" value="' + inDatum + '">';
+ },
+ formatNode: function(inNode, inDatum, inRowIndex){
+ this.inherited(arguments);
+ // FIXME: feels too specific for this interface
+ this.registerOnBlur(inNode, inRowIndex);
+ },
+ doKey: function(e){
+ if(this.keyFilter){
+ var key = String.fromCharCode(e.charCode);
+ if(key.search(this.keyFilter) == -1){
+ dojo.stopEvent(e);
+ }
+ }
+ },
+ _finish: function(inRowIndex){
+ this.inherited(arguments);
+ var n = this.getEditNode(inRowIndex);
+ try{
+ dojox.grid.util.fire(n, "blur");
+ }catch(e){}
+ }
+ });
+ dgc.Cell.markupFactory = function(node, cellDef){
+ dgc._Base.markupFactory(node, cellDef);
+ var d = dojo;
+ var keyFilter = d.trim(d.attr(node, "keyFilter")||"");
+ if(keyFilter){
+ cellDef.keyFilter = new RegExp(keyFilter);
+ }
+ };
+
+ dojo.declare("dojox.grid.cells.RowIndex", dgc.Cell, {
+ name: 'Row',
+
+ postscript: function(){
+ this.editable = false;
+ },
+ get: function(inRowIndex){
+ return inRowIndex + 1;
+ }
+ });
+ dgc.RowIndex.markupFactory = function(node, cellDef){
+ dgc.Cell.markupFactory(node, cellDef);
+ };
+
+ dojo.declare("dojox.grid.cells.Select", dgc.Cell, {
+ // summary:
+ // grid cell that provides a standard select for editing
+
+ // options: Array
+ // text of each item
+ options: null,
+
+ // values: Array
+ // value for each item
+ values: null,
+
+ // returnIndex: Integer
+ // editor returns only the index of the selected option and not the value
+ returnIndex: -1,
+
+ constructor: function(inCell){
+ this.values = this.values || this.options;
+ },
+ formatEditing: function(inDatum, inRowIndex){
+ this.needFormatNode(inDatum, inRowIndex);
+ var h = [ '<select class="dojoxGridSelect">' ];
+ for (var i=0, o, v; ((o=this.options[i]) !== undefined)&&((v=this.values[i]) !== undefined); i++){
+ h.push("<option", (inDatum==v ? ' selected' : ''), ' value="' + v + '"', ">", o, "</option>");
+ }
+ h.push('</select>');
+ return h.join('');
+ },
+ getValue: function(inRowIndex){
+ var n = this.getEditNode(inRowIndex);
+ if(n){
+ var i = n.selectedIndex, o = n.options[i];
+ return this.returnIndex > -1 ? i : o.value || o.innerHTML;
+ }
+ }
+ });
+ dgc.Select.markupFactory = function(node, cell){
+ dgc.Cell.markupFactory(node, cell);
+ var d=dojo;
+ var options = d.trim(d.attr(node, "options")||"");
+ if(options){
+ var o = options.split(',');
+ if(o[0] != options){
+ cell.options = o;
+ }
+ }
+ var values = d.trim(d.attr(node, "values")||"");
+ if(values){
+ var v = values.split(',');
+ if(v[0] != values){
+ cell.values = v;
+ }
+ }
+ };
+
+ dojo.declare("dojox.grid.cells.AlwaysEdit", dgc.Cell, {
+ // summary:
+ // grid cell that is always in an editable state, regardless of grid editing state
+ alwaysEditing: true,
+ _formatNode: function(inDatum, inRowIndex){
+ this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex);
+ },
+ applyStaticValue: function(inRowIndex){
+ var e = this.grid.edit;
+ e.applyCellEdit(this.getValue(inRowIndex), this, inRowIndex);
+ e.start(this, inRowIndex, true);
+ }
+ });
+ dgc.AlwaysEdit.markupFactory = function(node, cell){
+ dgc.Cell.markupFactory(node, cell);
+ };
+
+ dojo.declare("dojox.grid.cells.Bool", dgc.AlwaysEdit, {
+ // summary:
+ // grid cell that provides a standard checkbox that is always on for editing
+ _valueProp: "checked",
+ formatEditing: function(inDatum, inRowIndex){
+ return '<input class="dojoxGridInput" type="checkbox"' + (inDatum ? ' checked="checked"' : '') + ' style="width: auto" />';
+ },
+ doclick: function(e){
+ if(e.target.tagName == 'INPUT'){
+ this.applyStaticValue(e.rowIndex);
+ }
+ }
+ });
+ dgc.Bool.markupFactory = function(node, cell){
+ dgc.AlwaysEdit.markupFactory(node, cell);
+ };
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/cells/_base.xd.js b/js/dojo-1.6/dojox/grid/cells/_base.xd.js
new file mode 100644
index 0000000..cd72aca
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/cells/_base.xd.js
@@ -0,0 +1,470 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.cells._base"],
+["require", "dojox.grid.util"],
+["require", "dijit._Widget"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.cells._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.cells._base"] = true;
+dojo.provide("dojox.grid.cells._base");
+
+dojo.require("dojox.grid.util");
+dojo.require("dijit._Widget");
+
+dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
+ deferred: null,
+ _destroyOnRemove: true,
+ postCreate: function(){
+ if(this.deferred){
+ this.deferred.addBoth(dojo.hitch(this, function(text){
+ if(this.domNode){
+ this.domNode.innerHTML = text;
+ }
+ }));
+ }
+ }
+});
+
+(function(){
+ var focusSelectNode = function(inNode){
+ try{
+ dojox.grid.util.fire(inNode, "focus");
+ dojox.grid.util.fire(inNode, "select");
+ }catch(e){// IE sux bad
+ }
+ };
+
+ var whenIdle = function(/*inContext, inMethod, args ...*/){
+ setTimeout(dojo.hitch.apply(dojo, arguments), 0);
+ };
+
+ var dgc = dojox.grid.cells;
+
+ dojo.declare("dojox.grid.cells._Base", null, {
+ // summary:
+ // Respresents a grid cell and contains information about column options and methods
+ // for retrieving cell related information.
+ // Each column in a grid layout has a cell object and most events and many methods
+ // provide access to these objects.
+ styles: '',
+ classes: '',
+ editable: false,
+ alwaysEditing: false,
+ formatter: null,
+ defaultValue: '...',
+ value: null,
+ hidden: false,
+ noresize: false,
+ draggable: true,
+ //private
+ _valueProp: "value",
+ _formatPending: false,
+
+ constructor: function(inProps){
+ this._props = inProps || {};
+ dojo.mixin(this, inProps);
+ if(this.draggable === undefined){
+ this.draggable = true;
+ }
+ },
+
+ _defaultFormat: function(inValue, callArgs){
+ var s = this.grid.formatterScope || this;
+ var f = this.formatter;
+ if(f && s && typeof f == "string"){
+ f = this.formatter = s[f];
+ }
+ var v = (inValue != this.defaultValue && f) ? f.apply(s, callArgs) : inValue;
+ if(typeof v == "undefined"){
+ return this.defaultValue;
+ }
+ if(v && v.addBoth){
+ // Check if it's a deferred
+ v = new dojox.grid._DeferredTextWidget({deferred: v},
+ dojo.create("span", {innerHTML: this.defaultValue}));
+ }
+ if(v && v.declaredClass && v.startup){
+ return "<div class='dojoxGridStubNode' linkWidget='" +
+ v.id +
+ "' cellIdx='" +
+ this.index +
+ "'>" +
+ this.defaultValue +
+ "</div>";
+ }
+ return v;
+ },
+
+ // data source
+ format: function(inRowIndex, inItem){
+ // summary:
+ // provides the html for a given grid cell.
+ // inRowIndex: int
+ // grid row index
+ // returns: html for a given grid cell
+ var f, i=this.grid.edit.info, d=this.get ? this.get(inRowIndex, inItem) : (this.value || this.defaultValue);
+ d = (d && d.replace && this.grid.escapeHTMLInData) ? d.replace(/&/g, '&amp;').replace(/</g, '&lt;') : d;
+ if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndex && i.cell==this))){
+ return this.formatEditing(d, inRowIndex);
+ }else{
+ return this._defaultFormat(d, [d, inRowIndex, this]);
+ }
+ },
+ formatEditing: function(inDatum, inRowIndex){
+ // summary:
+ // formats the cell for editing
+ // inDatum: anything
+ // cell data to edit
+ // inRowIndex: int
+ // grid row index
+ // returns: string of html to place in grid cell
+ },
+ // utility
+ getNode: function(inRowIndex){
+ // summary:
+ // gets the dom node for a given grid cell.
+ // inRowIndex: int
+ // grid row index
+ // returns: dom node for a given grid cell
+ return this.view.getCellNode(inRowIndex, this.index);
+ },
+ getHeaderNode: function(){
+ return this.view.getHeaderCellNode(this.index);
+ },
+ getEditNode: function(inRowIndex){
+ return (this.getNode(inRowIndex) || 0).firstChild || 0;
+ },
+ canResize: function(){
+ var uw = this.unitWidth;
+ return uw && (uw!=='auto');
+ },
+ isFlex: function(){
+ var uw = this.unitWidth;
+ return uw && dojo.isString(uw) && (uw=='auto' || uw.slice(-1)=='%');
+ },
+ // edit support
+ applyEdit: function(inValue, inRowIndex){
+ this.grid.edit.applyCellEdit(inValue, this, inRowIndex);
+ },
+ cancelEdit: function(inRowIndex){
+ this.grid.doCancelEdit(inRowIndex);
+ },
+ _onEditBlur: function(inRowIndex){
+ if(this.grid.edit.isEditCell(inRowIndex, this.index)){
+ //console.log('editor onblur', e);
+ this.grid.edit.apply();
+ }
+ },
+ registerOnBlur: function(inNode, inRowIndex){
+ if(this.commitOnBlur){
+ dojo.connect(inNode, "onblur", function(e){
+ // hack: if editor still thinks this editor is current some ms after it blurs, assume we've focused away from grid
+ setTimeout(dojo.hitch(this, "_onEditBlur", inRowIndex), 250);
+ });
+ }
+ },
+ //protected
+ needFormatNode: function(inDatum, inRowIndex){
+ this._formatPending = true;
+ whenIdle(this, "_formatNode", inDatum, inRowIndex);
+ },
+ cancelFormatNode: function(){
+ this._formatPending = false;
+ },
+ //private
+ _formatNode: function(inDatum, inRowIndex){
+ if(this._formatPending){
+ this._formatPending = false;
+ // make cell selectable
+ dojo.setSelectable(this.grid.domNode, true);
+ this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex);
+ }
+ },
+ //protected
+ formatNode: function(inNode, inDatum, inRowIndex){
+ // summary:
+ // format the editing dom node. Use when editor is a widget.
+ // inNode: dom node
+ // dom node for the editor
+ // inDatum: anything
+ // cell data to edit
+ // inRowIndex: int
+ // grid row index
+ if(dojo.isIE){
+ // IE sux bad
+ whenIdle(this, "focus", inRowIndex, inNode);
+ }else{
+ this.focus(inRowIndex, inNode);
+ }
+ },
+ dispatchEvent: function(m, e){
+ if(m in this){
+ return this[m](e);
+ }
+ },
+ //public
+ getValue: function(inRowIndex){
+ // summary:
+ // returns value entered into editor
+ // inRowIndex: int
+ // grid row index
+ // returns:
+ // value of editor
+ return this.getEditNode(inRowIndex)[this._valueProp];
+ },
+ setValue: function(inRowIndex, inValue){
+ // summary:
+ // set the value of the grid editor
+ // inRowIndex: int
+ // grid row index
+ // inValue: anything
+ // value of editor
+ var n = this.getEditNode(inRowIndex);
+ if(n){
+ n[this._valueProp] = inValue;
+ }
+ },
+ focus: function(inRowIndex, inNode){
+ // summary:
+ // focus the grid editor
+ // inRowIndex: int
+ // grid row index
+ // inNode: dom node
+ // editor node
+ focusSelectNode(inNode || this.getEditNode(inRowIndex));
+ },
+ save: function(inRowIndex){
+ // summary:
+ // save editor state
+ // inRowIndex: int
+ // grid row index
+ this.value = this.value || this.getValue(inRowIndex);
+ //console.log("save", this.value, inCell.index, inRowIndex);
+ },
+ restore: function(inRowIndex){
+ // summary:
+ // restore editor state
+ // inRowIndex: int
+ // grid row index
+ this.setValue(inRowIndex, this.value);
+ //console.log("restore", this.value, inCell.index, inRowIndex);
+ },
+ //protected
+ _finish: function(inRowIndex){
+ // summary:
+ // called when editing is completed to clean up editor
+ // inRowIndex: int
+ // grid row index
+ dojo.setSelectable(this.grid.domNode, false);
+ this.cancelFormatNode();
+ },
+ //public
+ apply: function(inRowIndex){
+ // summary:
+ // apply edit from cell editor
+ // inRowIndex: int
+ // grid row index
+ this.applyEdit(this.getValue(inRowIndex), inRowIndex);
+ this._finish(inRowIndex);
+ },
+ cancel: function(inRowIndex){
+ // summary:
+ // cancel cell edit
+ // inRowIndex: int
+ // grid row index
+ this.cancelEdit(inRowIndex);
+ this._finish(inRowIndex);
+ }
+ });
+ dgc._Base.markupFactory = function(node, cellDef){
+ var d = dojo;
+ var formatter = d.trim(d.attr(node, "formatter")||"");
+ if(formatter){
+ cellDef.formatter = dojo.getObject(formatter)||formatter;
+ }
+ var get = d.trim(d.attr(node, "get")||"");
+ if(get){
+ cellDef.get = dojo.getObject(get);
+ }
+ var getBoolAttr = function(attr, cell, cellAttr){
+ var value = d.trim(d.attr(node, attr)||"");
+ if(value){ cell[cellAttr||attr] = !(value.toLowerCase()=="false"); }
+ };
+ getBoolAttr("sortDesc", cellDef);
+ getBoolAttr("editable", cellDef);
+ getBoolAttr("alwaysEditing", cellDef);
+ getBoolAttr("noresize", cellDef);
+ getBoolAttr("draggable", cellDef);
+
+ var value = d.trim(d.attr(node, "loadingText")||d.attr(node, "defaultValue")||"");
+ if(value){
+ cellDef.defaultValue = value;
+ }
+
+ var getStrAttr = function(attr, cell, cellAttr){
+ var value = d.trim(d.attr(node, attr)||"")||undefined;
+ if(value){ cell[cellAttr||attr] = value; }
+ };
+ getStrAttr("styles", cellDef);
+ getStrAttr("headerStyles", cellDef);
+ getStrAttr("cellStyles", cellDef);
+ getStrAttr("classes", cellDef);
+ getStrAttr("headerClasses", cellDef);
+ getStrAttr("cellClasses", cellDef);
+ };
+
+ dojo.declare("dojox.grid.cells.Cell", dgc._Base, {
+ // summary
+ // grid cell that provides a standard text input box upon editing
+ constructor: function(){
+ this.keyFilter = this.keyFilter;
+ },
+ // keyFilter: RegExp
+ // optional regex for disallowing keypresses
+ keyFilter: null,
+ formatEditing: function(inDatum, inRowIndex){
+ this.needFormatNode(inDatum, inRowIndex);
+ return '<input class="dojoxGridInput" type="text" value="' + inDatum + '">';
+ },
+ formatNode: function(inNode, inDatum, inRowIndex){
+ this.inherited(arguments);
+ // FIXME: feels too specific for this interface
+ this.registerOnBlur(inNode, inRowIndex);
+ },
+ doKey: function(e){
+ if(this.keyFilter){
+ var key = String.fromCharCode(e.charCode);
+ if(key.search(this.keyFilter) == -1){
+ dojo.stopEvent(e);
+ }
+ }
+ },
+ _finish: function(inRowIndex){
+ this.inherited(arguments);
+ var n = this.getEditNode(inRowIndex);
+ try{
+ dojox.grid.util.fire(n, "blur");
+ }catch(e){}
+ }
+ });
+ dgc.Cell.markupFactory = function(node, cellDef){
+ dgc._Base.markupFactory(node, cellDef);
+ var d = dojo;
+ var keyFilter = d.trim(d.attr(node, "keyFilter")||"");
+ if(keyFilter){
+ cellDef.keyFilter = new RegExp(keyFilter);
+ }
+ };
+
+ dojo.declare("dojox.grid.cells.RowIndex", dgc.Cell, {
+ name: 'Row',
+
+ postscript: function(){
+ this.editable = false;
+ },
+ get: function(inRowIndex){
+ return inRowIndex + 1;
+ }
+ });
+ dgc.RowIndex.markupFactory = function(node, cellDef){
+ dgc.Cell.markupFactory(node, cellDef);
+ };
+
+ dojo.declare("dojox.grid.cells.Select", dgc.Cell, {
+ // summary:
+ // grid cell that provides a standard select for editing
+
+ // options: Array
+ // text of each item
+ options: null,
+
+ // values: Array
+ // value for each item
+ values: null,
+
+ // returnIndex: Integer
+ // editor returns only the index of the selected option and not the value
+ returnIndex: -1,
+
+ constructor: function(inCell){
+ this.values = this.values || this.options;
+ },
+ formatEditing: function(inDatum, inRowIndex){
+ this.needFormatNode(inDatum, inRowIndex);
+ var h = [ '<select class="dojoxGridSelect">' ];
+ for (var i=0, o, v; ((o=this.options[i]) !== undefined)&&((v=this.values[i]) !== undefined); i++){
+ h.push("<option", (inDatum==v ? ' selected' : ''), ' value="' + v + '"', ">", o, "</option>");
+ }
+ h.push('</select>');
+ return h.join('');
+ },
+ getValue: function(inRowIndex){
+ var n = this.getEditNode(inRowIndex);
+ if(n){
+ var i = n.selectedIndex, o = n.options[i];
+ return this.returnIndex > -1 ? i : o.value || o.innerHTML;
+ }
+ }
+ });
+ dgc.Select.markupFactory = function(node, cell){
+ dgc.Cell.markupFactory(node, cell);
+ var d=dojo;
+ var options = d.trim(d.attr(node, "options")||"");
+ if(options){
+ var o = options.split(',');
+ if(o[0] != options){
+ cell.options = o;
+ }
+ }
+ var values = d.trim(d.attr(node, "values")||"");
+ if(values){
+ var v = values.split(',');
+ if(v[0] != values){
+ cell.values = v;
+ }
+ }
+ };
+
+ dojo.declare("dojox.grid.cells.AlwaysEdit", dgc.Cell, {
+ // summary:
+ // grid cell that is always in an editable state, regardless of grid editing state
+ alwaysEditing: true,
+ _formatNode: function(inDatum, inRowIndex){
+ this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex);
+ },
+ applyStaticValue: function(inRowIndex){
+ var e = this.grid.edit;
+ e.applyCellEdit(this.getValue(inRowIndex), this, inRowIndex);
+ e.start(this, inRowIndex, true);
+ }
+ });
+ dgc.AlwaysEdit.markupFactory = function(node, cell){
+ dgc.Cell.markupFactory(node, cell);
+ };
+
+ dojo.declare("dojox.grid.cells.Bool", dgc.AlwaysEdit, {
+ // summary:
+ // grid cell that provides a standard checkbox that is always on for editing
+ _valueProp: "checked",
+ formatEditing: function(inDatum, inRowIndex){
+ return '<input class="dojoxGridInput" type="checkbox"' + (inDatum ? ' checked="checked"' : '') + ' style="width: auto" />';
+ },
+ doclick: function(e){
+ if(e.target.tagName == 'INPUT'){
+ this.applyStaticValue(e.rowIndex);
+ }
+ }
+ });
+ dgc.Bool.markupFactory = function(node, cell){
+ dgc.AlwaysEdit.markupFactory(node, cell);
+ };
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/cells/dijit.js b/js/dojo-1.6/dojox/grid/cells/dijit.js
new file mode 100644
index 0000000..8d8f0d5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/cells/dijit.js
@@ -0,0 +1,249 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.cells.dijit"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.cells.dijit"] = true;
+dojo.provide("dojox.grid.cells.dijit");
+
+dojo.require("dojox.grid.cells");
+
+// TODO: shouldn't it be the test file's job to require these modules,
+// if it is using them? Most of these modules aren't referenced by this file.
+
+dojo.require("dijit.form.DateTextBox");
+dojo.require("dijit.form.TimeTextBox");
+dojo.require("dijit.form.ComboBox");
+dojo.require("dojo.data.ItemFileReadStore");
+dojo.require("dijit.form.CheckBox");
+dojo.require("dijit.form.TextBox");
+dojo.require("dijit.form.NumberSpinner");
+dojo.require("dijit.form.NumberTextBox");
+dojo.require("dijit.form.CurrencyTextBox");
+dojo.require("dijit.form.HorizontalSlider");
+dojo.require("dijit.Editor");
+
+(function(){
+ var dgc = dojox.grid.cells;
+ dojo.declare("dojox.grid.cells._Widget", dgc._Base, {
+ widgetClass: dijit.form.TextBox,
+ constructor: function(inCell){
+ this.widget = null;
+ if(typeof this.widgetClass == "string"){
+ dojo.deprecated("Passing a string to widgetClass is deprecated", "pass the widget class object instead", "2.0");
+ this.widgetClass = dojo.getObject(this.widgetClass);
+ }
+ },
+ formatEditing: function(inDatum, inRowIndex){
+ this.needFormatNode(inDatum, inRowIndex);
+ return "<div></div>";
+ },
+ getValue: function(inRowIndex){
+ return this.widget.get('value');
+ },
+ setValue: function(inRowIndex, inValue){
+ if(this.widget&&this.widget.set){
+ //Look for lazy-loading editor and handle it via its deferred.
+ if(this.widget.onLoadDeferred){
+ var self = this;
+ this.widget.onLoadDeferred.addCallback(function(){
+ self.widget.set("value",inValue===null?"":inValue);
+ });
+ }else{
+ this.widget.set("value", inValue);
+ }
+ }else{
+ this.inherited(arguments);
+ }
+ },
+ getWidgetProps: function(inDatum){
+ return dojo.mixin(
+ {
+ dir: this.dir,
+ lang: this.lang
+ },
+ this.widgetProps||{},
+ {
+ constraints: dojo.mixin({}, this.constraint) || {}, //TODO: really just for ValidationTextBoxes
+ value: inDatum
+ }
+ );
+ },
+ createWidget: function(inNode, inDatum, inRowIndex){
+ return new this.widgetClass(this.getWidgetProps(inDatum), inNode);
+ },
+ attachWidget: function(inNode, inDatum, inRowIndex){
+ inNode.appendChild(this.widget.domNode);
+ this.setValue(inRowIndex, inDatum);
+ },
+ formatNode: function(inNode, inDatum, inRowIndex){
+ if(!this.widgetClass){
+ return inDatum;
+ }
+ if(!this.widget){
+ this.widget = this.createWidget.apply(this, arguments);
+ }else{
+ this.attachWidget.apply(this, arguments);
+ }
+ this.sizeWidget.apply(this, arguments);
+ this.grid.views.renormalizeRow(inRowIndex);
+ this.grid.scroller.rowHeightChanged(inRowIndex, true/*fix #11101*/);
+ this.focus();
+ return undefined;
+ },
+ sizeWidget: function(inNode, inDatum, inRowIndex){
+ var
+ p = this.getNode(inRowIndex),
+ box = dojo.contentBox(p);
+ dojo.marginBox(this.widget.domNode, {w: box.w});
+ },
+ focus: function(inRowIndex, inNode){
+ if(this.widget){
+ setTimeout(dojo.hitch(this.widget, function(){
+ dojox.grid.util.fire(this, "focus");
+ }), 0);
+ }
+ },
+ _finish: function(inRowIndex){
+ this.inherited(arguments);
+ dojox.grid.util.removeNode(this.widget.domNode);
+ if(dojo.isIE){
+ dojo.setSelectable(this.widget.domNode, true);
+ }
+ }
+ });
+ dgc._Widget.markupFactory = function(node, cell){
+ dgc._Base.markupFactory(node, cell);
+ var d = dojo;
+ var widgetProps = d.trim(d.attr(node, "widgetProps")||"");
+ var constraint = d.trim(d.attr(node, "constraint")||"");
+ var widgetClass = d.trim(d.attr(node, "widgetClass")||"");
+ if(widgetProps){
+ cell.widgetProps = d.fromJson(widgetProps);
+ }
+ if(constraint){
+ cell.constraint = d.fromJson(constraint);
+ }
+ if(widgetClass){
+ cell.widgetClass = d.getObject(widgetClass);
+ }
+ };
+
+ dojo.declare("dojox.grid.cells.ComboBox", dgc._Widget, {
+ widgetClass: dijit.form.ComboBox,
+ getWidgetProps: function(inDatum){
+ var items=[];
+ dojo.forEach(this.options, function(o){
+ items.push({name: o, value: o});
+ });
+ var store = new dojo.data.ItemFileReadStore({data: {identifier:"name", items: items}});
+ return dojo.mixin({}, this.widgetProps||{}, {
+ value: inDatum,
+ store: store
+ });
+ },
+ getValue: function(){
+ var e = this.widget;
+ // make sure to apply the displayed value
+ e.set('displayedValue', e.get('displayedValue'));
+ return e.get('value');
+ }
+ });
+ dgc.ComboBox.markupFactory = function(node, cell){
+ dgc._Widget.markupFactory(node, cell);
+ var d=dojo;
+ var options = d.trim(d.attr(node, "options")||"");
+ if(options){
+ var o = options.split(',');
+ if(o[0] != options){
+ cell.options = o;
+ }
+ }
+ };
+
+ dojo.declare("dojox.grid.cells.DateTextBox", dgc._Widget, {
+ widgetClass: dijit.form.DateTextBox,
+ setValue: function(inRowIndex, inValue){
+ if(this.widget){
+ this.widget.set('value', new Date(inValue));
+ }else{
+ this.inherited(arguments);
+ }
+ },
+ getWidgetProps: function(inDatum){
+ return dojo.mixin(this.inherited(arguments), {
+ value: new Date(inDatum)
+ });
+ }
+ });
+ dgc.DateTextBox.markupFactory = function(node, cell){
+ dgc._Widget.markupFactory(node, cell);
+ };
+
+ dojo.declare("dojox.grid.cells.CheckBox", dgc._Widget, {
+ widgetClass: dijit.form.CheckBox,
+ getValue: function(){
+ return this.widget.checked;
+ },
+ setValue: function(inRowIndex, inValue){
+ if(this.widget&&this.widget.attributeMap.checked){
+ this.widget.set("checked", inValue);
+ }else{
+ this.inherited(arguments);
+ }
+ },
+ sizeWidget: function(inNode, inDatum, inRowIndex){
+ return;
+ }
+ });
+ dgc.CheckBox.markupFactory = function(node, cell){
+ dgc._Widget.markupFactory(node, cell);
+ };
+
+ dojo.declare("dojox.grid.cells.Editor", dgc._Widget, {
+ widgetClass: dijit.Editor,
+ getWidgetProps: function(inDatum){
+ return dojo.mixin({}, this.widgetProps||{}, {
+ height: this.widgetHeight || "100px"
+ });
+ },
+ createWidget: function(inNode, inDatum, inRowIndex){
+ // widget needs its value set after creation
+ var widget = new this.widgetClass(this.getWidgetProps(inDatum), inNode);
+ dojo.connect(widget, 'onLoad', dojo.hitch(this, 'populateEditor'));
+ return widget;
+ },
+ formatNode: function(inNode, inDatum, inRowIndex){
+ this.content = inDatum;
+ this.inherited(arguments);
+ if(dojo.isMoz){
+ // FIXME: seem to need to reopen the editor and display the toolbar
+ var e = this.widget;
+ e.open();
+ if(this.widgetToolbar){
+ dojo.place(e.toolbar.domNode, e.editingArea, "before");
+ }
+ }
+ },
+ populateEditor: function(){
+ this.widget.set('value', this.content);
+ this.widget.placeCursorAtEnd();
+ }
+ });
+ dgc.Editor.markupFactory = function(node, cell){
+ dgc._Widget.markupFactory(node, cell);
+ var d = dojo;
+ var h = dojo.trim(dojo.attr(node, "widgetHeight")||"");
+ if(h){
+ if((h != "auto")&&(h.substr(-2) != "em")){
+ h = parseInt(h, 10)+"px";
+ }
+ cell.widgetHeight = h;
+ }
+ };
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/cells/dijit.xd.js b/js/dojo-1.6/dojox/grid/cells/dijit.xd.js
new file mode 100644
index 0000000..4f3ff2a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/cells/dijit.xd.js
@@ -0,0 +1,265 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.cells.dijit"],
+["require", "dojox.grid.cells"],
+["require", "dijit.form.DateTextBox"],
+["require", "dijit.form.TimeTextBox"],
+["require", "dijit.form.ComboBox"],
+["require", "dojo.data.ItemFileReadStore"],
+["require", "dijit.form.CheckBox"],
+["require", "dijit.form.TextBox"],
+["require", "dijit.form.NumberSpinner"],
+["require", "dijit.form.NumberTextBox"],
+["require", "dijit.form.CurrencyTextBox"],
+["require", "dijit.form.HorizontalSlider"],
+["require", "dijit.Editor"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.cells.dijit"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.cells.dijit"] = true;
+dojo.provide("dojox.grid.cells.dijit");
+
+dojo.require("dojox.grid.cells");
+
+// TODO: shouldn't it be the test file's job to require these modules,
+// if it is using them? Most of these modules aren't referenced by this file.
+
+dojo.require("dijit.form.DateTextBox");
+dojo.require("dijit.form.TimeTextBox");
+dojo.require("dijit.form.ComboBox");
+dojo.require("dojo.data.ItemFileReadStore");
+dojo.require("dijit.form.CheckBox");
+dojo.require("dijit.form.TextBox");
+dojo.require("dijit.form.NumberSpinner");
+dojo.require("dijit.form.NumberTextBox");
+dojo.require("dijit.form.CurrencyTextBox");
+dojo.require("dijit.form.HorizontalSlider");
+dojo.require("dijit.Editor");
+
+(function(){
+ var dgc = dojox.grid.cells;
+ dojo.declare("dojox.grid.cells._Widget", dgc._Base, {
+ widgetClass: dijit.form.TextBox,
+ constructor: function(inCell){
+ this.widget = null;
+ if(typeof this.widgetClass == "string"){
+ dojo.deprecated("Passing a string to widgetClass is deprecated", "pass the widget class object instead", "2.0");
+ this.widgetClass = dojo.getObject(this.widgetClass);
+ }
+ },
+ formatEditing: function(inDatum, inRowIndex){
+ this.needFormatNode(inDatum, inRowIndex);
+ return "<div></div>";
+ },
+ getValue: function(inRowIndex){
+ return this.widget.get('value');
+ },
+ setValue: function(inRowIndex, inValue){
+ if(this.widget&&this.widget.set){
+ //Look for lazy-loading editor and handle it via its deferred.
+ if(this.widget.onLoadDeferred){
+ var self = this;
+ this.widget.onLoadDeferred.addCallback(function(){
+ self.widget.set("value",inValue===null?"":inValue);
+ });
+ }else{
+ this.widget.set("value", inValue);
+ }
+ }else{
+ this.inherited(arguments);
+ }
+ },
+ getWidgetProps: function(inDatum){
+ return dojo.mixin(
+ {
+ dir: this.dir,
+ lang: this.lang
+ },
+ this.widgetProps||{},
+ {
+ constraints: dojo.mixin({}, this.constraint) || {}, //TODO: really just for ValidationTextBoxes
+ value: inDatum
+ }
+ );
+ },
+ createWidget: function(inNode, inDatum, inRowIndex){
+ return new this.widgetClass(this.getWidgetProps(inDatum), inNode);
+ },
+ attachWidget: function(inNode, inDatum, inRowIndex){
+ inNode.appendChild(this.widget.domNode);
+ this.setValue(inRowIndex, inDatum);
+ },
+ formatNode: function(inNode, inDatum, inRowIndex){
+ if(!this.widgetClass){
+ return inDatum;
+ }
+ if(!this.widget){
+ this.widget = this.createWidget.apply(this, arguments);
+ }else{
+ this.attachWidget.apply(this, arguments);
+ }
+ this.sizeWidget.apply(this, arguments);
+ this.grid.views.renormalizeRow(inRowIndex);
+ this.grid.scroller.rowHeightChanged(inRowIndex, true/*fix #11101*/);
+ this.focus();
+ return undefined;
+ },
+ sizeWidget: function(inNode, inDatum, inRowIndex){
+ var
+ p = this.getNode(inRowIndex),
+ box = dojo.contentBox(p);
+ dojo.marginBox(this.widget.domNode, {w: box.w});
+ },
+ focus: function(inRowIndex, inNode){
+ if(this.widget){
+ setTimeout(dojo.hitch(this.widget, function(){
+ dojox.grid.util.fire(this, "focus");
+ }), 0);
+ }
+ },
+ _finish: function(inRowIndex){
+ this.inherited(arguments);
+ dojox.grid.util.removeNode(this.widget.domNode);
+ if(dojo.isIE){
+ dojo.setSelectable(this.widget.domNode, true);
+ }
+ }
+ });
+ dgc._Widget.markupFactory = function(node, cell){
+ dgc._Base.markupFactory(node, cell);
+ var d = dojo;
+ var widgetProps = d.trim(d.attr(node, "widgetProps")||"");
+ var constraint = d.trim(d.attr(node, "constraint")||"");
+ var widgetClass = d.trim(d.attr(node, "widgetClass")||"");
+ if(widgetProps){
+ cell.widgetProps = d.fromJson(widgetProps);
+ }
+ if(constraint){
+ cell.constraint = d.fromJson(constraint);
+ }
+ if(widgetClass){
+ cell.widgetClass = d.getObject(widgetClass);
+ }
+ };
+
+ dojo.declare("dojox.grid.cells.ComboBox", dgc._Widget, {
+ widgetClass: dijit.form.ComboBox,
+ getWidgetProps: function(inDatum){
+ var items=[];
+ dojo.forEach(this.options, function(o){
+ items.push({name: o, value: o});
+ });
+ var store = new dojo.data.ItemFileReadStore({data: {identifier:"name", items: items}});
+ return dojo.mixin({}, this.widgetProps||{}, {
+ value: inDatum,
+ store: store
+ });
+ },
+ getValue: function(){
+ var e = this.widget;
+ // make sure to apply the displayed value
+ e.set('displayedValue', e.get('displayedValue'));
+ return e.get('value');
+ }
+ });
+ dgc.ComboBox.markupFactory = function(node, cell){
+ dgc._Widget.markupFactory(node, cell);
+ var d=dojo;
+ var options = d.trim(d.attr(node, "options")||"");
+ if(options){
+ var o = options.split(',');
+ if(o[0] != options){
+ cell.options = o;
+ }
+ }
+ };
+
+ dojo.declare("dojox.grid.cells.DateTextBox", dgc._Widget, {
+ widgetClass: dijit.form.DateTextBox,
+ setValue: function(inRowIndex, inValue){
+ if(this.widget){
+ this.widget.set('value', new Date(inValue));
+ }else{
+ this.inherited(arguments);
+ }
+ },
+ getWidgetProps: function(inDatum){
+ return dojo.mixin(this.inherited(arguments), {
+ value: new Date(inDatum)
+ });
+ }
+ });
+ dgc.DateTextBox.markupFactory = function(node, cell){
+ dgc._Widget.markupFactory(node, cell);
+ };
+
+ dojo.declare("dojox.grid.cells.CheckBox", dgc._Widget, {
+ widgetClass: dijit.form.CheckBox,
+ getValue: function(){
+ return this.widget.checked;
+ },
+ setValue: function(inRowIndex, inValue){
+ if(this.widget&&this.widget.attributeMap.checked){
+ this.widget.set("checked", inValue);
+ }else{
+ this.inherited(arguments);
+ }
+ },
+ sizeWidget: function(inNode, inDatum, inRowIndex){
+ return;
+ }
+ });
+ dgc.CheckBox.markupFactory = function(node, cell){
+ dgc._Widget.markupFactory(node, cell);
+ };
+
+ dojo.declare("dojox.grid.cells.Editor", dgc._Widget, {
+ widgetClass: dijit.Editor,
+ getWidgetProps: function(inDatum){
+ return dojo.mixin({}, this.widgetProps||{}, {
+ height: this.widgetHeight || "100px"
+ });
+ },
+ createWidget: function(inNode, inDatum, inRowIndex){
+ // widget needs its value set after creation
+ var widget = new this.widgetClass(this.getWidgetProps(inDatum), inNode);
+ dojo.connect(widget, 'onLoad', dojo.hitch(this, 'populateEditor'));
+ return widget;
+ },
+ formatNode: function(inNode, inDatum, inRowIndex){
+ this.content = inDatum;
+ this.inherited(arguments);
+ if(dojo.isMoz){
+ // FIXME: seem to need to reopen the editor and display the toolbar
+ var e = this.widget;
+ e.open();
+ if(this.widgetToolbar){
+ dojo.place(e.toolbar.domNode, e.editingArea, "before");
+ }
+ }
+ },
+ populateEditor: function(){
+ this.widget.set('value', this.content);
+ this.widget.placeCursorAtEnd();
+ }
+ });
+ dgc.Editor.markupFactory = function(node, cell){
+ dgc._Widget.markupFactory(node, cell);
+ var d = dojo;
+ var h = dojo.trim(dojo.attr(node, "widgetHeight")||"");
+ if(h){
+ if((h != "auto")&&(h.substr(-2) != "em")){
+ h = parseInt(h, 10)+"px";
+ }
+ cell.widgetHeight = h;
+ }
+ };
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/cells/tree.js b/js/dojo-1.6/dojox/grid/cells/tree.js
new file mode 100644
index 0000000..35db24e
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/cells/tree.js
@@ -0,0 +1,78 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.cells.tree"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.cells.tree"] = true;
+dojo.provide("dojox.grid.cells.tree");
+
+dojo.require("dojox.grid.cells");
+
+dojox.grid.cells.TreeCell = {
+ formatAggregate: function(inItem, level, inRowIndexes){
+ var f, g=this.grid, i=g.edit.info,
+ d=g.aggregator ? g.aggregator.getForCell(this, level, inItem, level === this.level ? "cnt" : this.parentCell.aggregate) : (this.value || this.defaultValue);
+ return this._defaultFormat(d, [d, level - this.level, inRowIndexes, this]);
+ },
+ formatIndexes: function(inRowIndexes, inItem){
+ var f, g=this.grid, i=g.edit.info,
+ d=this.get ? this.get(inRowIndexes[0], inItem, inRowIndexes) : (this.value || this.defaultValue);
+ if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndexes[0] && i.cell==this))){
+ return this.formatEditing(d, inRowIndexes[0], inRowIndexes);
+ }else{
+ return this._defaultFormat(d, [d, inRowIndexes[0], inRowIndexes, this]);
+ }
+ },
+ getOpenState: function(itemId){
+ var grid = this.grid, store = grid.store, itm = null;
+ if(store.isItem(itemId)){
+ itm = itemId;
+ itemId = store.getIdentity(itemId);
+ }
+ if(!this.openStates){ this.openStates = {}; }
+ if(typeof itemId != "string" || !(itemId in this.openStates)){
+ this.openStates[itemId] = grid.getDefaultOpenState(this, itm);
+ }
+ return this.openStates[itemId];
+ },
+ formatAtLevel: function(inRowIndexes, inItem, level, summaryRow, toggleClass, cellClasses){
+ if(!dojo.isArray(inRowIndexes)){
+ inRowIndexes = [inRowIndexes];
+ }
+ var result = "";
+ if(level > this.level || (level === this.level && summaryRow)){
+ cellClasses.push("dojoxGridSpacerCell");
+ if(level === this.level){
+ cellClasses.push("dojoxGridTotalCell");
+ }
+ result = '<span></span>';
+ }else if(level < this.level){
+ cellClasses.push("dojoxGridSummaryCell");
+ result = '<span class="dojoxGridSummarySpan">' + this.formatAggregate(inItem, level, inRowIndexes) + '</span>';
+ }else{
+ var ret = "";
+ if(this.isCollapsable){
+ var store = this.grid.store, id = "";
+ if(store.isItem(inItem)){
+ id = store.getIdentity(inItem);
+ }
+ cellClasses.push("dojoxGridExpandoCell");
+ ret = '<span dojoType="dojox.grid._Expando" level="' + level + '" class="dojoxGridExpando"' +
+ '" toggleClass="' + toggleClass + '" itemId="' + id + '" cellIdx="' + this.index + '"></span>';
+ }
+ result = ret + this.formatIndexes(inRowIndexes, inItem);
+ }
+
+ if(this.grid.focus.cell && this.index == this.grid.focus.cell.index &&
+ inRowIndexes.join('/') == this.grid.focus.rowIndex){
+ cellClasses.push(this.grid.focus.focusClass);
+ }
+
+ return result;
+ }
+};
+
+}
diff --git a/js/dojo-1.6/dojox/grid/cells/tree.xd.js b/js/dojo-1.6/dojox/grid/cells/tree.xd.js
new file mode 100644
index 0000000..edb4f11
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/cells/tree.xd.js
@@ -0,0 +1,83 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.cells.tree"],
+["require", "dojox.grid.cells"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.cells.tree"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.cells.tree"] = true;
+dojo.provide("dojox.grid.cells.tree");
+
+dojo.require("dojox.grid.cells");
+
+dojox.grid.cells.TreeCell = {
+ formatAggregate: function(inItem, level, inRowIndexes){
+ var f, g=this.grid, i=g.edit.info,
+ d=g.aggregator ? g.aggregator.getForCell(this, level, inItem, level === this.level ? "cnt" : this.parentCell.aggregate) : (this.value || this.defaultValue);
+ return this._defaultFormat(d, [d, level - this.level, inRowIndexes, this]);
+ },
+ formatIndexes: function(inRowIndexes, inItem){
+ var f, g=this.grid, i=g.edit.info,
+ d=this.get ? this.get(inRowIndexes[0], inItem, inRowIndexes) : (this.value || this.defaultValue);
+ if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndexes[0] && i.cell==this))){
+ return this.formatEditing(d, inRowIndexes[0], inRowIndexes);
+ }else{
+ return this._defaultFormat(d, [d, inRowIndexes[0], inRowIndexes, this]);
+ }
+ },
+ getOpenState: function(itemId){
+ var grid = this.grid, store = grid.store, itm = null;
+ if(store.isItem(itemId)){
+ itm = itemId;
+ itemId = store.getIdentity(itemId);
+ }
+ if(!this.openStates){ this.openStates = {}; }
+ if(typeof itemId != "string" || !(itemId in this.openStates)){
+ this.openStates[itemId] = grid.getDefaultOpenState(this, itm);
+ }
+ return this.openStates[itemId];
+ },
+ formatAtLevel: function(inRowIndexes, inItem, level, summaryRow, toggleClass, cellClasses){
+ if(!dojo.isArray(inRowIndexes)){
+ inRowIndexes = [inRowIndexes];
+ }
+ var result = "";
+ if(level > this.level || (level === this.level && summaryRow)){
+ cellClasses.push("dojoxGridSpacerCell");
+ if(level === this.level){
+ cellClasses.push("dojoxGridTotalCell");
+ }
+ result = '<span></span>';
+ }else if(level < this.level){
+ cellClasses.push("dojoxGridSummaryCell");
+ result = '<span class="dojoxGridSummarySpan">' + this.formatAggregate(inItem, level, inRowIndexes) + '</span>';
+ }else{
+ var ret = "";
+ if(this.isCollapsable){
+ var store = this.grid.store, id = "";
+ if(store.isItem(inItem)){
+ id = store.getIdentity(inItem);
+ }
+ cellClasses.push("dojoxGridExpandoCell");
+ ret = '<span dojoType="dojox.grid._Expando" level="' + level + '" class="dojoxGridExpando"' +
+ '" toggleClass="' + toggleClass + '" itemId="' + id + '" cellIdx="' + this.index + '"></span>';
+ }
+ result = ret + this.formatIndexes(inRowIndexes, inItem);
+ }
+
+ if(this.grid.focus.cell && this.index == this.grid.focus.cell.index &&
+ inRowIndexes.join('/') == this.grid.focus.rowIndex){
+ cellClasses.push(this.grid.focus.focusClass);
+ }
+
+ return result;
+ }
+};
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/compatGrid.tar.gz b/js/dojo-1.6/dojox/grid/compatGrid.tar.gz
new file mode 100644
index 0000000..87c39c8
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/compatGrid.tar.gz
Binary files differ
diff --git a/js/dojo-1.6/dojox/grid/enhanced/_Events.js b/js/dojo-1.6/dojox/grid/enhanced/_Events.js
new file mode 100644
index 0000000..fb81ccc
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/_Events.js
@@ -0,0 +1,223 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced._Events"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced._Events"] = true;
+dojo.provide("dojox.grid.enhanced._Events");
+
+dojo.declare("dojox.grid.enhanced._Events", null, {
+ // summary:
+ // Overwrite some default events of DataGrid
+ //
+ // description:
+ // Methods are copied or replaced for overwriting, this might be refined once
+ // an overall plugin architecture is set up for DataGrid.
+
+ //_events: Object
+ // Method map cached from dojox.grid._Events().
+ _events: null,
+
+ // headerCellActiveClass: String
+ // css class to apply to grid header cells when activated(mouse down)
+ headerCellActiveClass: 'dojoxGridHeaderActive',
+
+ // cellActiveClass: String
+ // css class to apply to grid content cells when activated(mouse down)
+ cellActiveClass: 'dojoxGridCellActive',
+
+ // rowActiveClass: String
+ // css class to apply to grid rows when activated(mouse down)
+ rowActiveClass: 'dojoxGridRowActive',
+
+ constructor: function(inGrid){
+ //get the default Grid events
+ this._events = new dojox.grid._Events();
+ //for methods that won't be overwritten, copy them to "this" scope
+ for(var p in this._events){
+ if(!this[p]){
+ this.p = this._events.p;
+ }
+ }
+ //mixin "this" to Grid
+ inGrid.mixin(inGrid, this);
+ },
+ dokeyup: function(e){
+ // summary:
+ // Grid key up event handler.
+ // e: Event
+ // Un-decorated event object
+ this.focus.currentArea().keyup(e);
+ },
+ onKeyDown: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onKeyDown();
+ if(e.altKey || e.metaKey){ return; }
+ var dk = dojo.keys;
+ var focus = this.focus;
+ switch(e.keyCode){
+ case dk.TAB:
+ if(e.ctrlKey){ return; }
+ focus.tab(e.shiftKey ? -1:1,e);
+ break;
+ case dk.UP_ARROW:
+ case dk.DOWN_ARROW:
+ focus.currentArea().move(e.keyCode == dk.UP_ARROW ? -1 : 1, 0, e);
+ break;
+ case dk.LEFT_ARROW:
+ case dk.RIGHT_ARROW:
+ var offset = (e.keyCode == dk.LEFT_ARROW) ? 1 : -1;
+ if(dojo._isBodyLtr()){ offset *= -1; }
+ focus.currentArea().move(0, offset, e);
+ break;
+ case dk.F10:
+ if(this.menus && e.shiftKey){
+ this.onRowContextMenu(e);
+ }
+ break;
+ default:
+ focus.currentArea().keydown(e);
+ break;
+ }
+ },
+ //TODO - make the following events more reasonalble - e.g. more accurate conditions
+ //events for row selectors
+ domouseup: function(e){
+ if(e.cellNode){
+ this.onMouseUp(e);
+ }else{
+ this.onRowSelectorMouseUp(e);
+ }
+ },
+ domousedown: function(e){
+ if(!e.cellNode){
+ this.onRowSelectorMouseDown(e);
+ }
+ },
+ onMouseUp: function(e){
+ // summary:
+ // New - Event fired when mouse is up inside grid.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ this[e.rowIndex == -1 ? "onHeaderCellMouseUp" : "onCellMouseUp"](e);
+ },
+ onCellMouseDown: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onCellMouseDown()
+ dojo.addClass(e.cellNode, this.cellActiveClass);
+ dojo.addClass(e.rowNode, this.rowActiveClass);
+ },
+ onCellMouseUp: function(e){
+ // summary:
+ // New - Event fired when mouse is up inside content cell.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ dojo.removeClass(e.cellNode, this.cellActiveClass);
+ dojo.removeClass(e.rowNode, this.rowActiveClass);
+ },
+ onCellClick: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onCellClick()
+
+ //invoke dojox.grid._Events.onCellClick()
+ this._events.onCellClick.call(this, e);
+ //move mouse events to the focus manager.
+ this.focus.contentMouseEvent(e);//TODO
+ },
+ onCellDblClick: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onCellDblClick()
+ if(this.pluginMgr.isFixedCell(e.cell)){ return; }
+ if(this._click.length > 1 && (!this._click[0] || !this._click[1])){
+ this._click[0] = this._click[1] = e;
+ }
+ //invoke dojox.grid._Events.onCellDblClick()
+ this._events.onCellDblClick.call(this, e);
+ //now focus.setFocusCell need isEditing info, so call it after that is set.
+ this.focus.setFocusCell(e.cell, e.rowIndex);
+ },
+ onRowClick: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onRowClick()
+ this.edit.rowClick(e);
+ if(e.cell && !e.cell.isRowSelector && (!this.rowSelectCell || !this.rowSelectCell.disabled(e.rowIndex))){
+ this.selection.clickSelectEvent(e);
+ }
+ },
+ onRowContextMenu: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onRowContextMenu()
+ if(!this.edit.isEditing() && this.menus){
+ this.showMenu(e);
+ }
+ },
+ onSelectedRegionContextMenu: function(e){
+ // summary:
+ // New - Event fired when a selected region context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid and info of selected
+ // regions(selection type - row|column, selected index - [...])
+ if(this.selectedRegionMenu){
+ this.selectedRegionMenu._openMyself({
+ target: e.target,
+ coords: e.keyCode !== dojo.keys.F10 && "pageX" in e ? {
+ x: e.pageX,
+ y: e.pageY
+ } : null
+ });
+ dojo.stopEvent(e);
+ }
+ },
+ onHeaderCellMouseOut: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onHeaderCellMouseOut()
+ if(e.cellNode){
+ dojo.removeClass(e.cellNode, this.cellOverClass);
+ dojo.removeClass(e.cellNode, this.headerCellActiveClass);
+ }
+ },
+ onHeaderCellMouseDown: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onHeaderCellMouseDown()
+ if(e.cellNode){//TBD - apply to selection region for nested sorting?
+ dojo.addClass(e.cellNode, this.headerCellActiveClass);
+ }
+ },
+ onHeaderCellMouseUp: function(e){
+ // summary:
+ // New event
+ if(e.cellNode){
+ dojo.removeClass(e.cellNode, this.headerCellActiveClass);
+ }
+ },
+ onHeaderCellClick: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onHeaderCellClick()
+ //move focus to header.
+ this.focus.currentArea("header");
+ //invoke dojox.grid._Events.onHeaderCellClick()
+ if(!e.cell.isRowSelector){
+ this._events.onHeaderCellClick.call(this, e);
+ }
+ //move mouse events to the focus manager.
+ this.focus.headerMouseEvent(e);
+ },
+ onRowSelectorMouseDown: function(e){
+ this.focus.focusArea("rowHeader", e);
+ },
+
+ onRowSelectorMouseUp: function(e){},
+
+ //triggered in _View, see Selector plugin
+ onMouseUpRow: function(e){
+ if(e.rowIndex != -1){
+ this.onRowMouseUp(e);
+ }
+ },
+ onRowMouseUp: function(e){}
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/_Events.xd.js b/js/dojo-1.6/dojox/grid/enhanced/_Events.xd.js
new file mode 100644
index 0000000..3470f54
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/_Events.xd.js
@@ -0,0 +1,227 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced._Events"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced._Events"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced._Events"] = true;
+dojo.provide("dojox.grid.enhanced._Events");
+
+dojo.declare("dojox.grid.enhanced._Events", null, {
+ // summary:
+ // Overwrite some default events of DataGrid
+ //
+ // description:
+ // Methods are copied or replaced for overwriting, this might be refined once
+ // an overall plugin architecture is set up for DataGrid.
+
+ //_events: Object
+ // Method map cached from dojox.grid._Events().
+ _events: null,
+
+ // headerCellActiveClass: String
+ // css class to apply to grid header cells when activated(mouse down)
+ headerCellActiveClass: 'dojoxGridHeaderActive',
+
+ // cellActiveClass: String
+ // css class to apply to grid content cells when activated(mouse down)
+ cellActiveClass: 'dojoxGridCellActive',
+
+ // rowActiveClass: String
+ // css class to apply to grid rows when activated(mouse down)
+ rowActiveClass: 'dojoxGridRowActive',
+
+ constructor: function(inGrid){
+ //get the default Grid events
+ this._events = new dojox.grid._Events();
+ //for methods that won't be overwritten, copy them to "this" scope
+ for(var p in this._events){
+ if(!this[p]){
+ this.p = this._events.p;
+ }
+ }
+ //mixin "this" to Grid
+ inGrid.mixin(inGrid, this);
+ },
+ dokeyup: function(e){
+ // summary:
+ // Grid key up event handler.
+ // e: Event
+ // Un-decorated event object
+ this.focus.currentArea().keyup(e);
+ },
+ onKeyDown: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onKeyDown();
+ if(e.altKey || e.metaKey){ return; }
+ var dk = dojo.keys;
+ var focus = this.focus;
+ switch(e.keyCode){
+ case dk.TAB:
+ if(e.ctrlKey){ return; }
+ focus.tab(e.shiftKey ? -1:1,e);
+ break;
+ case dk.UP_ARROW:
+ case dk.DOWN_ARROW:
+ focus.currentArea().move(e.keyCode == dk.UP_ARROW ? -1 : 1, 0, e);
+ break;
+ case dk.LEFT_ARROW:
+ case dk.RIGHT_ARROW:
+ var offset = (e.keyCode == dk.LEFT_ARROW) ? 1 : -1;
+ if(dojo._isBodyLtr()){ offset *= -1; }
+ focus.currentArea().move(0, offset, e);
+ break;
+ case dk.F10:
+ if(this.menus && e.shiftKey){
+ this.onRowContextMenu(e);
+ }
+ break;
+ default:
+ focus.currentArea().keydown(e);
+ break;
+ }
+ },
+ //TODO - make the following events more reasonalble - e.g. more accurate conditions
+ //events for row selectors
+ domouseup: function(e){
+ if(e.cellNode){
+ this.onMouseUp(e);
+ }else{
+ this.onRowSelectorMouseUp(e);
+ }
+ },
+ domousedown: function(e){
+ if(!e.cellNode){
+ this.onRowSelectorMouseDown(e);
+ }
+ },
+ onMouseUp: function(e){
+ // summary:
+ // New - Event fired when mouse is up inside grid.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ this[e.rowIndex == -1 ? "onHeaderCellMouseUp" : "onCellMouseUp"](e);
+ },
+ onCellMouseDown: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onCellMouseDown()
+ dojo.addClass(e.cellNode, this.cellActiveClass);
+ dojo.addClass(e.rowNode, this.rowActiveClass);
+ },
+ onCellMouseUp: function(e){
+ // summary:
+ // New - Event fired when mouse is up inside content cell.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ dojo.removeClass(e.cellNode, this.cellActiveClass);
+ dojo.removeClass(e.rowNode, this.rowActiveClass);
+ },
+ onCellClick: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onCellClick()
+
+ //invoke dojox.grid._Events.onCellClick()
+ this._events.onCellClick.call(this, e);
+ //move mouse events to the focus manager.
+ this.focus.contentMouseEvent(e);//TODO
+ },
+ onCellDblClick: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onCellDblClick()
+ if(this.pluginMgr.isFixedCell(e.cell)){ return; }
+ if(this._click.length > 1 && (!this._click[0] || !this._click[1])){
+ this._click[0] = this._click[1] = e;
+ }
+ //invoke dojox.grid._Events.onCellDblClick()
+ this._events.onCellDblClick.call(this, e);
+ //now focus.setFocusCell need isEditing info, so call it after that is set.
+ this.focus.setFocusCell(e.cell, e.rowIndex);
+ },
+ onRowClick: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onRowClick()
+ this.edit.rowClick(e);
+ if(e.cell && !e.cell.isRowSelector && (!this.rowSelectCell || !this.rowSelectCell.disabled(e.rowIndex))){
+ this.selection.clickSelectEvent(e);
+ }
+ },
+ onRowContextMenu: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onRowContextMenu()
+ if(!this.edit.isEditing() && this.menus){
+ this.showMenu(e);
+ }
+ },
+ onSelectedRegionContextMenu: function(e){
+ // summary:
+ // New - Event fired when a selected region context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid and info of selected
+ // regions(selection type - row|column, selected index - [...])
+ if(this.selectedRegionMenu){
+ this.selectedRegionMenu._openMyself({
+ target: e.target,
+ coords: e.keyCode !== dojo.keys.F10 && "pageX" in e ? {
+ x: e.pageX,
+ y: e.pageY
+ } : null
+ });
+ dojo.stopEvent(e);
+ }
+ },
+ onHeaderCellMouseOut: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onHeaderCellMouseOut()
+ if(e.cellNode){
+ dojo.removeClass(e.cellNode, this.cellOverClass);
+ dojo.removeClass(e.cellNode, this.headerCellActiveClass);
+ }
+ },
+ onHeaderCellMouseDown: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onHeaderCellMouseDown()
+ if(e.cellNode){//TBD - apply to selection region for nested sorting?
+ dojo.addClass(e.cellNode, this.headerCellActiveClass);
+ }
+ },
+ onHeaderCellMouseUp: function(e){
+ // summary:
+ // New event
+ if(e.cellNode){
+ dojo.removeClass(e.cellNode, this.headerCellActiveClass);
+ }
+ },
+ onHeaderCellClick: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onHeaderCellClick()
+ //move focus to header.
+ this.focus.currentArea("header");
+ //invoke dojox.grid._Events.onHeaderCellClick()
+ if(!e.cell.isRowSelector){
+ this._events.onHeaderCellClick.call(this, e);
+ }
+ //move mouse events to the focus manager.
+ this.focus.headerMouseEvent(e);
+ },
+ onRowSelectorMouseDown: function(e){
+ this.focus.focusArea("rowHeader", e);
+ },
+
+ onRowSelectorMouseUp: function(e){},
+
+ //triggered in _View, see Selector plugin
+ onMouseUpRow: function(e){
+ if(e.rowIndex != -1){
+ this.onRowMouseUp(e);
+ }
+ },
+ onRowMouseUp: function(e){}
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/_FocusManager.js b/js/dojo-1.6/dojox/grid/enhanced/_FocusManager.js
new file mode 100644
index 0000000..0d1cd2e
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/_FocusManager.js
@@ -0,0 +1,784 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced._FocusManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced._FocusManager"] = true;
+dojo.provide("dojox.grid.enhanced._FocusManager");
+
+dojo.declare("dojox.grid.enhanced._FocusArea",null,{
+ // summary:
+ // This is a friend class of _FocusManager
+/*=====
+ // name: string
+ // Name of this area.
+ name: "",
+
+ // onFocus: function(event, step)
+ // Called when this area logically gets focus.
+ // event: Event object
+ // May be unavailable, should check before use.
+ // step: Integer
+ // The distance in the tab sequence from last focused area to this area.
+ // returns:
+ // whether this area is successfully focused. If not, the next area will get focus.
+ onFocus: function(event, step){return true;},
+
+ // onBlur: function(event, step)
+ // Called when this area logically loses focus.
+ // event: Event object
+ // May be unavailable, should check before use.
+ // step: Integer
+ // The distance in the tab sequence from this area to the area to focus.
+ // returns:
+ // If Boolean, means whether this area has successfully blurred. If not, the next area to focus is still this one.
+ // If String, means the next area to focus is given by this returned name.
+ onBlur: function(event, step){return true;},
+
+ // onMove: function(rowStep, colStep, event)
+ // Called when focus is moving around within this area.
+ // rowStep: Integer
+ // colStep: Integer
+ // event: Event object
+ // May be unavailable, should check before use.
+ onMove: function(rowStep, colStep, event){},
+
+ // onKey: function(event, isBubble)
+ // Called when some key is pressed when focus is logically in this area.
+ // event: Event object
+ // isBubble: Boolean
+ // Whether is in bubble stage (true) or catch stage (false).
+ // returns:
+ // If you do NOT want the event to propagate any further along the area stack, return exactly false.
+ // So if you return nothing (undefined), this event is still propagating.
+ onKey: function(event, isBubble){return true},
+
+ // getRegions: function()
+ // Define the small regions (dom nodes) in this area.
+ // returns: Array of dom nodes.
+ getRegions: function(){},
+
+ // onRegionFocus: function(event)
+ // Connected to the onfocus event of the defined regions (if any)
+ onRegionFocus: function(event){},
+
+ // onRegionBlur: function(event)
+ // Connected to the onblur event of the defined regions (if any)
+ onRegionBlur: function(event){},
+=====*/
+ constructor: function(area, focusManager){
+ this._fm = focusManager;
+ this._evtStack = [area.name];
+ var dummy = function(){return true;};
+ area.onFocus = area.onFocus || dummy;
+ area.onBlur = area.onBlur || dummy;
+ area.onMove = area.onMove || dummy;
+ area.onKeyUp = area.onKeyUp || dummy;
+ area.onKeyDown = area.onKeyDown || dummy;
+ dojo.mixin(this, area);
+ },
+ move: function(rowStep, colStep, evt){
+ if(this.name){
+ var i, len = this._evtStack.length;
+ for(i = len - 1; i >= 0; --i){
+ if(this._fm._areas[this._evtStack[i]].onMove(rowStep, colStep, evt) === false){
+ return false;
+ }
+ }
+ }
+ return true;
+ },
+ _onKeyEvent: function(evt, funcName){
+ if(this.name){
+ var i, len = this._evtStack.length;
+ for(i = len - 1; i >= 0; --i){
+ if(this._fm._areas[this._evtStack[i]][funcName](evt, false) === false){
+ return false;
+ }
+ }
+ for(i = 0; i < len; ++i){
+ if(this._fm._areas[this._evtStack[i]][funcName](evt, true) === false){
+ return false;
+ }
+ }
+ }
+ return true;
+ },
+ keydown: function(evt){
+ return this._onKeyEvent(evt, "onKeyDown");
+ },
+ keyup: function(evt){
+ return this._onKeyEvent(evt, "onKeyUp");
+ },
+ contentMouseEventPlanner: function(){
+ return 0;
+ },
+ headerMouseEventPlanner: function(){
+ return 0;
+ }
+});
+dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
+ _stopEvent: function(evt){
+ try{
+ if(evt && evt.preventDefault){
+ dojo.stopEvent(evt);
+ }
+ }catch(e){}
+ },
+
+ constructor: function(grid){
+ this.grid = grid;
+ this._areas = {};
+ this._areaQueue = [];
+ this._contentMouseEventHandlers = [];
+ this._headerMouseEventHandlers = [];
+ this._currentAreaIdx = -1;
+ this._gridBlured = true;
+ this._connects.push(dojo.connect(grid, "onBlur", this, "_doBlur"));
+
+ this.addArea({
+ name: "header",
+ onFocus: dojo.hitch(this, this.focusHeader),
+ onBlur: dojo.hitch(this, this._blurHeader),
+ onMove: dojo.hitch(this, this._navHeader),
+ getRegions: dojo.hitch(this, this._findHeaderCells),
+ onRegionFocus: dojo.hitch(this, this.doColHeaderFocus),
+ onRegionBlur: dojo.hitch(this, this.doColHeaderBlur),
+ onKeyDown: dojo.hitch(this, this._onHeaderKeyDown)
+ });
+ this.addArea({
+ name: "content",
+ onFocus: dojo.hitch(this, this._focusContent),
+ onBlur: dojo.hitch(this, this._blurContent),
+ onMove: dojo.hitch(this, this._navContent),
+ onKeyDown: dojo.hitch(this, this._onContentKeyDown)
+ });
+ this.addArea({
+ name: "editableCell",
+ onFocus: dojo.hitch(this, this._focusEditableCell),
+ onBlur: dojo.hitch(this, this._blurEditableCell),
+ onKeyDown: dojo.hitch(this, this._onEditableCellKeyDown),
+ onContentMouseEvent: dojo.hitch(this, this._onEditableCellMouseEvent),
+ contentMouseEventPlanner: function(evt, areas){ return -1; }
+ });
+ this.placeArea("header");
+ this.placeArea("content");
+ this.placeArea("editableCell");
+ this.placeArea("editableCell","above","content");
+ },
+ destroy: function(){
+ for(var name in this._areas){
+ var area = this._areas[name];
+ dojo.forEach(area._connects, dojo.disconnect);
+ area._connects = null;
+ if(area.uninitialize){
+ area.uninitialize();
+ }
+ }
+ this.inherited(arguments);
+ },
+ addArea: function(area){
+ if(area.name && dojo.isString(area.name)){
+ if(this._areas[area.name]){
+ //Just replace the original area, instead of remove it, so the position does not change.
+ dojo.forEach(area._connects, dojo.disconnect);
+ }
+ this._areas[area.name] = new dojox.grid.enhanced._FocusArea(area, this);
+ if(area.onHeaderMouseEvent){
+ this._headerMouseEventHandlers.push(area.name);
+ }
+ if(area.onContentMouseEvent){
+ this._contentMouseEventHandlers.push(area.name);
+ }
+ }
+ },
+ getArea: function(areaName){
+ return this._areas[areaName];
+ },
+ _bindAreaEvents: function(){
+ var area, hdl, areas = this._areas;
+ dojo.forEach(this._areaQueue, function(name){
+ area = areas[name];
+ if(!area._initialized && dojo.isFunction(area.initialize)){
+ area.initialize();
+ area._initialized = true;
+ }
+ if(area.getRegions){
+ area._regions = area.getRegions() || [];
+ dojo.forEach(area._connects || [], dojo.disconnect);
+ area._connects = [];
+ dojo.forEach(area._regions, function(r){
+ if(area.onRegionFocus){
+ hdl = dojo.connect(r, "onfocus", area.onRegionFocus);
+ area._connects.push(hdl);
+ }
+ if(area.onRegionBlur){
+ hdl = dojo.connect(r, "onblur", area.onRegionBlur);
+ area._connects.push(hdl);
+ }
+ });
+ }
+ });
+ },
+ removeArea: function(areaName){
+ var area = this._areas[areaName];
+ if(area){
+ this.ignoreArea(areaName);
+ var i = dojo.indexOf(this._contentMouseEventHandlers, areaName);
+ if(i >= 0){
+ this._contentMouseEventHandlers.splice(i, 1);
+ }
+ i = dojo.indexOf(this._headerMouseEventHandlers, areaName);
+ if(i >= 0){
+ this._headerMouseEventHandlers.splice(i, 1);
+ }
+ dojo.forEach(area._connects, dojo.disconnect);
+ if(area.uninitialize){
+ area.uninitialize();
+ }
+ delete this._areas[areaName];
+ }
+ },
+ currentArea: function(areaName, toBlurOld){
+ // summary:
+ // Set current area to the one areaName refers.
+ // areaName: String
+ var idx, cai = this._currentAreaIdx;
+ if(dojo.isString(areaName) && (idx = dojo.indexOf(this._areaQueue, areaName)) >= 0){
+ if(cai != idx){
+ this.tabbingOut = false;
+ if(toBlurOld && cai >= 0 && cai < this._areaQueue.length){
+ this._areas[this._areaQueue[cai]].onBlur();
+ }
+ this._currentAreaIdx = idx;
+ }
+ }else{
+ return (cai < 0 || cai >= this._areaQueue.length) ?
+ new dojox.grid.enhanced._FocusArea({}, this) :
+ this._areas[this._areaQueue[this._currentAreaIdx]];
+ }
+ return null;
+ },
+ placeArea: function(name, pos, otherAreaName){
+ // summary:
+ // Place the area refered by *name* at some logical position relative to an existing area.
+ // example:
+ // placeArea("myarea","before"|"after",...)
+ // placeArea("myarea","below"|"above",...)
+ if(!this._areas[name]){ return; }
+ var idx = dojo.indexOf(this._areaQueue,otherAreaName);
+ switch(pos){
+ case "after":
+ if(idx >= 0){ ++idx; }
+ //intentional drop through
+ case "before":
+ if(idx >= 0){
+ this._areaQueue.splice(idx,0,name);
+ break;
+ }
+ //intentional drop through
+ default:
+ this._areaQueue.push(name);
+ break;
+ case "above":
+ var isAbove = true;
+ //intentional drop through
+ case "below":
+ var otherArea = this._areas[otherAreaName];
+ if(otherArea){
+ if(isAbove){
+ otherArea._evtStack.push(name);
+ }else{
+ otherArea._evtStack.splice(0,0,name);
+ }
+ }
+ }
+ },
+ ignoreArea: function(name){
+ this._areaQueue = dojo.filter(this._areaQueue,function(areaName){
+ return areaName != name;
+ });
+ },
+ focusArea: function(/* int|string|areaObj */areaId,evt){
+ var idx;
+ if(typeof areaId == "number"){
+ idx = areaId < 0 ? this._areaQueue.length + areaId : areaId;
+ }else{
+ idx = dojo.indexOf(this._areaQueue,
+ dojo.isString(areaId) ? areaId : (areaId && areaId.name));
+ }
+ if(idx < 0){ idx = 0; }
+ var step = idx - this._currentAreaIdx;
+ this._gridBlured = false;
+ if(step){
+ this.tab(step, evt);
+ }else{
+ this.currentArea().onFocus(evt, step);
+ }
+ },
+ tab: function(step,evt){
+ //console.log("===========tab",step,"curArea",this._currentAreaIdx,"areaCnt",this._areaQueue.length);
+ this._gridBlured = false;
+ this.tabbingOut = false;
+ if(step === 0){
+ return;
+ }
+ var cai = this._currentAreaIdx;
+ var dir = step > 0 ? 1:-1;
+ if(cai < 0 || cai >= this._areaQueue.length){
+ cai = (this._currentAreaIdx += step);
+ }else{
+ var nextArea = this._areas[this._areaQueue[cai]].onBlur(evt,step);
+ if(nextArea === true){
+ cai = (this._currentAreaIdx += step);
+ }else if(dojo.isString(nextArea) && this._areas[nextArea]){
+ cai = this._currentAreaIdx = dojo.indexOf(this._areaQueue,nextArea);
+ }
+ }
+ //console.log("target area:",cai);
+ for(; cai >= 0 && cai < this._areaQueue.length; cai += dir){
+ this._currentAreaIdx = cai;
+ if(this._areaQueue[cai] && this._areas[this._areaQueue[cai]].onFocus(evt,step)){
+ //console.log("final target area:",this._currentAreaIdx);
+ return;
+ }
+ }
+ //console.log("tab out");
+ this.tabbingOut = true;
+ if(step < 0){
+ this._currentAreaIdx = -1;
+ dijit.focus(this.grid.domNode);
+ }else{
+ this._currentAreaIdx = this._areaQueue.length;
+ dijit.focus(this.grid.lastFocusNode);
+ }
+ },
+ _onMouseEvent: function(type, evt){
+ var lowercase = type.toLowerCase(),
+ handlers = this["_" + lowercase + "MouseEventHandlers"],
+ res = dojo.map(handlers, function(areaName){
+ return {
+ "area": areaName,
+ "idx": this._areas[areaName][lowercase + "MouseEventPlanner"](evt, handlers)
+ };
+ }, this).sort(function(a, b){
+ return b.idx - a.idx;
+ }),
+ resHandlers = dojo.map(res, function(handler){
+ return res.area;
+ }),
+ i = res.length;
+ while(--i >= 0){
+ if(this._areas[res[i].area]["on" + type + "MouseEvent"](evt, resHandlers) === false){
+ return;
+ }
+ }
+ },
+ contentMouseEvent: function(evt){
+ this._onMouseEvent("Content", evt);
+ },
+ headerMouseEvent: function(evt){
+ this._onMouseEvent("Header", evt);
+ },
+ initFocusView: function(){
+ // summary:
+ // Overwritten
+ this.focusView = this.grid.views.getFirstScrollingView() || this.focusView || this.grid.views.views[0];
+ this._bindAreaEvents();
+ },
+ isNavHeader: function(){
+ // summary:
+ // Overwritten
+ // Check whether currently navigating among column headers.
+ // return:
+ // true - focus is on a certain column header | false otherwise
+ return this._areaQueue[this._currentAreaIdx] == "header";
+ },
+ previousKey: function(e){
+ // summary:
+ // Overwritten
+ this.tab(-1,e);
+ },
+ nextKey: function(e){
+ // summary:
+ // Overwritten
+ this.tab(1,e);
+ },
+ setFocusCell: function(/* Object */inCell, /* Integer */inRowIndex){
+ // summary:
+ // Overwritten - focuses the given grid cell
+ if(inCell){
+ this.currentArea(this.grid.edit.isEditing() ? "editableCell" : "content", true);
+ //This is very slow when selecting cells!
+ //this.focusGridView();
+ this._focusifyCellNode(false);
+ this.cell = inCell;
+ this.rowIndex = inRowIndex;
+ this._focusifyCellNode(true);
+ }
+ this.grid.onCellFocus(this.cell, this.rowIndex);
+ },
+ doFocus: function(e){
+ // summary:
+ // Overwritten
+ // trap focus only for grid dom node
+ // do not focus for scrolling if grid is about to blur
+ if(e && e.target == e.currentTarget && !this.tabbingOut){
+ if(this._gridBlured){
+ this._gridBlured = false;
+ if(this._currentAreaIdx < 0 || this._currentAreaIdx >= this._areaQueue.length){
+ this.focusArea(0, e);
+ }else{
+ this.focusArea(this._currentAreaIdx, e);
+ }
+ }
+ }else{
+ this.tabbingOut = false;
+ }
+ dojo.stopEvent(e);
+ },
+ _doBlur: function(){
+ this._gridBlured = true;
+ },
+ doLastNodeFocus: function(e){
+ // summary:
+ // Overwritten
+ if(this.tabbingOut){
+ this.tabbingOut = false;
+ }else{
+ this.focusArea(-1, e);
+ }
+ },
+ _delayedHeaderFocus: function(){
+ // summary:
+ // Overwritten
+ if(this.isNavHeader()){
+ this.focusHeader();
+ }
+ },
+ _delayedCellFocus: function(){
+ // summary:
+ // Overwritten
+ if(this.currentArea().name == "content"){
+ this.focusArea(this._currentAreaIdx);
+ }
+ },
+ _changeMenuBindNode: function(oldBindNode, newBindNode){
+ var hm = this.grid.headerMenu;
+ if(hm && this._contextMenuBindNode == oldBindNode){
+ hm.unBindDomNode(oldBindNode);
+ hm.bindDomNode(newBindNode);
+ this._contextMenuBindNode = newBindNode;
+ }
+ },
+ //---------------Header Area------------------------------------------
+ focusHeader: function(evt, step){ //need a further look why these changes to parent's
+ // summary:
+ // Overwritten
+ var didFocus = false;
+ this.inherited(arguments);
+ if(this._colHeadNode && dojo.style(this._colHeadNode, 'display') != "none"){
+ dijit.focus(this._colHeadNode);
+ this._stopEvent(evt);
+ didFocus = true;
+ }
+ return didFocus;
+ },
+ _blurHeader: function(evt,step){
+ // summary:
+ // Overwritten
+ if(this._colHeadNode){
+ dojo.removeClass(this._colHeadNode, this.focusClass);
+ }
+ dojo.removeAttr(this.grid.domNode,"aria-activedescendant");
+ // reset contextMenu onto viewsHeaderNode so right mouse on header will invoke (see focusHeader)
+ this._changeMenuBindNode(this.grid.domNode,this.grid.viewsHeaderNode);
+ //moved here from nextKey
+ this._colHeadNode = this._colHeadFocusIdx = null;
+ return true;
+ },
+ _navHeader: function(rowStep, colStep, evt){
+ var colDir = colStep < 0 ? -1 : 1,
+ savedIdx = dojo.indexOf(this._findHeaderCells(), this._colHeadNode);
+ if(savedIdx >= 0 && (evt.shiftKey && evt.ctrlKey)){
+ this.colSizeAdjust(evt, savedIdx, colDir * 5);
+ return;
+ }
+ this.move(rowStep, colStep);
+ },
+ _onHeaderKeyDown: function(e, isBubble){
+ if(isBubble){
+ var dk = dojo.keys;
+ switch(e.keyCode){
+ case dk.ENTER:
+ case dk.SPACE:
+ var colIdx = this.getHeaderIndex();
+ if(colIdx >= 0 && !this.grid.pluginMgr.isFixedCell(e.cell)/*TODO*/){
+ this.grid.setSortIndex(colIdx, null, e);
+ dojo.stopEvent(e);
+ }
+ break;
+ }
+ }
+ return true;
+ },
+ _setActiveColHeader: function(){
+ // summary:
+ // Overwritten
+ this.inherited(arguments);
+ //EDG now will decorate event on header key events, if no focus, the cell will be wrong
+ dijit.focus(this._colHeadNode);
+ },
+ //---------------Content Area------------------------------------------
+ findAndFocusGridCell: function(){
+ // summary:
+ // Overwritten
+ this._focusContent();
+ },
+ _focusContent: function(evt,step){
+ var didFocus = true;
+ var isEmpty = (this.grid.rowCount === 0); // If grid is empty this.grid.rowCount == 0
+ if(this.isNoFocusCell() && !isEmpty){
+ //skip all the hidden cells
+ for(var i = 0, cell = this.grid.getCell(0); cell && cell.hidden; cell = this.grid.getCell(++i)){}
+ this.setFocusIndex(0, cell ? i : 0);
+ }else if(this.cell && !isEmpty){
+ if(this.focusView && !this.focusView.rowNodes[this.rowIndex]){
+ // if rowNode for current index is undefined (likely as a result of a sort and because of #7304)
+ // scroll to that row
+ this.grid.scrollToRow(this.rowIndex);
+ this.focusGrid();
+ }else{
+ this.setFocusIndex(this.rowIndex, this.cell.index);
+ }
+ }else{
+ didFocus = false;
+ }
+ if(didFocus){ this._stopEvent(evt); }
+ return didFocus;
+ },
+ _blurContent: function(evt,step){
+ this._focusifyCellNode(false);
+ return true;
+ },
+ _navContent: function(rowStep, colStep, evt){
+ if((this.rowIndex === 0 && rowStep < 0) || (this.rowIndex === this.grid.rowCount - 1 && rowStep > 0)){
+ return;
+ }
+ this._colHeadNode = null;
+ this.move(rowStep, colStep, evt);
+ if(evt){
+ dojo.stopEvent(evt);
+ }
+ },
+ move: function(inRowDelta, inColDelta){
+ // summary:
+ // Overwritten
+ this.inherited(arguments);
+ var cell = this.cell, row = this.rowIndex;
+ if(!this.isNavHeader() && cell){
+ if(inRowDelta !== 0){//jump over hidden rows
+ var node = cell.view.getRowNode(row);//row node
+ if(node && dojo.style(node, "display") === "none"){
+ this.move(inRowDelta > 0 ? 1 : -1, inColDelta);
+ }
+ }else if(inColDelta !== 0){//jump over hidden cells
+ var node = cell.getNode(row);//cell node
+ if(node && dojo.style(node, "display") === "none"){
+ this.move(inRowDelta, inColDelta > 0 ? 1 : -1);
+ }
+ }
+ }
+ },
+ _onContentKeyDown: function(e, isBubble){
+ if(isBubble){
+ var dk = dojo.keys, s = this.grid.scroller;
+ switch(e.keyCode){
+ case dk.ENTER:
+ case dk.SPACE:
+ var g = this.grid;
+ if(g.indirectSelection){ break; }
+ g.selection.clickSelect(this.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ g.onRowClick(e);
+ dojo.stopEvent(e);
+ break;
+ case dk.PAGE_UP:
+ if(this.rowIndex !== 0){
+ if(this.rowIndex != s.firstVisibleRow + 1){
+ this._navContent(s.firstVisibleRow - this.rowIndex, 0);
+ }else{
+ this.grid.setScrollTop(s.findScrollTop(this.rowIndex - 1));
+ this._navContent(s.firstVisibleRow - s.lastVisibleRow + 1, 0);
+ }
+ dojo.stopEvent(e);
+ }
+ break;
+ case dk.PAGE_DOWN:
+ if(this.rowIndex + 1 != this.grid.rowCount){
+ dojo.stopEvent(e);
+ if(this.rowIndex != s.lastVisibleRow - 1){
+ this._navContent(s.lastVisibleRow - this.rowIndex - 1, 0);
+ }else{
+ this.grid.setScrollTop(s.findScrollTop(this.rowIndex + 1));
+ this._navContent(s.lastVisibleRow - s.firstVisibleRow - 1, 0);
+ }
+ dojo.stopEvent(e);
+ }
+ break;
+ }
+ }
+ return true;
+ },
+ //------------------editable content area-------------------------
+ _blurFromEditableCell: false,
+ _isNavigating: false,
+ _navElems: null,
+ _focusEditableCell: function(evt,step){
+ var didFocus = false;
+ if(this._isNavigating){
+ didFocus = true;
+ }else if(this.grid.edit.isEditing() && this.cell){
+ if(this._blurFromEditableCell || !this._blurEditableCell(evt, step)){
+ this.setFocusIndex(this.rowIndex,this.cell.index);
+ didFocus = true;
+ }
+ this._stopEvent(evt);
+ }
+ return didFocus;
+ },
+ _applyEditableCell: function(){
+ try{
+ this.grid.edit.apply();
+ }catch(e){
+ console.warn("_FocusManager._applyEditableCell() error:", e);
+ }
+ },
+ _blurEditableCell: function(evt,step){
+ this._blurFromEditableCell = false;
+ if(this._isNavigating){
+ var toBlur = true;
+ if(evt){
+ var elems = this._navElems;
+ var firstElem = elems.lowest || elems.first;
+ var lastElem = elems.last || elems.highest || firstElem;
+ var target = dojo.isIE ? evt.srcElement : evt.target;
+ toBlur = target == (step > 0 ? lastElem : firstElem);
+ }
+ if(toBlur){
+ this._isNavigating = false;
+ return "content";
+ }
+ return false;
+ }else if(this.grid.edit.isEditing() && this.cell){
+ if(!step || typeof step != "number"){ return false; }
+ var dir = step > 0 ? 1 : -1;
+ var cc = this.grid.layout.cellCount;
+ for(var cell, col = this.cell.index + dir; col >= 0 && col < cc; col += dir){
+ cell = this.grid.getCell(col);
+ if(cell.editable){
+ this.cell = cell;
+ this._blurFromEditableCell = true;
+ return false;
+ }
+ }
+ if((this.rowIndex > 0 || dir == 1) && (this.rowIndex < this.grid.rowCount || dir == -1)){
+ this.rowIndex += dir;
+ //this.cell = this.grid.getCell(0); //There must be an editable cell, so this is not necessary.
+ for(col = dir > 0 ? 0 : cc - 1; col >= 0 && col < cc; col += dir){
+ cell = this.grid.getCell(col);
+ if(cell.editable){
+ this.cell = cell;
+ break;
+ }
+ }
+ this._applyEditableCell();
+ return "content";
+ }
+ }
+ return true;
+ },
+ _initNavigatableElems: function(){
+ this._navElems = dijit._getTabNavigable(this.cell.getNode(this.rowIndex));
+ },
+ _onEditableCellKeyDown: function(e, isBubble){
+ var dk = dojo.keys,
+ g = this.grid,
+ edit = g.edit,
+ editApplied = false,
+ toPropagate = true;
+ switch(e.keyCode){
+ case dk.ENTER:
+ if(isBubble && edit.isEditing()){
+ this._applyEditableCell();
+ editApplied = true;
+ }
+ //intentional drop through
+ case dk.SPACE:
+ if(!isBubble && this._isNavigating){
+ toPropagate = false;
+ break;
+ }
+ if(isBubble){
+ if(!this.cell.editable && this.cell.navigatable){
+ this._initNavigatableElems();
+ var toFocus = this._navElems.lowest || this._navElems.first;
+ if(toFocus){
+ this._isNavigating = true;
+ dijit.focus(toFocus);
+ dojo.stopEvent(e);
+ this.currentArea("editableCell", true);
+ break;
+ }
+ }
+ if(!editApplied && !edit.isEditing() && !g.pluginMgr.isFixedCell(this.cell)){
+ edit.setEditCell(this.cell, this.rowIndex);
+ }
+ if(editApplied){
+ this.currentArea("content", true);
+ }else if(this.cell.editable && g.canEdit()){
+ this.currentArea("editableCell", true);
+ }
+ }
+ break;
+ case dk.PAGE_UP:
+ case dk.PAGE_DOWN:
+ if(!isBubble && edit.isEditing()){
+ //prevent propagating to content area
+ toPropagate = false;
+ }
+ break;
+ case dk.ESCAPE:
+ if(!isBubble){
+ edit.cancel();
+ this.currentArea("content", true);
+ }
+ }
+ return toPropagate;
+ },
+ _onEditableCellMouseEvent: function(evt){
+ if(evt.type == "click"){
+ var cell = this.cell || evt.cell;
+ if(cell && !cell.editable && cell.navigatable){
+ this._initNavigatableElems();
+ if(this._navElems.lowest || this._navElems.first){
+ var target = dojo.isIE ? evt.srcElement : evt.target;
+ if(target != cell.getNode(evt.rowIndex)){
+ this._isNavigating = true;
+ this.focusArea("editableCell", evt);
+ dijit.focus(target);
+ return false;
+ }
+ }
+ }else if(this.grid.singleClickEdit){
+ this.currentArea("editableCell");
+ return false;
+ }
+ }
+ return true;
+ }
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/_FocusManager.xd.js b/js/dojo-1.6/dojox/grid/enhanced/_FocusManager.xd.js
new file mode 100644
index 0000000..8fdc0d5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/_FocusManager.xd.js
@@ -0,0 +1,788 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced._FocusManager"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced._FocusManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced._FocusManager"] = true;
+dojo.provide("dojox.grid.enhanced._FocusManager");
+
+dojo.declare("dojox.grid.enhanced._FocusArea",null,{
+ // summary:
+ // This is a friend class of _FocusManager
+/*=====
+ // name: string
+ // Name of this area.
+ name: "",
+
+ // onFocus: function(event, step)
+ // Called when this area logically gets focus.
+ // event: Event object
+ // May be unavailable, should check before use.
+ // step: Integer
+ // The distance in the tab sequence from last focused area to this area.
+ // returns:
+ // whether this area is successfully focused. If not, the next area will get focus.
+ onFocus: function(event, step){return true;},
+
+ // onBlur: function(event, step)
+ // Called when this area logically loses focus.
+ // event: Event object
+ // May be unavailable, should check before use.
+ // step: Integer
+ // The distance in the tab sequence from this area to the area to focus.
+ // returns:
+ // If Boolean, means whether this area has successfully blurred. If not, the next area to focus is still this one.
+ // If String, means the next area to focus is given by this returned name.
+ onBlur: function(event, step){return true;},
+
+ // onMove: function(rowStep, colStep, event)
+ // Called when focus is moving around within this area.
+ // rowStep: Integer
+ // colStep: Integer
+ // event: Event object
+ // May be unavailable, should check before use.
+ onMove: function(rowStep, colStep, event){},
+
+ // onKey: function(event, isBubble)
+ // Called when some key is pressed when focus is logically in this area.
+ // event: Event object
+ // isBubble: Boolean
+ // Whether is in bubble stage (true) or catch stage (false).
+ // returns:
+ // If you do NOT want the event to propagate any further along the area stack, return exactly false.
+ // So if you return nothing (undefined), this event is still propagating.
+ onKey: function(event, isBubble){return true},
+
+ // getRegions: function()
+ // Define the small regions (dom nodes) in this area.
+ // returns: Array of dom nodes.
+ getRegions: function(){},
+
+ // onRegionFocus: function(event)
+ // Connected to the onfocus event of the defined regions (if any)
+ onRegionFocus: function(event){},
+
+ // onRegionBlur: function(event)
+ // Connected to the onblur event of the defined regions (if any)
+ onRegionBlur: function(event){},
+=====*/
+ constructor: function(area, focusManager){
+ this._fm = focusManager;
+ this._evtStack = [area.name];
+ var dummy = function(){return true;};
+ area.onFocus = area.onFocus || dummy;
+ area.onBlur = area.onBlur || dummy;
+ area.onMove = area.onMove || dummy;
+ area.onKeyUp = area.onKeyUp || dummy;
+ area.onKeyDown = area.onKeyDown || dummy;
+ dojo.mixin(this, area);
+ },
+ move: function(rowStep, colStep, evt){
+ if(this.name){
+ var i, len = this._evtStack.length;
+ for(i = len - 1; i >= 0; --i){
+ if(this._fm._areas[this._evtStack[i]].onMove(rowStep, colStep, evt) === false){
+ return false;
+ }
+ }
+ }
+ return true;
+ },
+ _onKeyEvent: function(evt, funcName){
+ if(this.name){
+ var i, len = this._evtStack.length;
+ for(i = len - 1; i >= 0; --i){
+ if(this._fm._areas[this._evtStack[i]][funcName](evt, false) === false){
+ return false;
+ }
+ }
+ for(i = 0; i < len; ++i){
+ if(this._fm._areas[this._evtStack[i]][funcName](evt, true) === false){
+ return false;
+ }
+ }
+ }
+ return true;
+ },
+ keydown: function(evt){
+ return this._onKeyEvent(evt, "onKeyDown");
+ },
+ keyup: function(evt){
+ return this._onKeyEvent(evt, "onKeyUp");
+ },
+ contentMouseEventPlanner: function(){
+ return 0;
+ },
+ headerMouseEventPlanner: function(){
+ return 0;
+ }
+});
+dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
+ _stopEvent: function(evt){
+ try{
+ if(evt && evt.preventDefault){
+ dojo.stopEvent(evt);
+ }
+ }catch(e){}
+ },
+
+ constructor: function(grid){
+ this.grid = grid;
+ this._areas = {};
+ this._areaQueue = [];
+ this._contentMouseEventHandlers = [];
+ this._headerMouseEventHandlers = [];
+ this._currentAreaIdx = -1;
+ this._gridBlured = true;
+ this._connects.push(dojo.connect(grid, "onBlur", this, "_doBlur"));
+
+ this.addArea({
+ name: "header",
+ onFocus: dojo.hitch(this, this.focusHeader),
+ onBlur: dojo.hitch(this, this._blurHeader),
+ onMove: dojo.hitch(this, this._navHeader),
+ getRegions: dojo.hitch(this, this._findHeaderCells),
+ onRegionFocus: dojo.hitch(this, this.doColHeaderFocus),
+ onRegionBlur: dojo.hitch(this, this.doColHeaderBlur),
+ onKeyDown: dojo.hitch(this, this._onHeaderKeyDown)
+ });
+ this.addArea({
+ name: "content",
+ onFocus: dojo.hitch(this, this._focusContent),
+ onBlur: dojo.hitch(this, this._blurContent),
+ onMove: dojo.hitch(this, this._navContent),
+ onKeyDown: dojo.hitch(this, this._onContentKeyDown)
+ });
+ this.addArea({
+ name: "editableCell",
+ onFocus: dojo.hitch(this, this._focusEditableCell),
+ onBlur: dojo.hitch(this, this._blurEditableCell),
+ onKeyDown: dojo.hitch(this, this._onEditableCellKeyDown),
+ onContentMouseEvent: dojo.hitch(this, this._onEditableCellMouseEvent),
+ contentMouseEventPlanner: function(evt, areas){ return -1; }
+ });
+ this.placeArea("header");
+ this.placeArea("content");
+ this.placeArea("editableCell");
+ this.placeArea("editableCell","above","content");
+ },
+ destroy: function(){
+ for(var name in this._areas){
+ var area = this._areas[name];
+ dojo.forEach(area._connects, dojo.disconnect);
+ area._connects = null;
+ if(area.uninitialize){
+ area.uninitialize();
+ }
+ }
+ this.inherited(arguments);
+ },
+ addArea: function(area){
+ if(area.name && dojo.isString(area.name)){
+ if(this._areas[area.name]){
+ //Just replace the original area, instead of remove it, so the position does not change.
+ dojo.forEach(area._connects, dojo.disconnect);
+ }
+ this._areas[area.name] = new dojox.grid.enhanced._FocusArea(area, this);
+ if(area.onHeaderMouseEvent){
+ this._headerMouseEventHandlers.push(area.name);
+ }
+ if(area.onContentMouseEvent){
+ this._contentMouseEventHandlers.push(area.name);
+ }
+ }
+ },
+ getArea: function(areaName){
+ return this._areas[areaName];
+ },
+ _bindAreaEvents: function(){
+ var area, hdl, areas = this._areas;
+ dojo.forEach(this._areaQueue, function(name){
+ area = areas[name];
+ if(!area._initialized && dojo.isFunction(area.initialize)){
+ area.initialize();
+ area._initialized = true;
+ }
+ if(area.getRegions){
+ area._regions = area.getRegions() || [];
+ dojo.forEach(area._connects || [], dojo.disconnect);
+ area._connects = [];
+ dojo.forEach(area._regions, function(r){
+ if(area.onRegionFocus){
+ hdl = dojo.connect(r, "onfocus", area.onRegionFocus);
+ area._connects.push(hdl);
+ }
+ if(area.onRegionBlur){
+ hdl = dojo.connect(r, "onblur", area.onRegionBlur);
+ area._connects.push(hdl);
+ }
+ });
+ }
+ });
+ },
+ removeArea: function(areaName){
+ var area = this._areas[areaName];
+ if(area){
+ this.ignoreArea(areaName);
+ var i = dojo.indexOf(this._contentMouseEventHandlers, areaName);
+ if(i >= 0){
+ this._contentMouseEventHandlers.splice(i, 1);
+ }
+ i = dojo.indexOf(this._headerMouseEventHandlers, areaName);
+ if(i >= 0){
+ this._headerMouseEventHandlers.splice(i, 1);
+ }
+ dojo.forEach(area._connects, dojo.disconnect);
+ if(area.uninitialize){
+ area.uninitialize();
+ }
+ delete this._areas[areaName];
+ }
+ },
+ currentArea: function(areaName, toBlurOld){
+ // summary:
+ // Set current area to the one areaName refers.
+ // areaName: String
+ var idx, cai = this._currentAreaIdx;
+ if(dojo.isString(areaName) && (idx = dojo.indexOf(this._areaQueue, areaName)) >= 0){
+ if(cai != idx){
+ this.tabbingOut = false;
+ if(toBlurOld && cai >= 0 && cai < this._areaQueue.length){
+ this._areas[this._areaQueue[cai]].onBlur();
+ }
+ this._currentAreaIdx = idx;
+ }
+ }else{
+ return (cai < 0 || cai >= this._areaQueue.length) ?
+ new dojox.grid.enhanced._FocusArea({}, this) :
+ this._areas[this._areaQueue[this._currentAreaIdx]];
+ }
+ return null;
+ },
+ placeArea: function(name, pos, otherAreaName){
+ // summary:
+ // Place the area refered by *name* at some logical position relative to an existing area.
+ // example:
+ // placeArea("myarea","before"|"after",...)
+ // placeArea("myarea","below"|"above",...)
+ if(!this._areas[name]){ return; }
+ var idx = dojo.indexOf(this._areaQueue,otherAreaName);
+ switch(pos){
+ case "after":
+ if(idx >= 0){ ++idx; }
+ //intentional drop through
+ case "before":
+ if(idx >= 0){
+ this._areaQueue.splice(idx,0,name);
+ break;
+ }
+ //intentional drop through
+ default:
+ this._areaQueue.push(name);
+ break;
+ case "above":
+ var isAbove = true;
+ //intentional drop through
+ case "below":
+ var otherArea = this._areas[otherAreaName];
+ if(otherArea){
+ if(isAbove){
+ otherArea._evtStack.push(name);
+ }else{
+ otherArea._evtStack.splice(0,0,name);
+ }
+ }
+ }
+ },
+ ignoreArea: function(name){
+ this._areaQueue = dojo.filter(this._areaQueue,function(areaName){
+ return areaName != name;
+ });
+ },
+ focusArea: function(/* int|string|areaObj */areaId,evt){
+ var idx;
+ if(typeof areaId == "number"){
+ idx = areaId < 0 ? this._areaQueue.length + areaId : areaId;
+ }else{
+ idx = dojo.indexOf(this._areaQueue,
+ dojo.isString(areaId) ? areaId : (areaId && areaId.name));
+ }
+ if(idx < 0){ idx = 0; }
+ var step = idx - this._currentAreaIdx;
+ this._gridBlured = false;
+ if(step){
+ this.tab(step, evt);
+ }else{
+ this.currentArea().onFocus(evt, step);
+ }
+ },
+ tab: function(step,evt){
+ //console.log("===========tab",step,"curArea",this._currentAreaIdx,"areaCnt",this._areaQueue.length);
+ this._gridBlured = false;
+ this.tabbingOut = false;
+ if(step === 0){
+ return;
+ }
+ var cai = this._currentAreaIdx;
+ var dir = step > 0 ? 1:-1;
+ if(cai < 0 || cai >= this._areaQueue.length){
+ cai = (this._currentAreaIdx += step);
+ }else{
+ var nextArea = this._areas[this._areaQueue[cai]].onBlur(evt,step);
+ if(nextArea === true){
+ cai = (this._currentAreaIdx += step);
+ }else if(dojo.isString(nextArea) && this._areas[nextArea]){
+ cai = this._currentAreaIdx = dojo.indexOf(this._areaQueue,nextArea);
+ }
+ }
+ //console.log("target area:",cai);
+ for(; cai >= 0 && cai < this._areaQueue.length; cai += dir){
+ this._currentAreaIdx = cai;
+ if(this._areaQueue[cai] && this._areas[this._areaQueue[cai]].onFocus(evt,step)){
+ //console.log("final target area:",this._currentAreaIdx);
+ return;
+ }
+ }
+ //console.log("tab out");
+ this.tabbingOut = true;
+ if(step < 0){
+ this._currentAreaIdx = -1;
+ dijit.focus(this.grid.domNode);
+ }else{
+ this._currentAreaIdx = this._areaQueue.length;
+ dijit.focus(this.grid.lastFocusNode);
+ }
+ },
+ _onMouseEvent: function(type, evt){
+ var lowercase = type.toLowerCase(),
+ handlers = this["_" + lowercase + "MouseEventHandlers"],
+ res = dojo.map(handlers, function(areaName){
+ return {
+ "area": areaName,
+ "idx": this._areas[areaName][lowercase + "MouseEventPlanner"](evt, handlers)
+ };
+ }, this).sort(function(a, b){
+ return b.idx - a.idx;
+ }),
+ resHandlers = dojo.map(res, function(handler){
+ return res.area;
+ }),
+ i = res.length;
+ while(--i >= 0){
+ if(this._areas[res[i].area]["on" + type + "MouseEvent"](evt, resHandlers) === false){
+ return;
+ }
+ }
+ },
+ contentMouseEvent: function(evt){
+ this._onMouseEvent("Content", evt);
+ },
+ headerMouseEvent: function(evt){
+ this._onMouseEvent("Header", evt);
+ },
+ initFocusView: function(){
+ // summary:
+ // Overwritten
+ this.focusView = this.grid.views.getFirstScrollingView() || this.focusView || this.grid.views.views[0];
+ this._bindAreaEvents();
+ },
+ isNavHeader: function(){
+ // summary:
+ // Overwritten
+ // Check whether currently navigating among column headers.
+ // return:
+ // true - focus is on a certain column header | false otherwise
+ return this._areaQueue[this._currentAreaIdx] == "header";
+ },
+ previousKey: function(e){
+ // summary:
+ // Overwritten
+ this.tab(-1,e);
+ },
+ nextKey: function(e){
+ // summary:
+ // Overwritten
+ this.tab(1,e);
+ },
+ setFocusCell: function(/* Object */inCell, /* Integer */inRowIndex){
+ // summary:
+ // Overwritten - focuses the given grid cell
+ if(inCell){
+ this.currentArea(this.grid.edit.isEditing() ? "editableCell" : "content", true);
+ //This is very slow when selecting cells!
+ //this.focusGridView();
+ this._focusifyCellNode(false);
+ this.cell = inCell;
+ this.rowIndex = inRowIndex;
+ this._focusifyCellNode(true);
+ }
+ this.grid.onCellFocus(this.cell, this.rowIndex);
+ },
+ doFocus: function(e){
+ // summary:
+ // Overwritten
+ // trap focus only for grid dom node
+ // do not focus for scrolling if grid is about to blur
+ if(e && e.target == e.currentTarget && !this.tabbingOut){
+ if(this._gridBlured){
+ this._gridBlured = false;
+ if(this._currentAreaIdx < 0 || this._currentAreaIdx >= this._areaQueue.length){
+ this.focusArea(0, e);
+ }else{
+ this.focusArea(this._currentAreaIdx, e);
+ }
+ }
+ }else{
+ this.tabbingOut = false;
+ }
+ dojo.stopEvent(e);
+ },
+ _doBlur: function(){
+ this._gridBlured = true;
+ },
+ doLastNodeFocus: function(e){
+ // summary:
+ // Overwritten
+ if(this.tabbingOut){
+ this.tabbingOut = false;
+ }else{
+ this.focusArea(-1, e);
+ }
+ },
+ _delayedHeaderFocus: function(){
+ // summary:
+ // Overwritten
+ if(this.isNavHeader()){
+ this.focusHeader();
+ }
+ },
+ _delayedCellFocus: function(){
+ // summary:
+ // Overwritten
+ if(this.currentArea().name == "content"){
+ this.focusArea(this._currentAreaIdx);
+ }
+ },
+ _changeMenuBindNode: function(oldBindNode, newBindNode){
+ var hm = this.grid.headerMenu;
+ if(hm && this._contextMenuBindNode == oldBindNode){
+ hm.unBindDomNode(oldBindNode);
+ hm.bindDomNode(newBindNode);
+ this._contextMenuBindNode = newBindNode;
+ }
+ },
+ //---------------Header Area------------------------------------------
+ focusHeader: function(evt, step){ //need a further look why these changes to parent's
+ // summary:
+ // Overwritten
+ var didFocus = false;
+ this.inherited(arguments);
+ if(this._colHeadNode && dojo.style(this._colHeadNode, 'display') != "none"){
+ dijit.focus(this._colHeadNode);
+ this._stopEvent(evt);
+ didFocus = true;
+ }
+ return didFocus;
+ },
+ _blurHeader: function(evt,step){
+ // summary:
+ // Overwritten
+ if(this._colHeadNode){
+ dojo.removeClass(this._colHeadNode, this.focusClass);
+ }
+ dojo.removeAttr(this.grid.domNode,"aria-activedescendant");
+ // reset contextMenu onto viewsHeaderNode so right mouse on header will invoke (see focusHeader)
+ this._changeMenuBindNode(this.grid.domNode,this.grid.viewsHeaderNode);
+ //moved here from nextKey
+ this._colHeadNode = this._colHeadFocusIdx = null;
+ return true;
+ },
+ _navHeader: function(rowStep, colStep, evt){
+ var colDir = colStep < 0 ? -1 : 1,
+ savedIdx = dojo.indexOf(this._findHeaderCells(), this._colHeadNode);
+ if(savedIdx >= 0 && (evt.shiftKey && evt.ctrlKey)){
+ this.colSizeAdjust(evt, savedIdx, colDir * 5);
+ return;
+ }
+ this.move(rowStep, colStep);
+ },
+ _onHeaderKeyDown: function(e, isBubble){
+ if(isBubble){
+ var dk = dojo.keys;
+ switch(e.keyCode){
+ case dk.ENTER:
+ case dk.SPACE:
+ var colIdx = this.getHeaderIndex();
+ if(colIdx >= 0 && !this.grid.pluginMgr.isFixedCell(e.cell)/*TODO*/){
+ this.grid.setSortIndex(colIdx, null, e);
+ dojo.stopEvent(e);
+ }
+ break;
+ }
+ }
+ return true;
+ },
+ _setActiveColHeader: function(){
+ // summary:
+ // Overwritten
+ this.inherited(arguments);
+ //EDG now will decorate event on header key events, if no focus, the cell will be wrong
+ dijit.focus(this._colHeadNode);
+ },
+ //---------------Content Area------------------------------------------
+ findAndFocusGridCell: function(){
+ // summary:
+ // Overwritten
+ this._focusContent();
+ },
+ _focusContent: function(evt,step){
+ var didFocus = true;
+ var isEmpty = (this.grid.rowCount === 0); // If grid is empty this.grid.rowCount == 0
+ if(this.isNoFocusCell() && !isEmpty){
+ //skip all the hidden cells
+ for(var i = 0, cell = this.grid.getCell(0); cell && cell.hidden; cell = this.grid.getCell(++i)){}
+ this.setFocusIndex(0, cell ? i : 0);
+ }else if(this.cell && !isEmpty){
+ if(this.focusView && !this.focusView.rowNodes[this.rowIndex]){
+ // if rowNode for current index is undefined (likely as a result of a sort and because of #7304)
+ // scroll to that row
+ this.grid.scrollToRow(this.rowIndex);
+ this.focusGrid();
+ }else{
+ this.setFocusIndex(this.rowIndex, this.cell.index);
+ }
+ }else{
+ didFocus = false;
+ }
+ if(didFocus){ this._stopEvent(evt); }
+ return didFocus;
+ },
+ _blurContent: function(evt,step){
+ this._focusifyCellNode(false);
+ return true;
+ },
+ _navContent: function(rowStep, colStep, evt){
+ if((this.rowIndex === 0 && rowStep < 0) || (this.rowIndex === this.grid.rowCount - 1 && rowStep > 0)){
+ return;
+ }
+ this._colHeadNode = null;
+ this.move(rowStep, colStep, evt);
+ if(evt){
+ dojo.stopEvent(evt);
+ }
+ },
+ move: function(inRowDelta, inColDelta){
+ // summary:
+ // Overwritten
+ this.inherited(arguments);
+ var cell = this.cell, row = this.rowIndex;
+ if(!this.isNavHeader() && cell){
+ if(inRowDelta !== 0){//jump over hidden rows
+ var node = cell.view.getRowNode(row);//row node
+ if(node && dojo.style(node, "display") === "none"){
+ this.move(inRowDelta > 0 ? 1 : -1, inColDelta);
+ }
+ }else if(inColDelta !== 0){//jump over hidden cells
+ var node = cell.getNode(row);//cell node
+ if(node && dojo.style(node, "display") === "none"){
+ this.move(inRowDelta, inColDelta > 0 ? 1 : -1);
+ }
+ }
+ }
+ },
+ _onContentKeyDown: function(e, isBubble){
+ if(isBubble){
+ var dk = dojo.keys, s = this.grid.scroller;
+ switch(e.keyCode){
+ case dk.ENTER:
+ case dk.SPACE:
+ var g = this.grid;
+ if(g.indirectSelection){ break; }
+ g.selection.clickSelect(this.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ g.onRowClick(e);
+ dojo.stopEvent(e);
+ break;
+ case dk.PAGE_UP:
+ if(this.rowIndex !== 0){
+ if(this.rowIndex != s.firstVisibleRow + 1){
+ this._navContent(s.firstVisibleRow - this.rowIndex, 0);
+ }else{
+ this.grid.setScrollTop(s.findScrollTop(this.rowIndex - 1));
+ this._navContent(s.firstVisibleRow - s.lastVisibleRow + 1, 0);
+ }
+ dojo.stopEvent(e);
+ }
+ break;
+ case dk.PAGE_DOWN:
+ if(this.rowIndex + 1 != this.grid.rowCount){
+ dojo.stopEvent(e);
+ if(this.rowIndex != s.lastVisibleRow - 1){
+ this._navContent(s.lastVisibleRow - this.rowIndex - 1, 0);
+ }else{
+ this.grid.setScrollTop(s.findScrollTop(this.rowIndex + 1));
+ this._navContent(s.lastVisibleRow - s.firstVisibleRow - 1, 0);
+ }
+ dojo.stopEvent(e);
+ }
+ break;
+ }
+ }
+ return true;
+ },
+ //------------------editable content area-------------------------
+ _blurFromEditableCell: false,
+ _isNavigating: false,
+ _navElems: null,
+ _focusEditableCell: function(evt,step){
+ var didFocus = false;
+ if(this._isNavigating){
+ didFocus = true;
+ }else if(this.grid.edit.isEditing() && this.cell){
+ if(this._blurFromEditableCell || !this._blurEditableCell(evt, step)){
+ this.setFocusIndex(this.rowIndex,this.cell.index);
+ didFocus = true;
+ }
+ this._stopEvent(evt);
+ }
+ return didFocus;
+ },
+ _applyEditableCell: function(){
+ try{
+ this.grid.edit.apply();
+ }catch(e){
+ console.warn("_FocusManager._applyEditableCell() error:", e);
+ }
+ },
+ _blurEditableCell: function(evt,step){
+ this._blurFromEditableCell = false;
+ if(this._isNavigating){
+ var toBlur = true;
+ if(evt){
+ var elems = this._navElems;
+ var firstElem = elems.lowest || elems.first;
+ var lastElem = elems.last || elems.highest || firstElem;
+ var target = dojo.isIE ? evt.srcElement : evt.target;
+ toBlur = target == (step > 0 ? lastElem : firstElem);
+ }
+ if(toBlur){
+ this._isNavigating = false;
+ return "content";
+ }
+ return false;
+ }else if(this.grid.edit.isEditing() && this.cell){
+ if(!step || typeof step != "number"){ return false; }
+ var dir = step > 0 ? 1 : -1;
+ var cc = this.grid.layout.cellCount;
+ for(var cell, col = this.cell.index + dir; col >= 0 && col < cc; col += dir){
+ cell = this.grid.getCell(col);
+ if(cell.editable){
+ this.cell = cell;
+ this._blurFromEditableCell = true;
+ return false;
+ }
+ }
+ if((this.rowIndex > 0 || dir == 1) && (this.rowIndex < this.grid.rowCount || dir == -1)){
+ this.rowIndex += dir;
+ //this.cell = this.grid.getCell(0); //There must be an editable cell, so this is not necessary.
+ for(col = dir > 0 ? 0 : cc - 1; col >= 0 && col < cc; col += dir){
+ cell = this.grid.getCell(col);
+ if(cell.editable){
+ this.cell = cell;
+ break;
+ }
+ }
+ this._applyEditableCell();
+ return "content";
+ }
+ }
+ return true;
+ },
+ _initNavigatableElems: function(){
+ this._navElems = dijit._getTabNavigable(this.cell.getNode(this.rowIndex));
+ },
+ _onEditableCellKeyDown: function(e, isBubble){
+ var dk = dojo.keys,
+ g = this.grid,
+ edit = g.edit,
+ editApplied = false,
+ toPropagate = true;
+ switch(e.keyCode){
+ case dk.ENTER:
+ if(isBubble && edit.isEditing()){
+ this._applyEditableCell();
+ editApplied = true;
+ }
+ //intentional drop through
+ case dk.SPACE:
+ if(!isBubble && this._isNavigating){
+ toPropagate = false;
+ break;
+ }
+ if(isBubble){
+ if(!this.cell.editable && this.cell.navigatable){
+ this._initNavigatableElems();
+ var toFocus = this._navElems.lowest || this._navElems.first;
+ if(toFocus){
+ this._isNavigating = true;
+ dijit.focus(toFocus);
+ dojo.stopEvent(e);
+ this.currentArea("editableCell", true);
+ break;
+ }
+ }
+ if(!editApplied && !edit.isEditing() && !g.pluginMgr.isFixedCell(this.cell)){
+ edit.setEditCell(this.cell, this.rowIndex);
+ }
+ if(editApplied){
+ this.currentArea("content", true);
+ }else if(this.cell.editable && g.canEdit()){
+ this.currentArea("editableCell", true);
+ }
+ }
+ break;
+ case dk.PAGE_UP:
+ case dk.PAGE_DOWN:
+ if(!isBubble && edit.isEditing()){
+ //prevent propagating to content area
+ toPropagate = false;
+ }
+ break;
+ case dk.ESCAPE:
+ if(!isBubble){
+ edit.cancel();
+ this.currentArea("content", true);
+ }
+ }
+ return toPropagate;
+ },
+ _onEditableCellMouseEvent: function(evt){
+ if(evt.type == "click"){
+ var cell = this.cell || evt.cell;
+ if(cell && !cell.editable && cell.navigatable){
+ this._initNavigatableElems();
+ if(this._navElems.lowest || this._navElems.first){
+ var target = dojo.isIE ? evt.srcElement : evt.target;
+ if(target != cell.getNode(evt.rowIndex)){
+ this._isNavigating = true;
+ this.focusArea("editableCell", evt);
+ dijit.focus(target);
+ return false;
+ }
+ }
+ }else if(this.grid.singleClickEdit){
+ this.currentArea("editableCell");
+ return false;
+ }
+ }
+ return true;
+ }
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/_Plugin.js b/js/dojo-1.6/dojox/grid/enhanced/_Plugin.js
new file mode 100644
index 0000000..861a249
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/_Plugin.js
@@ -0,0 +1,174 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced._Plugin"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced._Plugin"] = true;
+dojo.provide("dojox.grid.enhanced._Plugin");
+
+dojo.require("dojox.grid.EnhancedGrid");
+dojo.declare("dojox.grid.enhanced._Plugin", null, {
+ // summary:
+ // Base class for all plugins.
+ //
+ // description:
+ // Provides common plugin functionality and basic life cycle management.
+ //
+ // Each concrete plugin must have a name field and is responsible for registering itself to the global plugin registry
+ // e.g. for dnd plugin:
+ // | dojox.grid.EnhancedGrid.registerPlugin("dnd" /*plugin name*/,
+ // | dojox.grid.enhanced.plugins.DnD /*full class name of a plugin*/
+ // | {"preInit": false, "dependency": ["nestedSorting"]} /*properties*/);
+ //
+ // [Keywords] of plugin properties(case sensitive)
+ // - "preInit": boolean, whether a plugin should be created before EnhancedGrid.postCreate(),
+ // false by default(plugins are created after EnhancedGrid.postCreate()).
+ // - "dependency": array or string, plugin(s) indicated by "dependency" will be created before the current one.
+ // Note: recursive cycle dependencies are not supported e.g. following dependency is invalid:
+ // pluginA -> pluginB -> pluginA
+ //
+ // example:
+ // 1. Customize default DnD plugin
+ // | dojo.declare("mygrid.MyDnD", dojox.grid.enhanced.plugins.DnD, {
+ // | name:"dnd" //still reuse the plugin name
+ // | constructor: function(inGrid, option){ ... }
+ // | });
+ // | dojox.grid.EnhancedGrid.registerPlugin("dnd", mygrid.MyDnD);
+ //
+ // 2. Add new plugin - PluginA
+ // | dojo.declare("mygrid.PluginA", dojox.grid.enhanced._Plugin, {
+ // | name: "pA",
+ // | constructor: function(inGrid, option){ ... }
+ // | });
+ // | dojox.grid.EnhancedGrid.registerPlugin("pA",mygrid.PluginA);
+ //
+ // 3. Use plugins
+ // | dojo.require("mygrid.MyDnD");
+ // | dojo.require("mygrid.PluginA");
+
+ // | <script type="text/javascript">
+ // | var grid = new dojox.grid.EnhancedGrid(
+ // | {plugins: {dnd:true, pA:true}, ... }, dojo.byId("gridDiv"));
+ // | grid.startup();
+ // | </script>
+
+ //name: String
+ // Plugin name, e.g. 'nestedSorting', 'dnd'...
+ name: 'plugin',
+
+ //grid: Object
+ // Grid that the plugin belongs to
+ grid: null,
+
+ //option: Object
+ // Plugin properties - leveraged with default and user specified properties.
+ // e.g. for dnd plugin, it may look like {"class": dojox.grid.enhanced.plugins.DnD, "dependency": ["nestedSorting"], ...}
+ option: {},
+
+ //_connects: Array
+ // List of all connections.
+ _connects: [],
+
+ //_subscribes: Array
+ // List of all subscribes.
+ _subscribes: [],
+
+ //privates: Object
+ // Private properties/methods shouldn't be mixin-ed anytime.
+ privates: {},
+
+ constructor: function(inGrid, option){
+ this.grid = inGrid;
+ this.option = option;
+ this._connects = [];
+ this._subscribes = [];
+ this.privates = dojo.mixin({},dojox.grid.enhanced._Plugin.prototype);
+ this.init();
+ },
+
+ init: function(){},
+
+ onPreInit: function(){},
+
+ onPostInit: function(){},
+
+ onStartUp: function(){},
+
+ connect: function(obj, event, method){
+ // summary:
+ // Connects specified obj/event to specified method of this object.
+ // example:
+ // | var plugin = new dojox.grid.enhanced._Plugin(grid,"myPlugin",{...});
+ // | // when foo.bar() is called, call the listener in the scope of plugin
+ // | plugin.connect(foo, "bar", function(){
+ // | console.debug(this.xxx());//"this" - plugin scope
+ // | });
+ var conn = dojo.connect(obj, event, this, method);
+ this._connects.push(conn);
+ return conn;
+ },
+ disconnect: function(handle){
+ // summary:
+ // Disconnects handle and removes it from connection list.
+ dojo.some(this._connects, function(conn, i, conns){
+ if(conn == handle){
+ dojo.disconnect(handle);
+ conns.splice(i, 1);
+ return true;
+ }
+ return false;
+ });
+ },
+ subscribe: function(topic, method){
+ // summary:
+ // Subscribes to the specified topic and calls the specified method
+ // of this object.
+ // example:
+ // | var plugin = new dojox.grid.enhanced._Plugin(grid,"myPlugin",{...});
+ // | // when /my/topic is published, call the subscriber in the scope of plugin
+ // | // with passed parameter - "v"
+ // | plugin.subscribe("/my/topic", function(v){
+ // | console.debug(this.xxx(v));//"this" - plugin scope
+ // | });
+ var subscribe = dojo.subscribe(topic, this, method);
+ this._subscribes.push(subscribe);
+ return subscribe;
+ },
+ unsubscribe: function(handle){
+ // summary:
+ // Un-subscribes handle and removes it from subscriptions list.
+ dojo.some(this._subscribes, function(subscribe, i, subscribes){
+ if(subscribe == handle){
+ dojo.unsubscribe(handle);
+ subscribes.splice(i, 1);
+ return true;
+ }
+ return false;
+ });
+ },
+ onSetStore: function(store){
+ // summary:
+ // Called when store is changed.
+ },
+ destroy: function(){
+ // summary:
+ // Destroy all resources.
+ dojo.forEach(this._connects, dojo.disconnect);
+ dojo.forEach(this._subscribes, dojo.unsubscribe);
+ delete this._connects;
+ delete this._subscribes;
+ delete this.option;
+ delete this.privates;
+ //console.log('Plugin [', this.name, '].destroy() executed!');
+ }
+});
+
+//Each plugin is responsible for registering itself
+// e.g. for DnD plugin(name:'dnd'):
+// | dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.DnD/*class*/,
+// | {"dependency": ["nestedSorting"]}/*Optional - properties*/);
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/_Plugin.xd.js b/js/dojo-1.6/dojox/grid/enhanced/_Plugin.xd.js
new file mode 100644
index 0000000..5d5d98d
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/_Plugin.xd.js
@@ -0,0 +1,179 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced._Plugin"],
+["require", "dojox.grid.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced._Plugin"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced._Plugin"] = true;
+dojo.provide("dojox.grid.enhanced._Plugin");
+
+dojo.require("dojox.grid.EnhancedGrid");
+dojo.declare("dojox.grid.enhanced._Plugin", null, {
+ // summary:
+ // Base class for all plugins.
+ //
+ // description:
+ // Provides common plugin functionality and basic life cycle management.
+ //
+ // Each concrete plugin must have a name field and is responsible for registering itself to the global plugin registry
+ // e.g. for dnd plugin:
+ // | dojox.grid.EnhancedGrid.registerPlugin("dnd" /*plugin name*/,
+ // | dojox.grid.enhanced.plugins.DnD /*full class name of a plugin*/
+ // | {"preInit": false, "dependency": ["nestedSorting"]} /*properties*/);
+ //
+ // [Keywords] of plugin properties(case sensitive)
+ // - "preInit": boolean, whether a plugin should be created before EnhancedGrid.postCreate(),
+ // false by default(plugins are created after EnhancedGrid.postCreate()).
+ // - "dependency": array or string, plugin(s) indicated by "dependency" will be created before the current one.
+ // Note: recursive cycle dependencies are not supported e.g. following dependency is invalid:
+ // pluginA -> pluginB -> pluginA
+ //
+ // example:
+ // 1. Customize default DnD plugin
+ // | dojo.declare("mygrid.MyDnD", dojox.grid.enhanced.plugins.DnD, {
+ // | name:"dnd" //still reuse the plugin name
+ // | constructor: function(inGrid, option){ ... }
+ // | });
+ // | dojox.grid.EnhancedGrid.registerPlugin("dnd", mygrid.MyDnD);
+ //
+ // 2. Add new plugin - PluginA
+ // | dojo.declare("mygrid.PluginA", dojox.grid.enhanced._Plugin, {
+ // | name: "pA",
+ // | constructor: function(inGrid, option){ ... }
+ // | });
+ // | dojox.grid.EnhancedGrid.registerPlugin("pA",mygrid.PluginA);
+ //
+ // 3. Use plugins
+ // | dojo.require("mygrid.MyDnD");
+ // | dojo.require("mygrid.PluginA");
+
+ // | <script type="text/javascript">
+ // | var grid = new dojox.grid.EnhancedGrid(
+ // | {plugins: {dnd:true, pA:true}, ... }, dojo.byId("gridDiv"));
+ // | grid.startup();
+ // | </script>
+
+ //name: String
+ // Plugin name, e.g. 'nestedSorting', 'dnd'...
+ name: 'plugin',
+
+ //grid: Object
+ // Grid that the plugin belongs to
+ grid: null,
+
+ //option: Object
+ // Plugin properties - leveraged with default and user specified properties.
+ // e.g. for dnd plugin, it may look like {"class": dojox.grid.enhanced.plugins.DnD, "dependency": ["nestedSorting"], ...}
+ option: {},
+
+ //_connects: Array
+ // List of all connections.
+ _connects: [],
+
+ //_subscribes: Array
+ // List of all subscribes.
+ _subscribes: [],
+
+ //privates: Object
+ // Private properties/methods shouldn't be mixin-ed anytime.
+ privates: {},
+
+ constructor: function(inGrid, option){
+ this.grid = inGrid;
+ this.option = option;
+ this._connects = [];
+ this._subscribes = [];
+ this.privates = dojo.mixin({},dojox.grid.enhanced._Plugin.prototype);
+ this.init();
+ },
+
+ init: function(){},
+
+ onPreInit: function(){},
+
+ onPostInit: function(){},
+
+ onStartUp: function(){},
+
+ connect: function(obj, event, method){
+ // summary:
+ // Connects specified obj/event to specified method of this object.
+ // example:
+ // | var plugin = new dojox.grid.enhanced._Plugin(grid,"myPlugin",{...});
+ // | // when foo.bar() is called, call the listener in the scope of plugin
+ // | plugin.connect(foo, "bar", function(){
+ // | console.debug(this.xxx());//"this" - plugin scope
+ // | });
+ var conn = dojo.connect(obj, event, this, method);
+ this._connects.push(conn);
+ return conn;
+ },
+ disconnect: function(handle){
+ // summary:
+ // Disconnects handle and removes it from connection list.
+ dojo.some(this._connects, function(conn, i, conns){
+ if(conn == handle){
+ dojo.disconnect(handle);
+ conns.splice(i, 1);
+ return true;
+ }
+ return false;
+ });
+ },
+ subscribe: function(topic, method){
+ // summary:
+ // Subscribes to the specified topic and calls the specified method
+ // of this object.
+ // example:
+ // | var plugin = new dojox.grid.enhanced._Plugin(grid,"myPlugin",{...});
+ // | // when /my/topic is published, call the subscriber in the scope of plugin
+ // | // with passed parameter - "v"
+ // | plugin.subscribe("/my/topic", function(v){
+ // | console.debug(this.xxx(v));//"this" - plugin scope
+ // | });
+ var subscribe = dojo.subscribe(topic, this, method);
+ this._subscribes.push(subscribe);
+ return subscribe;
+ },
+ unsubscribe: function(handle){
+ // summary:
+ // Un-subscribes handle and removes it from subscriptions list.
+ dojo.some(this._subscribes, function(subscribe, i, subscribes){
+ if(subscribe == handle){
+ dojo.unsubscribe(handle);
+ subscribes.splice(i, 1);
+ return true;
+ }
+ return false;
+ });
+ },
+ onSetStore: function(store){
+ // summary:
+ // Called when store is changed.
+ },
+ destroy: function(){
+ // summary:
+ // Destroy all resources.
+ dojo.forEach(this._connects, dojo.disconnect);
+ dojo.forEach(this._subscribes, dojo.unsubscribe);
+ delete this._connects;
+ delete this._subscribes;
+ delete this.option;
+ delete this.privates;
+ //console.log('Plugin [', this.name, '].destroy() executed!');
+ }
+});
+
+//Each plugin is responsible for registering itself
+// e.g. for DnD plugin(name:'dnd'):
+// | dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.DnD/*class*/,
+// | {"dependency": ["nestedSorting"]}/*Optional - properties*/);
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/_PluginManager.js b/js/dojo-1.6/dojox/grid/enhanced/_PluginManager.js
new file mode 100644
index 0000000..41a0003
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/_PluginManager.js
@@ -0,0 +1,275 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced._PluginManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced._PluginManager"] = true;
+dojo.provide("dojox.grid.enhanced._PluginManager");
+
+dojo.require("dojox.grid.enhanced._Events");
+dojo.require("dojox.grid.enhanced._FocusManager");
+
+dojo.declare("dojox.grid.enhanced._PluginManager", null, {
+ // summary:
+ // Singleton plugin manager
+ //
+ // description:
+ // Plugin manager is responsible for
+ // 1. Loading required plugins
+ // 2. Handling collaboration and dependencies among plugins
+ //
+ // Some plugin dependencies:
+ // - "columnReordering" attribute won't work when either DnD or Indirect Selections plugin is on.
+
+ //_options: Object
+ // Normalized plugin options
+ _options: null,
+
+ //_plugins: Array
+ // Plugin list
+ _plugins: null,
+
+ //_connects: Array
+ // Connection list
+ _connects: null,
+
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ this._store = inGrid.store;
+ this._options = {};
+ this._plugins = [];
+ this._connects = [];
+ this._parseProps(this.grid.plugins);
+
+ inGrid.connect(inGrid, "_setStore", dojo.hitch(this, function(store){
+ if(this._store !== store){
+ this.forEach('onSetStore', [store, this._store]);
+ this._store = store;
+ }
+ }));
+ },
+ startup: function(){
+ this.forEach('onStartUp');
+ },
+ preInit: function(){
+ // summary:
+ // Load appropriate plugins before DataGrid.postCreate().
+ // See EnhancedGrid.postCreate()
+ this.grid.focus.destroy();
+ this.grid.focus = new dojox.grid.enhanced._FocusManager(this.grid);
+ new dojox.grid.enhanced._Events(this.grid);//overwrite some default events of DataGrid
+ this._init(true);
+ this.forEach('onPreInit');
+ },
+ postInit: function(){
+ // summary:
+ // Load plugins after DataGrid.postCreate() - the default phase when plugins are created
+ // See EnhancedGrid.postCreate()
+ this._init(false);
+
+ dojo.forEach(this.grid.views.views, this._initView, this);
+ this._connects.push(dojo.connect(this.grid.views, 'addView', dojo.hitch(this, this._initView)));
+
+ if(this._plugins.length > 0){
+ var edit = this.grid.edit;
+ if(edit){ edit.styleRow = function(inRow){}; }
+ }
+ this.forEach('onPostInit');
+ },
+ forEach: function(func, args){
+ dojo.forEach(this._plugins, function(p){
+ if(!p || !p[func]){ return; }
+ p[func].apply(p, args ? args : []);
+ });
+ },
+ _parseProps: function(plugins){
+ // summary:
+ // Parse plugins properties
+ // plugins: Object
+ // Plugin properties defined by user
+ if(!plugins){ return; }
+
+ var p, loading = {}, options = this._options, grid = this.grid;
+ var registry = dojox.grid.enhanced._PluginManager.registry;//global plugin registry
+ for(p in plugins){
+ if(plugins[p]){//filter out boolean false e.g. {p:false}
+ this._normalize(p, plugins, registry, loading);
+ }
+ }
+ //"columnReordering" attribute won't work when either DnD or Indirect Selections plugin is used.
+ if(options.dnd || options.indirectSelection){
+ options.columnReordering = false;
+ }
+
+ //mixin all plugin properties into Grid
+ dojo.mixin(grid, options);
+ },
+ _normalize: function(p, plugins, registry, loading){
+ // summary:
+ // Normalize plugin properties especially the dependency chain
+ // p: String
+ // Plugin name
+ // plugins: Object
+ // Plugin properties set by user
+ // registry: Object
+ // The global plugin registry
+ // loading: Object
+ // Map for checking process state
+ if(!registry[p]){ throw new Error('Plugin ' + p + ' is required.');}
+
+ if(loading[p]){ throw new Error('Recursive cycle dependency is not supported.'); }
+
+ var options = this._options;
+ if(options[p]){ return options[p]; }
+
+ loading[p] = true;
+ //TBD - more strict conditions?
+ options[p] = dojo.mixin({}, registry[p], dojo.isObject(plugins[p]) ? plugins[p] : {});
+
+ var dependencies = options[p]['dependency'];
+ if(dependencies){
+ if(!dojo.isArray(dependencies)){
+ dependencies = options[p]['dependency'] = [dependencies];
+ }
+ dojo.forEach(dependencies, function(dependency){
+ if(!this._normalize(dependency, plugins, registry, loading)){
+ throw new Error('Plugin ' + dependency + ' is required.');
+ }
+ }, this);
+ }
+ delete loading[p];
+ return options[p];
+ },
+ _init: function(pre){
+ // summary:
+ // Find appropriate plugins and load them
+ // pre: Boolean
+ // True - preInit | False - postInit(by default)
+ var p, preInit, options = this._options;
+ for(p in options){
+ preInit = options[p]['preInit'];
+ if((pre ? preInit : !preInit) && options[p]['class'] && !this.pluginExisted(p)){
+ this.loadPlugin(p);
+ }
+ }
+ },
+ loadPlugin: function(name){
+ // summary:
+ // Load required plugin("name")
+ // name: String
+ // Plugin name
+ // return: Object
+ // The newly loaded plugin
+ var option = this._options[name];
+ if(!option){ return null; } //return if no plugin option
+
+ var plugin = this.getPlugin(name);
+ if(plugin){ return plugin; } //return if plugin("name") already existed
+
+ var dependencies = option['dependency'];
+ dojo.forEach(dependencies, function(dependency){
+ if(!this.loadPlugin(dependency)){
+ throw new Error('Plugin ' + dependency + ' is required.');
+ }
+ }, this);
+ var cls = option['class'];
+ delete option['class'];//remove it for safety
+ plugin = new this.getPluginClazz(cls)(this.grid, option);
+ this._plugins.push(plugin);
+ return plugin;
+ },
+ _initView: function(view){
+ // summary:
+ // Overwrite several default behavior for each views(including _RowSelector view)
+ if(!view){ return; }
+ //add more events handler - _View
+ dojox.grid.util.funnelEvents(view.contentNode, view, "doContentEvent", ['mouseup', 'mousemove']);
+ dojox.grid.util.funnelEvents(view.headerNode, view, "doHeaderEvent", ['mouseup']);
+ },
+ pluginExisted: function(name){
+ // summary:
+ // Check if plugin("name") existed
+ // name: String
+ // Plugin name
+ // return: Boolean
+ // True - existed | False - not existed
+ return !!this.getPlugin(name);
+ },
+ getPlugin: function(name){
+ // summary:
+ // Get plugin("name")
+ // name: String
+ // Plugin name
+ // return: Object
+ // Plugin instance
+ var plugins = this._plugins;
+ name = name.toLowerCase();
+ for(var i = 0, len = plugins.length; i < len; i++){
+ if(name == plugins[i]['name'].toLowerCase()){
+ return plugins[i];
+ }
+ }
+ return null;
+ },
+ getPluginClazz: function(clazz){
+ // summary:
+ // Load target plugin which must be already required (dojo.require(..))
+ // clazz: class | String
+ // Plugin class
+ if(dojo.isFunction(clazz)){
+ return clazz;//return if it's already a clazz
+ }
+ var errorMsg = 'Please make sure Plugin "' + clazz + '" is existed.';
+ try{
+ var cls = dojo.getObject(clazz);
+ if(!cls){ throw new Error(errorMsg); }
+ return cls;
+ }catch(e){
+ throw new Error(errorMsg);
+ }
+ },
+ isFixedCell: function(cell){
+ // summary:
+ // See if target cell(column) is fixed or not.
+ // cell: Object
+ // Target cell(column)
+ // return: Boolean
+ // True - fixed| False - not fixed
+
+ //target cell can use Boolean attributes named "isRowSelector" or "fixedPos" to mark it's a fixed cell(column)
+ return cell && (cell.isRowSelector || cell.fixedPos);
+ },
+ destroy: function(){
+ // summary:
+ // Destroy all resources
+ dojo.forEach(this._connects, dojo.disconnect);
+ this.forEach('destroy');
+ if(this.grid.unwrap){
+ this.grid.unwrap();
+ }
+ delete this._connects;
+ delete this._plugins;
+ delete this._options;
+ }
+});
+
+dojox.grid.enhanced._PluginManager.registerPlugin = function(clazz, props){
+ // summary:
+ // Register plugins - TODO, a better way rather than global registry?
+ // clazz: String
+ // Full class name, e.g. "dojox.grid.enhanced.plugins.DnD"
+ // props: Object - Optional
+ // Plugin properties e.g. {"dependency": ["nestedSorting"], ...}
+ if(!clazz){
+ console.warn("Failed to register plugin, class missed!");
+ return;
+ }
+ var cls = dojox.grid.enhanced._PluginManager;
+ cls.registry = cls.registry || {};
+ cls.registry[clazz.prototype.name]/*plugin name*/ = dojo.mixin({"class": clazz}, (props ? props : {}));
+};
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/_PluginManager.xd.js b/js/dojo-1.6/dojox/grid/enhanced/_PluginManager.xd.js
new file mode 100644
index 0000000..8cd765c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/_PluginManager.xd.js
@@ -0,0 +1,281 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced._PluginManager"],
+["require", "dojox.grid.enhanced._Events"],
+["require", "dojox.grid.enhanced._FocusManager"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced._PluginManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced._PluginManager"] = true;
+dojo.provide("dojox.grid.enhanced._PluginManager");
+
+dojo.require("dojox.grid.enhanced._Events");
+dojo.require("dojox.grid.enhanced._FocusManager");
+
+dojo.declare("dojox.grid.enhanced._PluginManager", null, {
+ // summary:
+ // Singleton plugin manager
+ //
+ // description:
+ // Plugin manager is responsible for
+ // 1. Loading required plugins
+ // 2. Handling collaboration and dependencies among plugins
+ //
+ // Some plugin dependencies:
+ // - "columnReordering" attribute won't work when either DnD or Indirect Selections plugin is on.
+
+ //_options: Object
+ // Normalized plugin options
+ _options: null,
+
+ //_plugins: Array
+ // Plugin list
+ _plugins: null,
+
+ //_connects: Array
+ // Connection list
+ _connects: null,
+
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ this._store = inGrid.store;
+ this._options = {};
+ this._plugins = [];
+ this._connects = [];
+ this._parseProps(this.grid.plugins);
+
+ inGrid.connect(inGrid, "_setStore", dojo.hitch(this, function(store){
+ if(this._store !== store){
+ this.forEach('onSetStore', [store, this._store]);
+ this._store = store;
+ }
+ }));
+ },
+ startup: function(){
+ this.forEach('onStartUp');
+ },
+ preInit: function(){
+ // summary:
+ // Load appropriate plugins before DataGrid.postCreate().
+ // See EnhancedGrid.postCreate()
+ this.grid.focus.destroy();
+ this.grid.focus = new dojox.grid.enhanced._FocusManager(this.grid);
+ new dojox.grid.enhanced._Events(this.grid);//overwrite some default events of DataGrid
+ this._init(true);
+ this.forEach('onPreInit');
+ },
+ postInit: function(){
+ // summary:
+ // Load plugins after DataGrid.postCreate() - the default phase when plugins are created
+ // See EnhancedGrid.postCreate()
+ this._init(false);
+
+ dojo.forEach(this.grid.views.views, this._initView, this);
+ this._connects.push(dojo.connect(this.grid.views, 'addView', dojo.hitch(this, this._initView)));
+
+ if(this._plugins.length > 0){
+ var edit = this.grid.edit;
+ if(edit){ edit.styleRow = function(inRow){}; }
+ }
+ this.forEach('onPostInit');
+ },
+ forEach: function(func, args){
+ dojo.forEach(this._plugins, function(p){
+ if(!p || !p[func]){ return; }
+ p[func].apply(p, args ? args : []);
+ });
+ },
+ _parseProps: function(plugins){
+ // summary:
+ // Parse plugins properties
+ // plugins: Object
+ // Plugin properties defined by user
+ if(!plugins){ return; }
+
+ var p, loading = {}, options = this._options, grid = this.grid;
+ var registry = dojox.grid.enhanced._PluginManager.registry;//global plugin registry
+ for(p in plugins){
+ if(plugins[p]){//filter out boolean false e.g. {p:false}
+ this._normalize(p, plugins, registry, loading);
+ }
+ }
+ //"columnReordering" attribute won't work when either DnD or Indirect Selections plugin is used.
+ if(options.dnd || options.indirectSelection){
+ options.columnReordering = false;
+ }
+
+ //mixin all plugin properties into Grid
+ dojo.mixin(grid, options);
+ },
+ _normalize: function(p, plugins, registry, loading){
+ // summary:
+ // Normalize plugin properties especially the dependency chain
+ // p: String
+ // Plugin name
+ // plugins: Object
+ // Plugin properties set by user
+ // registry: Object
+ // The global plugin registry
+ // loading: Object
+ // Map for checking process state
+ if(!registry[p]){ throw new Error('Plugin ' + p + ' is required.');}
+
+ if(loading[p]){ throw new Error('Recursive cycle dependency is not supported.'); }
+
+ var options = this._options;
+ if(options[p]){ return options[p]; }
+
+ loading[p] = true;
+ //TBD - more strict conditions?
+ options[p] = dojo.mixin({}, registry[p], dojo.isObject(plugins[p]) ? plugins[p] : {});
+
+ var dependencies = options[p]['dependency'];
+ if(dependencies){
+ if(!dojo.isArray(dependencies)){
+ dependencies = options[p]['dependency'] = [dependencies];
+ }
+ dojo.forEach(dependencies, function(dependency){
+ if(!this._normalize(dependency, plugins, registry, loading)){
+ throw new Error('Plugin ' + dependency + ' is required.');
+ }
+ }, this);
+ }
+ delete loading[p];
+ return options[p];
+ },
+ _init: function(pre){
+ // summary:
+ // Find appropriate plugins and load them
+ // pre: Boolean
+ // True - preInit | False - postInit(by default)
+ var p, preInit, options = this._options;
+ for(p in options){
+ preInit = options[p]['preInit'];
+ if((pre ? preInit : !preInit) && options[p]['class'] && !this.pluginExisted(p)){
+ this.loadPlugin(p);
+ }
+ }
+ },
+ loadPlugin: function(name){
+ // summary:
+ // Load required plugin("name")
+ // name: String
+ // Plugin name
+ // return: Object
+ // The newly loaded plugin
+ var option = this._options[name];
+ if(!option){ return null; } //return if no plugin option
+
+ var plugin = this.getPlugin(name);
+ if(plugin){ return plugin; } //return if plugin("name") already existed
+
+ var dependencies = option['dependency'];
+ dojo.forEach(dependencies, function(dependency){
+ if(!this.loadPlugin(dependency)){
+ throw new Error('Plugin ' + dependency + ' is required.');
+ }
+ }, this);
+ var cls = option['class'];
+ delete option['class'];//remove it for safety
+ plugin = new this.getPluginClazz(cls)(this.grid, option);
+ this._plugins.push(plugin);
+ return plugin;
+ },
+ _initView: function(view){
+ // summary:
+ // Overwrite several default behavior for each views(including _RowSelector view)
+ if(!view){ return; }
+ //add more events handler - _View
+ dojox.grid.util.funnelEvents(view.contentNode, view, "doContentEvent", ['mouseup', 'mousemove']);
+ dojox.grid.util.funnelEvents(view.headerNode, view, "doHeaderEvent", ['mouseup']);
+ },
+ pluginExisted: function(name){
+ // summary:
+ // Check if plugin("name") existed
+ // name: String
+ // Plugin name
+ // return: Boolean
+ // True - existed | False - not existed
+ return !!this.getPlugin(name);
+ },
+ getPlugin: function(name){
+ // summary:
+ // Get plugin("name")
+ // name: String
+ // Plugin name
+ // return: Object
+ // Plugin instance
+ var plugins = this._plugins;
+ name = name.toLowerCase();
+ for(var i = 0, len = plugins.length; i < len; i++){
+ if(name == plugins[i]['name'].toLowerCase()){
+ return plugins[i];
+ }
+ }
+ return null;
+ },
+ getPluginClazz: function(clazz){
+ // summary:
+ // Load target plugin which must be already required (dojo.require(..))
+ // clazz: class | String
+ // Plugin class
+ if(dojo.isFunction(clazz)){
+ return clazz;//return if it's already a clazz
+ }
+ var errorMsg = 'Please make sure Plugin "' + clazz + '" is existed.';
+ try{
+ var cls = dojo.getObject(clazz);
+ if(!cls){ throw new Error(errorMsg); }
+ return cls;
+ }catch(e){
+ throw new Error(errorMsg);
+ }
+ },
+ isFixedCell: function(cell){
+ // summary:
+ // See if target cell(column) is fixed or not.
+ // cell: Object
+ // Target cell(column)
+ // return: Boolean
+ // True - fixed| False - not fixed
+
+ //target cell can use Boolean attributes named "isRowSelector" or "fixedPos" to mark it's a fixed cell(column)
+ return cell && (cell.isRowSelector || cell.fixedPos);
+ },
+ destroy: function(){
+ // summary:
+ // Destroy all resources
+ dojo.forEach(this._connects, dojo.disconnect);
+ this.forEach('destroy');
+ if(this.grid.unwrap){
+ this.grid.unwrap();
+ }
+ delete this._connects;
+ delete this._plugins;
+ delete this._options;
+ }
+});
+
+dojox.grid.enhanced._PluginManager.registerPlugin = function(clazz, props){
+ // summary:
+ // Register plugins - TODO, a better way rather than global registry?
+ // clazz: String
+ // Full class name, e.g. "dojox.grid.enhanced.plugins.DnD"
+ // props: Object - Optional
+ // Plugin properties e.g. {"dependency": ["nestedSorting"], ...}
+ if(!clazz){
+ console.warn("Failed to register plugin, class missed!");
+ return;
+ }
+ var cls = dojox.grid.enhanced._PluginManager;
+ cls.registry = cls.registry || {};
+ cls.registry[clazz.prototype.name]/*plugin name*/ = dojo.mixin({"class": clazz}, (props ? props : {}));
+};
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/EnhancedGrid.js
new file mode 100644
index 0000000..6d60230
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/EnhancedGrid.js
@@ -0,0 +1 @@
+({"singleSort":"Single Sort","indirectSelectionRadio":"Row ${0}, single selection, radio box","ascending":"Ascending","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","descending":"Descending","nestedSort":"Nested Sort","unsorted":"Do not sort this column","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/EnhancedGrid.xd.js
new file mode 100644
index 0000000..e0c82ed
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "", ({"singleSort":"Single Sort","indirectSelectionRadio":"Row ${0}, single selection, radio box","ascending":"Ascending","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","descending":"Descending","nestedSort":"Nested Sort","unsorted":"Do not sort this column","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/Filter.js
new file mode 100644
index 0000000..9c6feb0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/Filter.js
@@ -0,0 +1 @@
+({"waiRemoveRuleButtonTemplate":"Remove rule ${0}","addRuleButton":"Add Rule","a11yFilterBarDefButton":"Filter...","falseLabel":"False","conditionAfter":"after","relationAny":"any rules","conditionNotStartWith":"does not start with","relationMsgTail":"","defaultItemsName":"items","conditionContains":"contains","waiRelAny":"Match any of the following rules:","and":"and","waiClearButton":"Clear the filter","waiAddRuleButton":"Add a new rule","conditionLargerEqual":"greater than or equal","filterBarClearButton":"Clear filter","statusTipRelPost":"rules.","cancelButton":"Cancel","removeRuleButton":"Remove Rule","relationAll":"all rules","waiValueBoxTemplate":"Enter value to filter for rule ${0}","conditionNotContain":"does not contain","filterButton":"Filter","statusTipMsg":"Click the filter bar here to filter on values in ${0}.","waiRelAll":"Match all of the following rules:","closeFilterBarBtn":"Close filter bar","waiCancelButton":"Cancel this dialog","waiFilterBarDefButton":"Filter the table","statusTipTitleHasFilter":"Filter","any":"any","waiFilterButton":"Submit the filter","conditionIsEmpty":"is empty","conditionEqual":"equal","columnSelectLabel":"Column","conditionLessEqual":"less than or equal","conditionNotEndWith":"does not end with","or":"or","clearFilterDialogTitle":"Clear Filter","conditionLarger":"is greater than","relationMsgFront":"Match","statusTipHeaderColumn":"Column","conditionEndWith":"ends with","clearButton":"Clear","statusTipTitle":"Filter Bar","valueBoxLabel":"Value","conditionRange":"range","waiColumnSelectTemplate":"Column for rule ${0}","all":"all","conditionSelectLabel":"Condition","filterBarMsgHasFilterTemplate":"${0} of ${1} ${2} shown.","conditionStartsWith":"starts with","filterBarMsgNoFilterTemplate":"No filter applied","trueLabel":"True","filterBarDefButton":"Define filter","waiFilterBarClearButton":"Clear the filter","conditionBefore":"before","rangeTo":"to","rangeTemplate":"from ${0} to ${1}","anyColumnOption":"Any Column","filterDefDialogTitle":"Filter","ruleTitleTemplate":"Rule ${0}","conditionNotEqual":"does not equal","conditionIsNot":"is not","statusTipRelPre":"Match","conditionIs":"is","clearFilterMsg":"This will remove the filter and show all available records.","statusTipHeaderCondition":"Rules","waiConditionSelectTemplate":"Condition for rule ${0}","statusTipTitleNoFilter":"Filter Bar","anycolumn":"any column","conditionLess":"is less than"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/Filter.xd.js
new file mode 100644
index 0000000..09470b1
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "", ({"waiRemoveRuleButtonTemplate":"Remove rule ${0}","addRuleButton":"Add Rule","a11yFilterBarDefButton":"Filter...","falseLabel":"False","conditionAfter":"after","relationAny":"any rules","conditionNotStartWith":"does not start with","relationMsgTail":"","defaultItemsName":"items","conditionContains":"contains","waiRelAny":"Match any of the following rules:","and":"and","waiClearButton":"Clear the filter","waiAddRuleButton":"Add a new rule","conditionLargerEqual":"greater than or equal","filterBarClearButton":"Clear filter","statusTipRelPost":"rules.","cancelButton":"Cancel","removeRuleButton":"Remove Rule","relationAll":"all rules","waiValueBoxTemplate":"Enter value to filter for rule ${0}","conditionNotContain":"does not contain","filterButton":"Filter","statusTipMsg":"Click the filter bar here to filter on values in ${0}.","waiRelAll":"Match all of the following rules:","closeFilterBarBtn":"Close filter bar","waiCancelButton":"Cancel this dialog","waiFilterBarDefButton":"Filter the table","statusTipTitleHasFilter":"Filter","any":"any","waiFilterButton":"Submit the filter","conditionIsEmpty":"is empty","conditionEqual":"equal","columnSelectLabel":"Column","conditionLessEqual":"less than or equal","conditionNotEndWith":"does not end with","or":"or","clearFilterDialogTitle":"Clear Filter","conditionLarger":"is greater than","relationMsgFront":"Match","statusTipHeaderColumn":"Column","conditionEndWith":"ends with","clearButton":"Clear","statusTipTitle":"Filter Bar","valueBoxLabel":"Value","conditionRange":"range","waiColumnSelectTemplate":"Column for rule ${0}","all":"all","conditionSelectLabel":"Condition","filterBarMsgHasFilterTemplate":"${0} of ${1} ${2} shown.","conditionStartsWith":"starts with","filterBarMsgNoFilterTemplate":"No filter applied","trueLabel":"True","filterBarDefButton":"Define filter","waiFilterBarClearButton":"Clear the filter","conditionBefore":"before","rangeTo":"to","rangeTemplate":"from ${0} to ${1}","anyColumnOption":"Any Column","filterDefDialogTitle":"Filter","ruleTitleTemplate":"Rule ${0}","conditionNotEqual":"does not equal","conditionIsNot":"is not","statusTipRelPre":"Match","conditionIs":"is","clearFilterMsg":"This will remove the filter and show all available records.","statusTipHeaderCondition":"Rules","waiConditionSelectTemplate":"Condition for rule ${0}","statusTipTitleNoFilter":"Filter Bar","anycolumn":"any column","conditionLess":"is less than"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/Pagination.js
new file mode 100644
index 0000000..d3fbd81
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Go to a specific page","prevTip":"Previous Page","pageCountIndication":" (${0} pages)","pageStepLabelTemplate":"Page ${0}","descTemplate":"${2} - ${3} of ${1} ${0}","lastTip":"Last Page","nextTip":"Next Page","pageSizeLabelTemplate":"${0} items per page","dialogCancel":"Cancel","itemTitle":"items","dialogConfirm":"Go","firstTip":"First Page","allItemsLabelTemplate":"All items","dialogIndication":"Specify the page number","dialogTitle":"Go to Page"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/Pagination.xd.js
new file mode 100644
index 0000000..f5d445a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "", ({"gotoButtonTitle":"Go to a specific page","prevTip":"Previous Page","pageCountIndication":" (${0} pages)","pageStepLabelTemplate":"Page ${0}","descTemplate":"${2} - ${3} of ${1} ${0}","lastTip":"Last Page","nextTip":"Next Page","pageSizeLabelTemplate":"${0} items per page","dialogCancel":"Cancel","itemTitle":"items","dialogConfirm":"Go","firstTip":"First Page","allItemsLabelTemplate":"All items","dialogIndication":"Specify the page number","dialogTitle":"Go to Page"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ar/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ar/EnhancedGrid.js
new file mode 100644
index 0000000..07e9096
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ar/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"‏تنازلي‏","ascending":"‏تصاعدي‏","nestedSort":"فرز متداخل","unsorted":"لا تقم بفرز هذ العمود","singleSort":"فرز منفرد","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ar/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ar/EnhancedGrid.xd.js
new file mode 100644
index 0000000..4f87307
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ar/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.ar.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.ar.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "ar", ({"descending":"‏تنازلي‏","ascending":"‏تصاعدي‏","nestedSort":"فرز متداخل","unsorted":"لا تقم بفرز هذ العمود","singleSort":"فرز منفرد","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ar/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ar/Filter.js
new file mode 100644
index 0000000..964509c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ar/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"قبل","filterBarDefButton":"تعريف ترشيح البيانات","filterBarMsgNoFilterTemplate":"لم يتم تطبيق ترشيح البيانات","conditionContains":"يحتوي","clearFilterMsg":"سيقوم هذا بازالة مرشح البيانات وعرض كل السجلات المتاحة.","all":"كل","waiValueBoxTemplate":"ادخال قيمة لترشيح بيانات القاعدة ${0}","conditionRange":"مدى","waiCancelButton":"الغاء هذا الحوار","relationAll":"كل القواعد","conditionLarger":"‏أكبر من‏","valueBoxLabel":"قيمة","statusTipMsg":"اضغط خط ترشيح البيانات هنا لترشيح بيانات القيم في ${0}.","waiRelAll":"مطابقة الكل للقواعد التالية:","closeFilterBarBtn":"اغلاق خط ترشيح البيانات","a11yFilterBarDefButton":"ترشيح بيانات...","trueLabel":"True","conditionIsNot":"ليس","conditionIs":"يكون","ruleTitleTemplate":"قاعدة ${0}","waiRemoveRuleButtonTemplate":"ازالة قاعدة ${0}","and":"and","conditionLess":"‏أقل من‏","waiColumnSelectTemplate":"العمود للقاعدة ${0}","anycolumn":"أي عمود","filterDefDialogTitle":"‏ترشيح البيانات‏","waiConditionSelectTemplate":"الشرط للعمود ${0}","waiFilterButton":"احالة ترشيح البيانات","statusTipTitle":"خط ترشيح البيانات","statusTipRelPre":"مطابقة","anyColumnOption":"أي عمود","conditionSelectLabel":"الشرط","cancelButton":"الغاء","conditionNotStartWith":"لا يبدأ بـ","conditionEndWith":"ينتهي بالحروف","statusTipTitleNoFilter":"خط ترشيح البيانات","columnSelectLabel":"العمود","conditionNotContain":"لا يتضمن","clearButton":"محو","conditionLargerEqual":"أكبر من أو يساوي","any":"أي","relationMsgFront":"مطابقة","statusTipHeaderColumn":"العمود","defaultItemsName":"البنود","conditionEqual":"يساوي","relationAny":"أي قواعد","trueLabelEditable":"تم الفحص","or":"أو","filterBarMsgHasFilterTemplate":"${0} من ${1} ${2} عرض.","rangeTo":"الى","conditionStartsWith":"يبدأ بالحروف","waiRelAny":"مطابقة أي من القواعد التالية:","statusTipRelPost":"قواعد.","relationMsgTail":"","filterBarClearButton":"محو ترشيح البيانات","incompleteRuleTip":"هذه القاعدة غير تامة.","conditionLessEqual":"أقل من أو يساوي","waiFilterBarClearButton":"محو ترشيح البيانات","conditionAfter":"بعد","statusTipHeaderCondition":"قواعد","falseLabel":"خطأ","filterButton":"‏ترشيح البيانات‏","clearFilterDialogTitle":"محو ترشيح البيانات","statusTipTitleHasFilter":"‏ترشيح البيانات‏","addRuleButton":"اضافة قاعدة","waiAddRuleButton":"اضافة قاعدة جديدة","waiClearButton":"محو ترشيح البيانات","conditionNotEqual":"غير مساوي الى","conditionNotEndWith":"لا ينتهي بـ","rangeTemplate":"من ${0} الى ${1}","removeRuleButton":"ازالة قاعدة","waiFilterBarDefButton":"ترشيح بيانات الجدول","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ar/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ar/Filter.xd.js
new file mode 100644
index 0000000..5a5c710
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ar/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.ar.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.ar.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "ar", ({"conditionBefore":"قبل","filterBarDefButton":"تعريف ترشيح البيانات","filterBarMsgNoFilterTemplate":"لم يتم تطبيق ترشيح البيانات","conditionContains":"يحتوي","clearFilterMsg":"سيقوم هذا بازالة مرشح البيانات وعرض كل السجلات المتاحة.","all":"كل","waiValueBoxTemplate":"ادخال قيمة لترشيح بيانات القاعدة ${0}","conditionRange":"مدى","waiCancelButton":"الغاء هذا الحوار","relationAll":"كل القواعد","conditionLarger":"‏أكبر من‏","valueBoxLabel":"قيمة","statusTipMsg":"اضغط خط ترشيح البيانات هنا لترشيح بيانات القيم في ${0}.","waiRelAll":"مطابقة الكل للقواعد التالية:","closeFilterBarBtn":"اغلاق خط ترشيح البيانات","a11yFilterBarDefButton":"ترشيح بيانات...","trueLabel":"True","conditionIsNot":"ليس","conditionIs":"يكون","ruleTitleTemplate":"قاعدة ${0}","waiRemoveRuleButtonTemplate":"ازالة قاعدة ${0}","and":"and","conditionLess":"‏أقل من‏","waiColumnSelectTemplate":"العمود للقاعدة ${0}","anycolumn":"أي عمود","filterDefDialogTitle":"‏ترشيح البيانات‏","waiConditionSelectTemplate":"الشرط للعمود ${0}","waiFilterButton":"احالة ترشيح البيانات","statusTipTitle":"خط ترشيح البيانات","statusTipRelPre":"مطابقة","anyColumnOption":"أي عمود","conditionSelectLabel":"الشرط","cancelButton":"الغاء","conditionNotStartWith":"لا يبدأ بـ","conditionEndWith":"ينتهي بالحروف","statusTipTitleNoFilter":"خط ترشيح البيانات","columnSelectLabel":"العمود","conditionNotContain":"لا يتضمن","clearButton":"محو","conditionLargerEqual":"أكبر من أو يساوي","any":"أي","relationMsgFront":"مطابقة","statusTipHeaderColumn":"العمود","defaultItemsName":"البنود","conditionEqual":"يساوي","relationAny":"أي قواعد","trueLabelEditable":"تم الفحص","or":"أو","filterBarMsgHasFilterTemplate":"${0} من ${1} ${2} عرض.","rangeTo":"الى","conditionStartsWith":"يبدأ بالحروف","waiRelAny":"مطابقة أي من القواعد التالية:","statusTipRelPost":"قواعد.","relationMsgTail":"","filterBarClearButton":"محو ترشيح البيانات","incompleteRuleTip":"هذه القاعدة غير تامة.","conditionLessEqual":"أقل من أو يساوي","waiFilterBarClearButton":"محو ترشيح البيانات","conditionAfter":"بعد","statusTipHeaderCondition":"قواعد","falseLabel":"خطأ","filterButton":"‏ترشيح البيانات‏","clearFilterDialogTitle":"محو ترشيح البيانات","statusTipTitleHasFilter":"‏ترشيح البيانات‏","addRuleButton":"اضافة قاعدة","waiAddRuleButton":"اضافة قاعدة جديدة","waiClearButton":"محو ترشيح البيانات","conditionNotEqual":"غير مساوي الى","conditionNotEndWith":"لا ينتهي بـ","rangeTemplate":"من ${0} الى ${1}","removeRuleButton":"ازالة قاعدة","waiFilterBarDefButton":"ترشيح بيانات الجدول","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ar/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ar/Pagination.js
new file mode 100644
index 0000000..54332d4
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ar/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"اذهب الى صفحة خاصة","prevTip":"الصفحة السابقة","pageCountIndication":" (${0} صفحات)","pageStepLabelTemplate":"صفحة ${0}","descTemplate":"${2} - ${3} من ${1} ${0}","lastTip":"الصفحة الأخيرة","nextTip":"الصفحة التالية","pageSizeLabelTemplate":"${0} بنود لكل صفحة","dialogCancel":"الغاء","itemTitle":"البنود","dialogConfirm":"بدء","firstTip":"الصفحة الأولى","allItemsLabelTemplate":"كل البنود","dialogIndication":"تحديد رقم الصفحة","dialogTitle":"اذهب الى صفحة"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ar/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ar/Pagination.xd.js
new file mode 100644
index 0000000..6c54103
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ar/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.ar.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.ar.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "ar", ({"gotoButtonTitle":"اذهب الى صفحة خاصة","prevTip":"الصفحة السابقة","pageCountIndication":" (${0} صفحات)","pageStepLabelTemplate":"صفحة ${0}","descTemplate":"${2} - ${3} من ${1} ${0}","lastTip":"الصفحة الأخيرة","nextTip":"الصفحة التالية","pageSizeLabelTemplate":"${0} بنود لكل صفحة","dialogCancel":"الغاء","itemTitle":"البنود","dialogConfirm":"بدء","firstTip":"الصفحة الأولى","allItemsLabelTemplate":"كل البنود","dialogIndication":"تحديد رقم الصفحة","dialogTitle":"اذهب الى صفحة"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ca/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ca/EnhancedGrid.js
new file mode 100644
index 0000000..a66056d
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ca/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Descendent","ascending":"Ascendent","nestedSort":"Ordre imbricat","unsorted":"No ordenis aquesta finestra","singleSort":"Ordre únic","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ca/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ca/EnhancedGrid.xd.js
new file mode 100644
index 0000000..ad62f3d
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ca/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.ca.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.ca.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "ca", ({"descending":"Descendent","ascending":"Ascendent","nestedSort":"Ordre imbricat","unsorted":"No ordenis aquesta finestra","singleSort":"Ordre únic","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ca/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ca/Filter.js
new file mode 100644
index 0000000..4ce12a1
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ca/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"abans","filterBarDefButton":"Defineix filtre","filterBarMsgNoFilterTemplate":"No s'ha aplicat cap filtre","conditionContains":"conté","clearFilterMsg":"Això eliminarà el filtre i mostrarà tots els registres disponibles.","all":"tot","waiValueBoxTemplate":"Especifiqueu el valor de filtre per a la regla ${0}","conditionRange":"interval","waiCancelButton":"Cancel·la aquest diàleg","relationAll":"totes les regles","conditionLarger":"és més que","valueBoxLabel":"Valor","statusTipMsg":"Feu clic aquí a la barra de filtre per filtrar els valors a ${0}.","waiRelAll":"Fes coincidir totes les regles següents:","closeFilterBarBtn":"Tancar la barra de filtre","a11yFilterBarDefButton":"Filtre...","trueLabel":"Cert","conditionIsNot":"no és","conditionIs":"és","ruleTitleTemplate":"Regla ${0}","waiRemoveRuleButtonTemplate":"Elimina la regla ${0}","and":"i","conditionLess":"és menys que","waiColumnSelectTemplate":"Columna per a la regla ${0}","anycolumn":"qualsevol columna","filterDefDialogTitle":"Filtre","waiConditionSelectTemplate":"Condició per a la regla ${0}","waiFilterButton":"Envia el filtre","statusTipTitle":"Barra de filtre","statusTipRelPre":"Coincidència","anyColumnOption":"Qualsevol columna","conditionSelectLabel":"Condició","cancelButton":"Cancel·la","conditionNotStartWith":"no comença per","conditionEndWith":"acaba per","statusTipTitleNoFilter":"Barra de filtre","columnSelectLabel":"Columna","conditionNotContain":"no conté","clearButton":"Esborra","conditionLargerEqual":"és més o igual que","any":"qualsevol","relationMsgFront":"Coincidència","statusTipHeaderColumn":"Columna","defaultItemsName":"elements","conditionEqual":"igual que","relationAny":"qualsevol regla","trueLabelEditable":"Seleccionat","or":"o","filterBarMsgHasFilterTemplate":"Es mostren ${0} de ${1} ${2}.","rangeTo":"a","conditionStartsWith":"comença per","waiRelAny":"Fes coincidir qualsevol de les regles següents:","statusTipRelPost":"regles.","relationMsgTail":"","filterBarClearButton":"Netejar filtre","incompleteRuleTip":"Aquesta regla no està completa","conditionLessEqual":"és menys o igual que","waiFilterBarClearButton":"Neteja el filtre","conditionAfter":"després","statusTipHeaderCondition":"Regles","falseLabel":"Fals","filterButton":"Filtre","clearFilterDialogTitle":"Netejar el filtre","statusTipTitleHasFilter":"Filtre","addRuleButton":"Afegeix regla","waiAddRuleButton":"Afegeix una regla nova","waiClearButton":"Neteja el filtre","conditionNotEqual":"no és igual que","conditionNotEndWith":"no acaba per","rangeTemplate":"de ${0} a ${1}","removeRuleButton":"Elimina regla","waiFilterBarDefButton":"Filtra la taula","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ca/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ca/Filter.xd.js
new file mode 100644
index 0000000..0b45282
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ca/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.ca.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.ca.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "ca", ({"conditionBefore":"abans","filterBarDefButton":"Defineix filtre","filterBarMsgNoFilterTemplate":"No s'ha aplicat cap filtre","conditionContains":"conté","clearFilterMsg":"Això eliminarà el filtre i mostrarà tots els registres disponibles.","all":"tot","waiValueBoxTemplate":"Especifiqueu el valor de filtre per a la regla ${0}","conditionRange":"interval","waiCancelButton":"Cancel·la aquest diàleg","relationAll":"totes les regles","conditionLarger":"és més que","valueBoxLabel":"Valor","statusTipMsg":"Feu clic aquí a la barra de filtre per filtrar els valors a ${0}.","waiRelAll":"Fes coincidir totes les regles següents:","closeFilterBarBtn":"Tancar la barra de filtre","a11yFilterBarDefButton":"Filtre...","trueLabel":"Cert","conditionIsNot":"no és","conditionIs":"és","ruleTitleTemplate":"Regla ${0}","waiRemoveRuleButtonTemplate":"Elimina la regla ${0}","and":"i","conditionLess":"és menys que","waiColumnSelectTemplate":"Columna per a la regla ${0}","anycolumn":"qualsevol columna","filterDefDialogTitle":"Filtre","waiConditionSelectTemplate":"Condició per a la regla ${0}","waiFilterButton":"Envia el filtre","statusTipTitle":"Barra de filtre","statusTipRelPre":"Coincidència","anyColumnOption":"Qualsevol columna","conditionSelectLabel":"Condició","cancelButton":"Cancel·la","conditionNotStartWith":"no comença per","conditionEndWith":"acaba per","statusTipTitleNoFilter":"Barra de filtre","columnSelectLabel":"Columna","conditionNotContain":"no conté","clearButton":"Esborra","conditionLargerEqual":"és més o igual que","any":"qualsevol","relationMsgFront":"Coincidència","statusTipHeaderColumn":"Columna","defaultItemsName":"elements","conditionEqual":"igual que","relationAny":"qualsevol regla","trueLabelEditable":"Seleccionat","or":"o","filterBarMsgHasFilterTemplate":"Es mostren ${0} de ${1} ${2}.","rangeTo":"a","conditionStartsWith":"comença per","waiRelAny":"Fes coincidir qualsevol de les regles següents:","statusTipRelPost":"regles.","relationMsgTail":"","filterBarClearButton":"Netejar filtre","incompleteRuleTip":"Aquesta regla no està completa","conditionLessEqual":"és menys o igual que","waiFilterBarClearButton":"Neteja el filtre","conditionAfter":"després","statusTipHeaderCondition":"Regles","falseLabel":"Fals","filterButton":"Filtre","clearFilterDialogTitle":"Netejar el filtre","statusTipTitleHasFilter":"Filtre","addRuleButton":"Afegeix regla","waiAddRuleButton":"Afegeix una regla nova","waiClearButton":"Neteja el filtre","conditionNotEqual":"no és igual que","conditionNotEndWith":"no acaba per","rangeTemplate":"de ${0} a ${1}","removeRuleButton":"Elimina regla","waiFilterBarDefButton":"Filtra la taula","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ca/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ca/Pagination.js
new file mode 100644
index 0000000..f85c977
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ca/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Vés a una pàgina específica","prevTip":"Pàgina anterior","pageCountIndication":" (${0} pàgines)","pageStepLabelTemplate":"Pàgina ${0}","descTemplate":"${2} - ${3} de ${1} ${0}","lastTip":"Darrera pàgina","nextTip":"Pàgina següent","pageSizeLabelTemplate":"${0} elements per pàgina","dialogCancel":"Cancel·la","itemTitle":"elements","dialogConfirm":"Vés-hi","firstTip":"Primera pàgina","allItemsLabelTemplate":"Tots els elements","dialogIndication":"Especifiqueu el número de pàgina","dialogTitle":"Vés a pàgina"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ca/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ca/Pagination.xd.js
new file mode 100644
index 0000000..f3c9ced
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ca/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.ca.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.ca.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "ca", ({"gotoButtonTitle":"Vés a una pàgina específica","prevTip":"Pàgina anterior","pageCountIndication":" (${0} pàgines)","pageStepLabelTemplate":"Pàgina ${0}","descTemplate":"${2} - ${3} de ${1} ${0}","lastTip":"Darrera pàgina","nextTip":"Pàgina següent","pageSizeLabelTemplate":"${0} elements per pàgina","dialogCancel":"Cancel·la","itemTitle":"elements","dialogConfirm":"Vés-hi","firstTip":"Primera pàgina","allItemsLabelTemplate":"Tots els elements","dialogIndication":"Especifiqueu el número de pàgina","dialogTitle":"Vés a pàgina"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/cs/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/cs/EnhancedGrid.js
new file mode 100644
index 0000000..13c7069
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/cs/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Sestupně","ascending":"Vzestupně","nestedSort":"Vnořené řazení","unsorted":"Tento sloupec neřadit","singleSort":"Jednoduché řazení","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/cs/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/cs/EnhancedGrid.xd.js
new file mode 100644
index 0000000..4d827cb
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/cs/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.cs.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.cs.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "cs", ({"descending":"Sestupně","ascending":"Vzestupně","nestedSort":"Vnořené řazení","unsorted":"Tento sloupec neřadit","singleSort":"Jednoduché řazení","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/cs/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/cs/Filter.js
new file mode 100644
index 0000000..3e8a592
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/cs/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"před","filterBarDefButton":"Definovat filtr","filterBarMsgNoFilterTemplate":"Není použit žádný filtr","conditionContains":"obsahuje","clearFilterMsg":"Tato akce odebere filtr a zobrazí se všechny dostupné záznamy.","all":"vše","waiValueBoxTemplate":"Zadat hodnotu filtru pro pravidlo ${0}","conditionRange":"rozsah","waiCancelButton":"Zrušit toto dialogové okno","relationAll":"všechna pravidla","conditionLarger":"je větší než","valueBoxLabel":"Hodnota","statusTipMsg":"Klepnutím sem na panel filtru provedete filtrování podle hodnoty pro ${0}.","waiRelAll":"Vyhovovat všem následujícím pravidlům:","closeFilterBarBtn":"Zavřít panel filtru","a11yFilterBarDefButton":"Filtrovat...","trueLabel":"Pravda","conditionIsNot":"není","conditionIs":"je","ruleTitleTemplate":"Pravidlo ${0}","waiRemoveRuleButtonTemplate":"Odebrat pravidlo ${0}","and":"a","conditionLess":"je menší než","waiColumnSelectTemplate":"Sloupec pravidla ${0}","anycolumn":"libovolný sloupec","filterDefDialogTitle":"Filtr","waiConditionSelectTemplate":"Podmínka pravidla ${0}","waiFilterButton":"Odeslat tento filtr","statusTipTitle":"Panel filtru","statusTipRelPre":"Shoda","anyColumnOption":"Libovolné sloupec","conditionSelectLabel":"Podmínka","cancelButton":"Storno","conditionNotStartWith":"nezačíná na","conditionEndWith":"končí na","statusTipTitleNoFilter":"Panel filtru","columnSelectLabel":"Sloupec","conditionNotContain":"neobsahuje","clearButton":"Vymazat","conditionLargerEqual":"větší nebo rovno","any":"libovolné","relationMsgFront":"Shoda","statusTipHeaderColumn":"Sloupec","defaultItemsName":"položek","conditionEqual":"rovná se","relationAny":"libovolné pravidlo","trueLabelEditable":"Zaškrtnuto","or":"nebo","filterBarMsgHasFilterTemplate":"Zobrazeno ${0} z ${1} ${2}.","rangeTo":"do","conditionStartsWith":"začíná na","waiRelAny":"Vyhovovat libovolnému z následujících pravidel:","statusTipRelPost":"pravidel.","relationMsgTail":"","filterBarClearButton":"Vymazat filtr","incompleteRuleTip":"Toto pravidlo není úplné.","conditionLessEqual":"menší nebo rovno","waiFilterBarClearButton":"Vymazat tento filtr","conditionAfter":"po","statusTipHeaderCondition":"Pravidla","falseLabel":"Nepravda","filterButton":"Filtrovat","clearFilterDialogTitle":"Vymazat filtr","statusTipTitleHasFilter":"Filtr","addRuleButton":"Přidat pravidlo","waiAddRuleButton":"Přidat nové pravidlo","waiClearButton":"Vymazat tento filtr","conditionNotEqual":"nerovná se","conditionNotEndWith":"nekončí na","rangeTemplate":"od ${0} do ${1}","removeRuleButton":"Odebrat pravidlo","waiFilterBarDefButton":"Filtrovat tabulku","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/cs/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/cs/Filter.xd.js
new file mode 100644
index 0000000..4543b76
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/cs/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.cs.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.cs.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "cs", ({"conditionBefore":"před","filterBarDefButton":"Definovat filtr","filterBarMsgNoFilterTemplate":"Není použit žádný filtr","conditionContains":"obsahuje","clearFilterMsg":"Tato akce odebere filtr a zobrazí se všechny dostupné záznamy.","all":"vše","waiValueBoxTemplate":"Zadat hodnotu filtru pro pravidlo ${0}","conditionRange":"rozsah","waiCancelButton":"Zrušit toto dialogové okno","relationAll":"všechna pravidla","conditionLarger":"je větší než","valueBoxLabel":"Hodnota","statusTipMsg":"Klepnutím sem na panel filtru provedete filtrování podle hodnoty pro ${0}.","waiRelAll":"Vyhovovat všem následujícím pravidlům:","closeFilterBarBtn":"Zavřít panel filtru","a11yFilterBarDefButton":"Filtrovat...","trueLabel":"Pravda","conditionIsNot":"není","conditionIs":"je","ruleTitleTemplate":"Pravidlo ${0}","waiRemoveRuleButtonTemplate":"Odebrat pravidlo ${0}","and":"a","conditionLess":"je menší než","waiColumnSelectTemplate":"Sloupec pravidla ${0}","anycolumn":"libovolný sloupec","filterDefDialogTitle":"Filtr","waiConditionSelectTemplate":"Podmínka pravidla ${0}","waiFilterButton":"Odeslat tento filtr","statusTipTitle":"Panel filtru","statusTipRelPre":"Shoda","anyColumnOption":"Libovolné sloupec","conditionSelectLabel":"Podmínka","cancelButton":"Storno","conditionNotStartWith":"nezačíná na","conditionEndWith":"končí na","statusTipTitleNoFilter":"Panel filtru","columnSelectLabel":"Sloupec","conditionNotContain":"neobsahuje","clearButton":"Vymazat","conditionLargerEqual":"větší nebo rovno","any":"libovolné","relationMsgFront":"Shoda","statusTipHeaderColumn":"Sloupec","defaultItemsName":"položek","conditionEqual":"rovná se","relationAny":"libovolné pravidlo","trueLabelEditable":"Zaškrtnuto","or":"nebo","filterBarMsgHasFilterTemplate":"Zobrazeno ${0} z ${1} ${2}.","rangeTo":"do","conditionStartsWith":"začíná na","waiRelAny":"Vyhovovat libovolnému z následujících pravidel:","statusTipRelPost":"pravidel.","relationMsgTail":"","filterBarClearButton":"Vymazat filtr","incompleteRuleTip":"Toto pravidlo není úplné.","conditionLessEqual":"menší nebo rovno","waiFilterBarClearButton":"Vymazat tento filtr","conditionAfter":"po","statusTipHeaderCondition":"Pravidla","falseLabel":"Nepravda","filterButton":"Filtrovat","clearFilterDialogTitle":"Vymazat filtr","statusTipTitleHasFilter":"Filtr","addRuleButton":"Přidat pravidlo","waiAddRuleButton":"Přidat nové pravidlo","waiClearButton":"Vymazat tento filtr","conditionNotEqual":"nerovná se","conditionNotEndWith":"nekončí na","rangeTemplate":"od ${0} do ${1}","removeRuleButton":"Odebrat pravidlo","waiFilterBarDefButton":"Filtrovat tabulku","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/cs/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/cs/Pagination.js
new file mode 100644
index 0000000..a02d726
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/cs/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Přejít na určitou stránku","prevTip":"Předchozí stránka","pageCountIndication":" (Počet stránek: ${0})","pageStepLabelTemplate":"Stránka ${0}","descTemplate":"${2} - ${3} z ${1} ${0}","lastTip":"Poslední stránka","nextTip":"Další stránka","pageSizeLabelTemplate":"${0} položek na stránce","dialogCancel":"Storno","itemTitle":"položek","dialogConfirm":"Přejít","firstTip":"První stránka","allItemsLabelTemplate":"Všechny položky","dialogIndication":"Zadat číslo stránky","dialogTitle":"Přejít na stránku"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/cs/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/cs/Pagination.xd.js
new file mode 100644
index 0000000..77d1dc6
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/cs/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.cs.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.cs.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "cs", ({"gotoButtonTitle":"Přejít na určitou stránku","prevTip":"Předchozí stránka","pageCountIndication":" (Počet stránek: ${0})","pageStepLabelTemplate":"Stránka ${0}","descTemplate":"${2} - ${3} z ${1} ${0}","lastTip":"Poslední stránka","nextTip":"Další stránka","pageSizeLabelTemplate":"${0} položek na stránce","dialogCancel":"Storno","itemTitle":"položek","dialogConfirm":"Přejít","firstTip":"První stránka","allItemsLabelTemplate":"Všechny položky","dialogIndication":"Zadat číslo stránky","dialogTitle":"Přejít na stránku"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/da/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/da/EnhancedGrid.js
new file mode 100644
index 0000000..6d99b51
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/da/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Faldende","ascending":"Stigende","nestedSort":"Indlejret sortering","unsorted":"Sortér ikke denne kolonne","singleSort":"Enkel sortering","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/da/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/da/EnhancedGrid.xd.js
new file mode 100644
index 0000000..b8b3601
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/da/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.da.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.da.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "da", ({"descending":"Faldende","ascending":"Stigende","nestedSort":"Indlejret sortering","unsorted":"Sortér ikke denne kolonne","singleSort":"Enkel sortering","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/da/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/da/Filter.js
new file mode 100644
index 0000000..5e520b8
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/da/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"før","filterBarDefButton":"Definér filter","filterBarMsgNoFilterTemplate":"Intet filter anvendt","conditionContains":"indeholder","clearFilterMsg":"Denne funktion fjerner filtret og viser alle tilgængelige records.","all":"alle","waiValueBoxTemplate":"Angiv værdi for filtrering for regel ${0}","conditionRange":"område","waiCancelButton":"Annullér denne dialogboks","relationAll":"alle regler","conditionLarger":"er større end","valueBoxLabel":"Værdi","statusTipMsg":"Klik på filterlinjen for at filtrere efter værdier i ${0}.","waiRelAll":"Skal matche følgende regler:","closeFilterBarBtn":"Luk filterlinjen","a11yFilterBarDefButton":"Filtrér...","trueLabel":"Sand","conditionIsNot":"er ikke","conditionIs":"er","ruleTitleTemplate":"Regel ${0}","waiRemoveRuleButtonTemplate":"Fjern reglel ${0}","and":"og","conditionLess":"er mindre end","waiColumnSelectTemplate":"Kolonne for regel ${0}","anycolumn":"vilkårlig kolonne","filterDefDialogTitle":"Filtrér","waiConditionSelectTemplate":"Betingelse for regel ${0}","waiFilterButton":"Afsend filtret","statusTipTitle":"Filterlinje","statusTipRelPre":"Match","anyColumnOption":"Vilkårlig kolonne","conditionSelectLabel":"Betingelse","cancelButton":"Annullér","conditionNotStartWith":"begynder ikke med","conditionEndWith":"slutter med","statusTipTitleNoFilter":"Filterlinje","columnSelectLabel":"Kolonne","conditionNotContain":"indeholder ikke","clearButton":"Ryd","conditionLargerEqual":"større end eller lig med","any":"nogle af","relationMsgFront":"Match","statusTipHeaderColumn":"Kolonne","defaultItemsName":"elementer","conditionEqual":"er lig med","relationAny":"nogle regler","trueLabelEditable":"Markeret","or":"eller","filterBarMsgHasFilterTemplate":"${0} af ${1} ${2} vist.","rangeTo":"til","conditionStartsWith":"begynder med","waiRelAny":"Skal matche nogle af følgende regler:","statusTipRelPost":"regler.","relationMsgTail":"","filterBarClearButton":"Ryd filter","incompleteRuleTip":"Reglen er ikke komplet.","conditionLessEqual":"mindre end eller lig med","waiFilterBarClearButton":"Ryd filtret","conditionAfter":"efter","statusTipHeaderCondition":"Regler","falseLabel":"Falsk","filterButton":"Filtrér","clearFilterDialogTitle":"Ryd filter","statusTipTitleHasFilter":"Filtrér","addRuleButton":"Tilføj regel","waiAddRuleButton":"Tilføj en ny regel","waiClearButton":"Ryd filtret","conditionNotEqual":"er ikke lig med","conditionNotEndWith":"slutter ikke med","rangeTemplate":"fra ${0} til ${1}","removeRuleButton":"Fjern regel","waiFilterBarDefButton":"Filtrér tabellen","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/da/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/da/Filter.xd.js
new file mode 100644
index 0000000..3206081
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/da/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.da.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.da.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "da", ({"conditionBefore":"før","filterBarDefButton":"Definér filter","filterBarMsgNoFilterTemplate":"Intet filter anvendt","conditionContains":"indeholder","clearFilterMsg":"Denne funktion fjerner filtret og viser alle tilgængelige records.","all":"alle","waiValueBoxTemplate":"Angiv værdi for filtrering for regel ${0}","conditionRange":"område","waiCancelButton":"Annullér denne dialogboks","relationAll":"alle regler","conditionLarger":"er større end","valueBoxLabel":"Værdi","statusTipMsg":"Klik på filterlinjen for at filtrere efter værdier i ${0}.","waiRelAll":"Skal matche følgende regler:","closeFilterBarBtn":"Luk filterlinjen","a11yFilterBarDefButton":"Filtrér...","trueLabel":"Sand","conditionIsNot":"er ikke","conditionIs":"er","ruleTitleTemplate":"Regel ${0}","waiRemoveRuleButtonTemplate":"Fjern reglel ${0}","and":"og","conditionLess":"er mindre end","waiColumnSelectTemplate":"Kolonne for regel ${0}","anycolumn":"vilkårlig kolonne","filterDefDialogTitle":"Filtrér","waiConditionSelectTemplate":"Betingelse for regel ${0}","waiFilterButton":"Afsend filtret","statusTipTitle":"Filterlinje","statusTipRelPre":"Match","anyColumnOption":"Vilkårlig kolonne","conditionSelectLabel":"Betingelse","cancelButton":"Annullér","conditionNotStartWith":"begynder ikke med","conditionEndWith":"slutter med","statusTipTitleNoFilter":"Filterlinje","columnSelectLabel":"Kolonne","conditionNotContain":"indeholder ikke","clearButton":"Ryd","conditionLargerEqual":"større end eller lig med","any":"nogle af","relationMsgFront":"Match","statusTipHeaderColumn":"Kolonne","defaultItemsName":"elementer","conditionEqual":"er lig med","relationAny":"nogle regler","trueLabelEditable":"Markeret","or":"eller","filterBarMsgHasFilterTemplate":"${0} af ${1} ${2} vist.","rangeTo":"til","conditionStartsWith":"begynder med","waiRelAny":"Skal matche nogle af følgende regler:","statusTipRelPost":"regler.","relationMsgTail":"","filterBarClearButton":"Ryd filter","incompleteRuleTip":"Reglen er ikke komplet.","conditionLessEqual":"mindre end eller lig med","waiFilterBarClearButton":"Ryd filtret","conditionAfter":"efter","statusTipHeaderCondition":"Regler","falseLabel":"Falsk","filterButton":"Filtrér","clearFilterDialogTitle":"Ryd filter","statusTipTitleHasFilter":"Filtrér","addRuleButton":"Tilføj regel","waiAddRuleButton":"Tilføj en ny regel","waiClearButton":"Ryd filtret","conditionNotEqual":"er ikke lig med","conditionNotEndWith":"slutter ikke med","rangeTemplate":"fra ${0} til ${1}","removeRuleButton":"Fjern regel","waiFilterBarDefButton":"Filtrér tabellen","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/da/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/da/Pagination.js
new file mode 100644
index 0000000..689f4a1
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/da/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Gå til en bestemt side","prevTip":"Forrige side","pageCountIndication":" (${0} sider)","pageStepLabelTemplate":"Side ${0}","descTemplate":"${2}-${3} af ${1} ${0}","lastTip":"Sidste side","nextTip":"Næste side","pageSizeLabelTemplate":"${0} elementer pr. side","dialogCancel":"Annullér","itemTitle":"elementer","dialogConfirm":"Udfør","firstTip":"Første side","allItemsLabelTemplate":"Alle elementer","dialogIndication":"Angiv sidenummeret","dialogTitle":"Gå til side"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/da/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/da/Pagination.xd.js
new file mode 100644
index 0000000..ad0cff9
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/da/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.da.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.da.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "da", ({"gotoButtonTitle":"Gå til en bestemt side","prevTip":"Forrige side","pageCountIndication":" (${0} sider)","pageStepLabelTemplate":"Side ${0}","descTemplate":"${2}-${3} af ${1} ${0}","lastTip":"Sidste side","nextTip":"Næste side","pageSizeLabelTemplate":"${0} elementer pr. side","dialogCancel":"Annullér","itemTitle":"elementer","dialogConfirm":"Udfør","firstTip":"Første side","allItemsLabelTemplate":"Alle elementer","dialogIndication":"Angiv sidenummeret","dialogTitle":"Gå til side"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/de/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/de/EnhancedGrid.js
new file mode 100644
index 0000000..962c9f3
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/de/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Absteigend","ascending":"Aufsteigend","nestedSort":"Verschachtelte Sortierung","unsorted":"Spalte nicht sortieren","singleSort":"Einfache Sortierung","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/de/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/de/EnhancedGrid.xd.js
new file mode 100644
index 0000000..e4927ec
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/de/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.de.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.de.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "de", ({"descending":"Absteigend","ascending":"Aufsteigend","nestedSort":"Verschachtelte Sortierung","unsorted":"Spalte nicht sortieren","singleSort":"Einfache Sortierung","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/de/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/de/Filter.js
new file mode 100644
index 0000000..2e40a8b
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/de/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"vor","filterBarDefButton":"Filter definieren","filterBarMsgNoFilterTemplate":"Kein Filter angewendet","conditionContains":"enthält","clearFilterMsg":"Dadurch wird der Filter gelöscht und alle verfügbaren Einträge werden angezeigt. ","all":"alle","waiValueBoxTemplate":"Wert zum Filtern für Regel ${0} eingeben","conditionRange":"Bereich","waiCancelButton":"Dieses Dialogfenster abbrechen","relationAll":"alle Regeln","conditionLarger":"größer als","valueBoxLabel":"Wert","statusTipMsg":"Klicken Sie hier auf die Filterleiste, um die Werte in ${0} zu filtern.","waiRelAll":"Übereinstimmung mit allen folgenden Regeln: ","closeFilterBarBtn":"Filterleiste schließen","a11yFilterBarDefButton":"Filtern...","trueLabel":"Wahr","conditionIsNot":"ist nicht","conditionIs":"ist","ruleTitleTemplate":"Regel ${0}","waiRemoveRuleButtonTemplate":"Regel ${0} entfernen","and":"und","conditionLess":"kleiner als","waiColumnSelectTemplate":"Spalte für Regel ${0}","anycolumn":"eine Spalte","filterDefDialogTitle":"Filter","waiConditionSelectTemplate":"Bedingung für Regel ${0}","waiFilterButton":"Filter übergeben","statusTipTitle":"Filterleiste","statusTipRelPre":"Übereinstimmung","anyColumnOption":"Eine Spalte","conditionSelectLabel":"Bedingung ","cancelButton":"Abbrechen","conditionNotStartWith":"beginnt nicht mit","conditionEndWith":"endet mit","statusTipTitleNoFilter":"Filterleiste","columnSelectLabel":"Spalte","conditionNotContain":"enthält nicht","clearButton":"Löschen","conditionLargerEqual":"größer-gleich","any":"ein(e/r)","relationMsgFront":"Übereinstimmung","statusTipHeaderColumn":"Spalte","defaultItemsName":"Elemente ","conditionEqual":"gleich","relationAny":"eine Regel","trueLabelEditable":"Ausgewählt","or":"oder","filterBarMsgHasFilterTemplate":"${0} von ${1} ${2} angezeigt. ","rangeTo":"bis","conditionStartsWith":"beginnt mit","waiRelAny":"Übereinstimmung mit einer der folgenden Regeln: ","statusTipRelPost":"Regeln.","relationMsgTail":"","filterBarClearButton":"Filter löschen","incompleteRuleTip":"Diese Regel ist nicht vollständig. ","conditionLessEqual":"kleiner-gleich","waiFilterBarClearButton":"Filter löschen","conditionAfter":"nach","statusTipHeaderCondition":"Regeln","falseLabel":"Falsch","filterButton":"Filter","clearFilterDialogTitle":"Filter löschen","statusTipTitleHasFilter":"Filter","addRuleButton":"Regel hinzufügen","waiAddRuleButton":"Neue Regel hinzufügen","waiClearButton":"Filter löschen","conditionNotEqual":"ungleich","conditionNotEndWith":"endet nicht mit","rangeTemplate":"von ${0} bis ${1}","removeRuleButton":"Regel entfernen","waiFilterBarDefButton":"Tabelle filtern","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/de/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/de/Filter.xd.js
new file mode 100644
index 0000000..eb7fb13
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/de/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.de.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.de.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "de", ({"conditionBefore":"vor","filterBarDefButton":"Filter definieren","filterBarMsgNoFilterTemplate":"Kein Filter angewendet","conditionContains":"enthält","clearFilterMsg":"Dadurch wird der Filter gelöscht und alle verfügbaren Einträge werden angezeigt. ","all":"alle","waiValueBoxTemplate":"Wert zum Filtern für Regel ${0} eingeben","conditionRange":"Bereich","waiCancelButton":"Dieses Dialogfenster abbrechen","relationAll":"alle Regeln","conditionLarger":"größer als","valueBoxLabel":"Wert","statusTipMsg":"Klicken Sie hier auf die Filterleiste, um die Werte in ${0} zu filtern.","waiRelAll":"Übereinstimmung mit allen folgenden Regeln: ","closeFilterBarBtn":"Filterleiste schließen","a11yFilterBarDefButton":"Filtern...","trueLabel":"Wahr","conditionIsNot":"ist nicht","conditionIs":"ist","ruleTitleTemplate":"Regel ${0}","waiRemoveRuleButtonTemplate":"Regel ${0} entfernen","and":"und","conditionLess":"kleiner als","waiColumnSelectTemplate":"Spalte für Regel ${0}","anycolumn":"eine Spalte","filterDefDialogTitle":"Filter","waiConditionSelectTemplate":"Bedingung für Regel ${0}","waiFilterButton":"Filter übergeben","statusTipTitle":"Filterleiste","statusTipRelPre":"Übereinstimmung","anyColumnOption":"Eine Spalte","conditionSelectLabel":"Bedingung ","cancelButton":"Abbrechen","conditionNotStartWith":"beginnt nicht mit","conditionEndWith":"endet mit","statusTipTitleNoFilter":"Filterleiste","columnSelectLabel":"Spalte","conditionNotContain":"enthält nicht","clearButton":"Löschen","conditionLargerEqual":"größer-gleich","any":"ein(e/r)","relationMsgFront":"Übereinstimmung","statusTipHeaderColumn":"Spalte","defaultItemsName":"Elemente ","conditionEqual":"gleich","relationAny":"eine Regel","trueLabelEditable":"Ausgewählt","or":"oder","filterBarMsgHasFilterTemplate":"${0} von ${1} ${2} angezeigt. ","rangeTo":"bis","conditionStartsWith":"beginnt mit","waiRelAny":"Übereinstimmung mit einer der folgenden Regeln: ","statusTipRelPost":"Regeln.","relationMsgTail":"","filterBarClearButton":"Filter löschen","incompleteRuleTip":"Diese Regel ist nicht vollständig. ","conditionLessEqual":"kleiner-gleich","waiFilterBarClearButton":"Filter löschen","conditionAfter":"nach","statusTipHeaderCondition":"Regeln","falseLabel":"Falsch","filterButton":"Filter","clearFilterDialogTitle":"Filter löschen","statusTipTitleHasFilter":"Filter","addRuleButton":"Regel hinzufügen","waiAddRuleButton":"Neue Regel hinzufügen","waiClearButton":"Filter löschen","conditionNotEqual":"ungleich","conditionNotEndWith":"endet nicht mit","rangeTemplate":"von ${0} bis ${1}","removeRuleButton":"Regel entfernen","waiFilterBarDefButton":"Tabelle filtern","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/de/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/de/Pagination.js
new file mode 100644
index 0000000..cadd986
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/de/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Zu einer bestimmten Seite wechseln","prevTip":"Vorherige Seite","pageCountIndication":" (${0} Seiten)","pageStepLabelTemplate":"Seite ${0}","descTemplate":"${2} - ${3} von ${1} ${0}","lastTip":"Letzte Seite","nextTip":"Nächste Seite","pageSizeLabelTemplate":"${0} Elemente pro Seite","dialogCancel":"Abbrechen","itemTitle":"Elemente","dialogConfirm":"Start","firstTip":"Erste Seite","allItemsLabelTemplate":"Alle Elemente","dialogIndication":"Seitenzahl angeben","dialogTitle":"Zur Seite wechseln"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/de/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/de/Pagination.xd.js
new file mode 100644
index 0000000..c2e6591
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/de/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.de.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.de.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "de", ({"gotoButtonTitle":"Zu einer bestimmten Seite wechseln","prevTip":"Vorherige Seite","pageCountIndication":" (${0} Seiten)","pageStepLabelTemplate":"Seite ${0}","descTemplate":"${2} - ${3} von ${1} ${0}","lastTip":"Letzte Seite","nextTip":"Nächste Seite","pageSizeLabelTemplate":"${0} Elemente pro Seite","dialogCancel":"Abbrechen","itemTitle":"Elemente","dialogConfirm":"Start","firstTip":"Erste Seite","allItemsLabelTemplate":"Alle Elemente","dialogIndication":"Seitenzahl angeben","dialogTitle":"Zur Seite wechseln"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/el/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/el/EnhancedGrid.js
new file mode 100644
index 0000000..6d1bb53
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/el/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Φθίνουσα","ascending":"Αύξουσα","nestedSort":"Ένθετη ταξινόμηση","unsorted":"Χωρίς ταξινόμηση αυτής της στήλης","singleSort":"Απλή ταξινόμηση","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/el/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/el/EnhancedGrid.xd.js
new file mode 100644
index 0000000..957e3d5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/el/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.el.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.el.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "el", ({"descending":"Φθίνουσα","ascending":"Αύξουσα","nestedSort":"Ένθετη ταξινόμηση","unsorted":"Χωρίς ταξινόμηση αυτής της στήλης","singleSort":"Απλή ταξινόμηση","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/el/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/el/Filter.js
new file mode 100644
index 0000000..13398e9
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/el/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"πριν","filterBarDefButton":"Ορισμός φίλτρου","filterBarMsgNoFilterTemplate":"Δεν έχει εφαρμοστεί φίλτρο","conditionContains":"περιέχει","clearFilterMsg":"Με την επιλογή αυτή θα αφαιρεθεί το φίλτρο και θα εμφανιστούν όλες οι διαθέσιμες εγγραφές.","all":"όλα","waiValueBoxTemplate":"Καταχωρήστε τιμή φίλτρου για τον κανόνα ${0}","conditionRange":"εύρος","waiCancelButton":"Ακύρωση αυτού του πλαισίου διαλόγου","relationAll":"όλοι οι κανόνες","conditionLarger":"είναι μεγαλύτερο από","valueBoxLabel":"Τιμή","statusTipMsg":"Πατήστε στη γραμμή φίλτρου για φιλτράρισμα με βάση τις τιμές στο ${0}.","waiRelAll":"Αντιστοιχία με όλους τους παρακάτω κανόνες:","closeFilterBarBtn":"Κλείσιμο γραμμής φίλτρου","a11yFilterBarDefButton":"Φιλτράρισμα...","trueLabel":"Αληθές","conditionIsNot":"δεν είναι","conditionIs":"είναι","ruleTitleTemplate":"Κανόνας ${0}","waiRemoveRuleButtonTemplate":"Αφαίρεση κανόνα ${0}","and":"και","conditionLess":"είναι μικρότερο από","waiColumnSelectTemplate":"Στήλη για τον κανόνα ${0}","anycolumn":"οποιαδήποτε στήλη","filterDefDialogTitle":"Φίλτρο","waiConditionSelectTemplate":"Συνθήκη για τον κανόνα ${0}","waiFilterButton":"Υποβολή του φίλτρου","statusTipTitle":"Γραμμή φίλτρου","statusTipRelPre":"Αντιστοιχία","anyColumnOption":"Οποιαδήποτε στήλη","conditionSelectLabel":"Συνθήκη","cancelButton":"Ακύρωση","conditionNotStartWith":"δεν αρχίζει από","conditionEndWith":"τελειώνει σε","statusTipTitleNoFilter":"Γραμμή φίλτρου","columnSelectLabel":"Στήλη","conditionNotContain":"δεν περιέχει","clearButton":"Εκκαθάριση","conditionLargerEqual":"μεγαλύτερο ή ίσο","any":"οποιοδήποτε","relationMsgFront":"Αντιστοιχία","statusTipHeaderColumn":"Στήλη","defaultItemsName":"στοιχεία","conditionEqual":"ίσο","relationAny":"οποιοσδήποτε κανόνας","trueLabelEditable":"Επιλεγμένο","or":"ή","filterBarMsgHasFilterTemplate":"Εμφανίζονται ${0} από ${1} ${2}.","rangeTo":"έως","conditionStartsWith":"αρχίζει από","waiRelAny":"Αντιστοιχία με οποιονδήποτε από τους παρακάτω κανόνες:","statusTipRelPost":"κανόνες.","relationMsgTail":"","filterBarClearButton":"Εκκαθάριση φίλτρου","incompleteRuleTip":"Αυτός ο κανόνας δεν είναι πλήρης.","conditionLessEqual":"μικρότερο ή ίσο","waiFilterBarClearButton":"Εκκαθάριση του φίλτρου","conditionAfter":"μετά","statusTipHeaderCondition":"Κανόνες","falseLabel":"Ψευδές","filterButton":"Φίλτρο","clearFilterDialogTitle":"Εκκαθάριση φίλτρου","statusTipTitleHasFilter":"Φίλτρο","addRuleButton":"Προσθήκη κανόνα","waiAddRuleButton":"Προσθήκη νέου κανόνα","waiClearButton":"Εκκαθάριση του φίλτρου","conditionNotEqual":"όχι ίσο","conditionNotEndWith":"δεν τελειώνει σε","rangeTemplate":"από ${0} έως ${1}","removeRuleButton":"Αφαίρεση κανόνα","waiFilterBarDefButton":"Φιλτράρισμα του πίνακα","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/el/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/el/Filter.xd.js
new file mode 100644
index 0000000..819a44f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/el/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.el.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.el.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "el", ({"conditionBefore":"πριν","filterBarDefButton":"Ορισμός φίλτρου","filterBarMsgNoFilterTemplate":"Δεν έχει εφαρμοστεί φίλτρο","conditionContains":"περιέχει","clearFilterMsg":"Με την επιλογή αυτή θα αφαιρεθεί το φίλτρο και θα εμφανιστούν όλες οι διαθέσιμες εγγραφές.","all":"όλα","waiValueBoxTemplate":"Καταχωρήστε τιμή φίλτρου για τον κανόνα ${0}","conditionRange":"εύρος","waiCancelButton":"Ακύρωση αυτού του πλαισίου διαλόγου","relationAll":"όλοι οι κανόνες","conditionLarger":"είναι μεγαλύτερο από","valueBoxLabel":"Τιμή","statusTipMsg":"Πατήστε στη γραμμή φίλτρου για φιλτράρισμα με βάση τις τιμές στο ${0}.","waiRelAll":"Αντιστοιχία με όλους τους παρακάτω κανόνες:","closeFilterBarBtn":"Κλείσιμο γραμμής φίλτρου","a11yFilterBarDefButton":"Φιλτράρισμα...","trueLabel":"Αληθές","conditionIsNot":"δεν είναι","conditionIs":"είναι","ruleTitleTemplate":"Κανόνας ${0}","waiRemoveRuleButtonTemplate":"Αφαίρεση κανόνα ${0}","and":"και","conditionLess":"είναι μικρότερο από","waiColumnSelectTemplate":"Στήλη για τον κανόνα ${0}","anycolumn":"οποιαδήποτε στήλη","filterDefDialogTitle":"Φίλτρο","waiConditionSelectTemplate":"Συνθήκη για τον κανόνα ${0}","waiFilterButton":"Υποβολή του φίλτρου","statusTipTitle":"Γραμμή φίλτρου","statusTipRelPre":"Αντιστοιχία","anyColumnOption":"Οποιαδήποτε στήλη","conditionSelectLabel":"Συνθήκη","cancelButton":"Ακύρωση","conditionNotStartWith":"δεν αρχίζει από","conditionEndWith":"τελειώνει σε","statusTipTitleNoFilter":"Γραμμή φίλτρου","columnSelectLabel":"Στήλη","conditionNotContain":"δεν περιέχει","clearButton":"Εκκαθάριση","conditionLargerEqual":"μεγαλύτερο ή ίσο","any":"οποιοδήποτε","relationMsgFront":"Αντιστοιχία","statusTipHeaderColumn":"Στήλη","defaultItemsName":"στοιχεία","conditionEqual":"ίσο","relationAny":"οποιοσδήποτε κανόνας","trueLabelEditable":"Επιλεγμένο","or":"ή","filterBarMsgHasFilterTemplate":"Εμφανίζονται ${0} από ${1} ${2}.","rangeTo":"έως","conditionStartsWith":"αρχίζει από","waiRelAny":"Αντιστοιχία με οποιονδήποτε από τους παρακάτω κανόνες:","statusTipRelPost":"κανόνες.","relationMsgTail":"","filterBarClearButton":"Εκκαθάριση φίλτρου","incompleteRuleTip":"Αυτός ο κανόνας δεν είναι πλήρης.","conditionLessEqual":"μικρότερο ή ίσο","waiFilterBarClearButton":"Εκκαθάριση του φίλτρου","conditionAfter":"μετά","statusTipHeaderCondition":"Κανόνες","falseLabel":"Ψευδές","filterButton":"Φίλτρο","clearFilterDialogTitle":"Εκκαθάριση φίλτρου","statusTipTitleHasFilter":"Φίλτρο","addRuleButton":"Προσθήκη κανόνα","waiAddRuleButton":"Προσθήκη νέου κανόνα","waiClearButton":"Εκκαθάριση του φίλτρου","conditionNotEqual":"όχι ίσο","conditionNotEndWith":"δεν τελειώνει σε","rangeTemplate":"από ${0} έως ${1}","removeRuleButton":"Αφαίρεση κανόνα","waiFilterBarDefButton":"Φιλτράρισμα του πίνακα","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/el/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/el/Pagination.js
new file mode 100644
index 0000000..79e6365
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/el/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Μετάβαση σε συγκεκριμένη σελίδα","prevTip":"Προηγούμενη σελίδα","pageCountIndication":" (${0} σελίδες)","pageStepLabelTemplate":"Σελίδα ${0}","descTemplate":"${2} - ${3} από ${1} ${0}","lastTip":"Τελευταία σελίδα","nextTip":"Επόμενη σελίδα","pageSizeLabelTemplate":"${0} στοιχεία ανά σελίδα","dialogCancel":"Ακύρωση","itemTitle":"στοιχεία","dialogConfirm":"Μετάβαση","firstTip":"Πρώτη σελίδα","allItemsLabelTemplate":"Όλα τα στοιχεία","dialogIndication":"Καθορίστε τον αριθμό της σελίδας","dialogTitle":"Μετάβαση σε σελίδα"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/el/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/el/Pagination.xd.js
new file mode 100644
index 0000000..6ca69b4
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/el/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.el.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.el.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "el", ({"gotoButtonTitle":"Μετάβαση σε συγκεκριμένη σελίδα","prevTip":"Προηγούμενη σελίδα","pageCountIndication":" (${0} σελίδες)","pageStepLabelTemplate":"Σελίδα ${0}","descTemplate":"${2} - ${3} από ${1} ${0}","lastTip":"Τελευταία σελίδα","nextTip":"Επόμενη σελίδα","pageSizeLabelTemplate":"${0} στοιχεία ανά σελίδα","dialogCancel":"Ακύρωση","itemTitle":"στοιχεία","dialogConfirm":"Μετάβαση","firstTip":"Πρώτη σελίδα","allItemsLabelTemplate":"Όλα τα στοιχεία","dialogIndication":"Καθορίστε τον αριθμό της σελίδας","dialogTitle":"Μετάβαση σε σελίδα"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/es/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/es/EnhancedGrid.js
new file mode 100644
index 0000000..c74050a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/es/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Descendente","ascending":"Ascendente","nestedSort":"Orden anidado","unsorted":"No ordenar esta columna","singleSort":"Orden único","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/es/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/es/EnhancedGrid.xd.js
new file mode 100644
index 0000000..2dde8b7
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/es/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.es.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.es.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "es", ({"descending":"Descendente","ascending":"Ascendente","nestedSort":"Orden anidado","unsorted":"No ordenar esta columna","singleSort":"Orden único","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/es/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/es/Filter.js
new file mode 100644
index 0000000..f061920
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/es/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"antes","filterBarDefButton":"Definir filtro","filterBarMsgNoFilterTemplate":"No se aplica ningún filtro","conditionContains":"contiene","clearFilterMsg":"Eliminará el filtro y mostrará todos los registros disponibles.","all":"todas","waiValueBoxTemplate":"Especifique un valor para el filtro para la regla ${0}","conditionRange":"rango","waiCancelButton":"Cancelar este diálogo","relationAll":"todas las reglas","conditionLarger":"es superior que","valueBoxLabel":"Valor","statusTipMsg":"Pulse la barra de filtros para filtrar los valores de ${0}.","waiRelAll":"Coincide con todas las reglas siguientes:","closeFilterBarBtn":"Cerrar la barra de filtros","a11yFilterBarDefButton":"Filtrar...","trueLabel":"Verdadero","conditionIsNot":"no es","conditionIs":"es","ruleTitleTemplate":"Regla ${0}","waiRemoveRuleButtonTemplate":"Eliminar regla ${0}","and":"y","conditionLess":"es menor que","waiColumnSelectTemplate":"Columna para la regla ${0}","anycolumn":"cualquier columna","filterDefDialogTitle":"Filtro","waiConditionSelectTemplate":"Condición para la regla ${0}","waiFilterButton":"Enviar el filtro","statusTipTitle":"Barra de filtros","statusTipRelPre":"Coincide","anyColumnOption":"Cualquier columna","conditionSelectLabel":"Condición","cancelButton":"Cancelar","conditionNotStartWith":"no empieza por","conditionEndWith":"termina por","statusTipTitleNoFilter":"Barra de filtros","columnSelectLabel":"Columna","conditionNotContain":"no contiene","clearButton":"Borrar","conditionLargerEqual":"superior o igual que","any":"cualquiera","relationMsgFront":"Coincide","statusTipHeaderColumn":"Columna","defaultItemsName":"elementos","conditionEqual":"igual","relationAny":"cualquier regla","trueLabelEditable":"Marcado","or":"o","filterBarMsgHasFilterTemplate":"Se muestran ${0} de ${1} ${2}.","rangeTo":"a","conditionStartsWith":"empieza por","waiRelAny":"Coincide con cualquiera de las reglas siguientes:","statusTipRelPost":"reglas.","relationMsgTail":"","filterBarClearButton":"Borrar filtro","incompleteRuleTip":"Esta regla no está completa.","conditionLessEqual":"es menor o igual que","waiFilterBarClearButton":"Borrar el filtro","conditionAfter":"después","statusTipHeaderCondition":"Reglas","falseLabel":"Falso","filterButton":"Filtro","clearFilterDialogTitle":"Limpiar filtro","statusTipTitleHasFilter":"Filtro","addRuleButton":"Añadir regla","waiAddRuleButton":"Añadir una regla nueva","waiClearButton":"Borrar el filtro","conditionNotEqual":"no es igual","conditionNotEndWith":"no termina por","rangeTemplate":"de ${0} a ${1}","removeRuleButton":"Eliminar regla","waiFilterBarDefButton":"Filtrar la tabla","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/es/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/es/Filter.xd.js
new file mode 100644
index 0000000..b67c499
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/es/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.es.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.es.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "es", ({"conditionBefore":"antes","filterBarDefButton":"Definir filtro","filterBarMsgNoFilterTemplate":"No se aplica ningún filtro","conditionContains":"contiene","clearFilterMsg":"Eliminará el filtro y mostrará todos los registros disponibles.","all":"todas","waiValueBoxTemplate":"Especifique un valor para el filtro para la regla ${0}","conditionRange":"rango","waiCancelButton":"Cancelar este diálogo","relationAll":"todas las reglas","conditionLarger":"es superior que","valueBoxLabel":"Valor","statusTipMsg":"Pulse la barra de filtros para filtrar los valores de ${0}.","waiRelAll":"Coincide con todas las reglas siguientes:","closeFilterBarBtn":"Cerrar la barra de filtros","a11yFilterBarDefButton":"Filtrar...","trueLabel":"Verdadero","conditionIsNot":"no es","conditionIs":"es","ruleTitleTemplate":"Regla ${0}","waiRemoveRuleButtonTemplate":"Eliminar regla ${0}","and":"y","conditionLess":"es menor que","waiColumnSelectTemplate":"Columna para la regla ${0}","anycolumn":"cualquier columna","filterDefDialogTitle":"Filtro","waiConditionSelectTemplate":"Condición para la regla ${0}","waiFilterButton":"Enviar el filtro","statusTipTitle":"Barra de filtros","statusTipRelPre":"Coincide","anyColumnOption":"Cualquier columna","conditionSelectLabel":"Condición","cancelButton":"Cancelar","conditionNotStartWith":"no empieza por","conditionEndWith":"termina por","statusTipTitleNoFilter":"Barra de filtros","columnSelectLabel":"Columna","conditionNotContain":"no contiene","clearButton":"Borrar","conditionLargerEqual":"superior o igual que","any":"cualquiera","relationMsgFront":"Coincide","statusTipHeaderColumn":"Columna","defaultItemsName":"elementos","conditionEqual":"igual","relationAny":"cualquier regla","trueLabelEditable":"Marcado","or":"o","filterBarMsgHasFilterTemplate":"Se muestran ${0} de ${1} ${2}.","rangeTo":"a","conditionStartsWith":"empieza por","waiRelAny":"Coincide con cualquiera de las reglas siguientes:","statusTipRelPost":"reglas.","relationMsgTail":"","filterBarClearButton":"Borrar filtro","incompleteRuleTip":"Esta regla no está completa.","conditionLessEqual":"es menor o igual que","waiFilterBarClearButton":"Borrar el filtro","conditionAfter":"después","statusTipHeaderCondition":"Reglas","falseLabel":"Falso","filterButton":"Filtro","clearFilterDialogTitle":"Limpiar filtro","statusTipTitleHasFilter":"Filtro","addRuleButton":"Añadir regla","waiAddRuleButton":"Añadir una regla nueva","waiClearButton":"Borrar el filtro","conditionNotEqual":"no es igual","conditionNotEndWith":"no termina por","rangeTemplate":"de ${0} a ${1}","removeRuleButton":"Eliminar regla","waiFilterBarDefButton":"Filtrar la tabla","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/es/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/es/Pagination.js
new file mode 100644
index 0000000..8811330
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/es/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Ir a una página específica","prevTip":"Página anterior","pageCountIndication":" (${0} páginas)","pageStepLabelTemplate":"Página ${0}","descTemplate":"${2} - ${3} de ${1} ${0}","lastTip":"Última página","nextTip":"Página siguiente","pageSizeLabelTemplate":"${0} elementos por página","dialogCancel":"Cancelar","itemTitle":"elementos","dialogConfirm":"Ir","firstTip":"Primera página","allItemsLabelTemplate":"Todos los elementos","dialogIndication":"Especifique el número de página","dialogTitle":"Ir a la página"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/es/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/es/Pagination.xd.js
new file mode 100644
index 0000000..38a0d9f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/es/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.es.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.es.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "es", ({"gotoButtonTitle":"Ir a una página específica","prevTip":"Página anterior","pageCountIndication":" (${0} páginas)","pageStepLabelTemplate":"Página ${0}","descTemplate":"${2} - ${3} de ${1} ${0}","lastTip":"Última página","nextTip":"Página siguiente","pageSizeLabelTemplate":"${0} elementos por página","dialogCancel":"Cancelar","itemTitle":"elementos","dialogConfirm":"Ir","firstTip":"Primera página","allItemsLabelTemplate":"Todos los elementos","dialogIndication":"Especifique el número de página","dialogTitle":"Ir a la página"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/fi/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/fi/EnhancedGrid.js
new file mode 100644
index 0000000..688ed7c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/fi/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Laskeva","ascending":"Nouseva","nestedSort":"Sisäkkäinen lajittelu","unsorted":"Älä lajittele tätä saraketta","singleSort":"Yksinkertainen lajittelu","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/fi/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/fi/EnhancedGrid.xd.js
new file mode 100644
index 0000000..de14a8d
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/fi/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.fi.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.fi.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "fi", ({"descending":"Laskeva","ascending":"Nouseva","nestedSort":"Sisäkkäinen lajittelu","unsorted":"Älä lajittele tätä saraketta","singleSort":"Yksinkertainen lajittelu","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/fi/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/fi/Filter.js
new file mode 100644
index 0000000..af84cef
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/fi/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"ennen","filterBarDefButton":"Määritä suodatin","filterBarMsgNoFilterTemplate":"Ei suodatinta käytössä","conditionContains":"sisältää","clearFilterMsg":"Poistaa suodattimen ja näyttää kaikki käytettävissä olevat tietueet.","all":"kaikki","waiValueBoxTemplate":"Anna suodatusarvo säännölle ${0}","conditionRange":"sallittu alue","waiCancelButton":"Peruuta tämä valintaikkuna","relationAll":"kaikki säännöt","conditionLarger":"on suurempi kuin","valueBoxLabel":"Arvo","statusTipMsg":"Napsauta suodatinpalkkia tässä ja suodata arvot kohteessa ${0}.","waiRelAll":"Vastaa kaikkia seuraavia sääntöjä:","closeFilterBarBtn":"Sulje suodatinpalkki","a11yFilterBarDefButton":"Suodata...","trueLabel":"Tosi","conditionIsNot":"ei ole","conditionIs":"on","ruleTitleTemplate":"Sääntö ${0}","waiRemoveRuleButtonTemplate":"Poista sääntö ${0}","and":"ja","conditionLess":"on pienempi kuin","waiColumnSelectTemplate":"Sarake säännölle ${0}","anycolumn":"mikä tahansa sarake","filterDefDialogTitle":"Suodatin","waiConditionSelectTemplate":"Ehto säännölle ${0}","waiFilterButton":"Lähetä suodatin","statusTipTitle":"Suodatinpalkki","statusTipRelPre":"Vastaa","anyColumnOption":"Mikä tahansa sarake","conditionSelectLabel":"Ehto","cancelButton":"Peruuta","conditionNotStartWith":"ei ala merkillä","conditionEndWith":"loppuu merkkiin","statusTipTitleNoFilter":"Suodatinpalkki","columnSelectLabel":"Sarake","conditionNotContain":"ei sisällä","clearButton":"Tyhjennä","conditionLargerEqual":"suurempi tai yhtä suuri","any":"mikä tahansa","relationMsgFront":"Vastaa","statusTipHeaderColumn":"Sarake","defaultItemsName":"kohteet","conditionEqual":"on yhtä suuri","relationAny":"mitkä tahansa säännöt","trueLabelEditable":"Tarkistettu","or":"tai","filterBarMsgHasFilterTemplate":"${0} / ${1} ${2} näkyy.","rangeTo":"-","conditionStartsWith":"alkaa merkillä","waiRelAny":"Vastaa jotakin seuraavista säännöistä:","statusTipRelPost":"sääntöä.","relationMsgTail":"","filterBarClearButton":"Tyhjennä suodatin","incompleteRuleTip":"Tämä sääntö ei ole valmis.","conditionLessEqual":"pienempi tai yhtä suuri","waiFilterBarClearButton":"Tyhjennä suodatin","conditionAfter":"jälkeen","statusTipHeaderCondition":"Säännöt","falseLabel":"Epätosi","filterButton":"Suodatin","clearFilterDialogTitle":"Tyhjennä suodatin","statusTipTitleHasFilter":"Suodatin","addRuleButton":"Lisää sääntö","waiAddRuleButton":"Lisää uusi sääntö","waiClearButton":"Tyhjennä suodatin","conditionNotEqual":"ei ole yhtä suuri","conditionNotEndWith":"ei lopu merkkiin","rangeTemplate":"${0} - ${1}","removeRuleButton":"Poista sääntö","waiFilterBarDefButton":"Suodata taulukko","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/fi/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/fi/Filter.xd.js
new file mode 100644
index 0000000..8d72085
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/fi/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.fi.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.fi.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "fi", ({"conditionBefore":"ennen","filterBarDefButton":"Määritä suodatin","filterBarMsgNoFilterTemplate":"Ei suodatinta käytössä","conditionContains":"sisältää","clearFilterMsg":"Poistaa suodattimen ja näyttää kaikki käytettävissä olevat tietueet.","all":"kaikki","waiValueBoxTemplate":"Anna suodatusarvo säännölle ${0}","conditionRange":"sallittu alue","waiCancelButton":"Peruuta tämä valintaikkuna","relationAll":"kaikki säännöt","conditionLarger":"on suurempi kuin","valueBoxLabel":"Arvo","statusTipMsg":"Napsauta suodatinpalkkia tässä ja suodata arvot kohteessa ${0}.","waiRelAll":"Vastaa kaikkia seuraavia sääntöjä:","closeFilterBarBtn":"Sulje suodatinpalkki","a11yFilterBarDefButton":"Suodata...","trueLabel":"Tosi","conditionIsNot":"ei ole","conditionIs":"on","ruleTitleTemplate":"Sääntö ${0}","waiRemoveRuleButtonTemplate":"Poista sääntö ${0}","and":"ja","conditionLess":"on pienempi kuin","waiColumnSelectTemplate":"Sarake säännölle ${0}","anycolumn":"mikä tahansa sarake","filterDefDialogTitle":"Suodatin","waiConditionSelectTemplate":"Ehto säännölle ${0}","waiFilterButton":"Lähetä suodatin","statusTipTitle":"Suodatinpalkki","statusTipRelPre":"Vastaa","anyColumnOption":"Mikä tahansa sarake","conditionSelectLabel":"Ehto","cancelButton":"Peruuta","conditionNotStartWith":"ei ala merkillä","conditionEndWith":"loppuu merkkiin","statusTipTitleNoFilter":"Suodatinpalkki","columnSelectLabel":"Sarake","conditionNotContain":"ei sisällä","clearButton":"Tyhjennä","conditionLargerEqual":"suurempi tai yhtä suuri","any":"mikä tahansa","relationMsgFront":"Vastaa","statusTipHeaderColumn":"Sarake","defaultItemsName":"kohteet","conditionEqual":"on yhtä suuri","relationAny":"mitkä tahansa säännöt","trueLabelEditable":"Tarkistettu","or":"tai","filterBarMsgHasFilterTemplate":"${0} / ${1} ${2} näkyy.","rangeTo":"-","conditionStartsWith":"alkaa merkillä","waiRelAny":"Vastaa jotakin seuraavista säännöistä:","statusTipRelPost":"sääntöä.","relationMsgTail":"","filterBarClearButton":"Tyhjennä suodatin","incompleteRuleTip":"Tämä sääntö ei ole valmis.","conditionLessEqual":"pienempi tai yhtä suuri","waiFilterBarClearButton":"Tyhjennä suodatin","conditionAfter":"jälkeen","statusTipHeaderCondition":"Säännöt","falseLabel":"Epätosi","filterButton":"Suodatin","clearFilterDialogTitle":"Tyhjennä suodatin","statusTipTitleHasFilter":"Suodatin","addRuleButton":"Lisää sääntö","waiAddRuleButton":"Lisää uusi sääntö","waiClearButton":"Tyhjennä suodatin","conditionNotEqual":"ei ole yhtä suuri","conditionNotEndWith":"ei lopu merkkiin","rangeTemplate":"${0} - ${1}","removeRuleButton":"Poista sääntö","waiFilterBarDefButton":"Suodata taulukko","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/fi/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/fi/Pagination.js
new file mode 100644
index 0000000..d325831
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/fi/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Siirry tietylle sivulle","prevTip":"Edellinen sivu","pageCountIndication":" (${0} sivua)","pageStepLabelTemplate":"Sivu ${0}","descTemplate":"${2} - ${3} / ${1} ${0}","lastTip":"Viimeinen sivu","nextTip":"Seuraava sivu","pageSizeLabelTemplate":"${0} kohdetta sivulla","dialogCancel":"Peruuta","itemTitle":"kohdetta","dialogConfirm":"Siirry","firstTip":"Ensimmäinen sivu","allItemsLabelTemplate":"Kaikki kohteet","dialogIndication":"Määritä sivunumero","dialogTitle":"Siirry sivulle"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/fi/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/fi/Pagination.xd.js
new file mode 100644
index 0000000..31ef12f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/fi/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.fi.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.fi.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "fi", ({"gotoButtonTitle":"Siirry tietylle sivulle","prevTip":"Edellinen sivu","pageCountIndication":" (${0} sivua)","pageStepLabelTemplate":"Sivu ${0}","descTemplate":"${2} - ${3} / ${1} ${0}","lastTip":"Viimeinen sivu","nextTip":"Seuraava sivu","pageSizeLabelTemplate":"${0} kohdetta sivulla","dialogCancel":"Peruuta","itemTitle":"kohdetta","dialogConfirm":"Siirry","firstTip":"Ensimmäinen sivu","allItemsLabelTemplate":"Kaikki kohteet","dialogIndication":"Määritä sivunumero","dialogTitle":"Siirry sivulle"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/fr/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/fr/EnhancedGrid.js
new file mode 100644
index 0000000..94e5819
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/fr/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Décroissant","ascending":"Croissant","nestedSort":"Tri imbriqué","unsorted":"Ne pas trier cette colonne","singleSort":"Tri unique","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/fr/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/fr/EnhancedGrid.xd.js
new file mode 100644
index 0000000..25240c2
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/fr/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.fr.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.fr.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "fr", ({"descending":"Décroissant","ascending":"Croissant","nestedSort":"Tri imbriqué","unsorted":"Ne pas trier cette colonne","singleSort":"Tri unique","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/fr/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/fr/Filter.js
new file mode 100644
index 0000000..08d147b
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/fr/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"avant","filterBarDefButton":"Définir le filtre","filterBarMsgNoFilterTemplate":"Aucun filtre appliqué","conditionContains":"contient","clearFilterMsg":"Le filtre sera supprimé et tous les enregistrements disponibles affichés.","all":"tout","waiValueBoxTemplate":"Entrez une valeur pour filtrer la règle ${0}","conditionRange":"plage","waiCancelButton":"Annuler cette boîte de dialogue","relationAll":"toutes les règles","conditionLarger":"supérieur à","valueBoxLabel":"Valeur","statusTipMsg":"Cliquez sur cette barre de filtre pour filtrer les valeurs de ${0}.","waiRelAll":"Répondre à toutes les règles suivantes :","closeFilterBarBtn":"Fermer la barre de filtre","a11yFilterBarDefButton":"Filtrer...","trueLabel":"Vrai","conditionIsNot":"n'est pas","conditionIs":"est","ruleTitleTemplate":"Règle ${0}","waiRemoveRuleButtonTemplate":"Supprimer la règle ${0}","and":"et","conditionLess":"inférieur à","waiColumnSelectTemplate":"Colonne pour la règle ${0}","anycolumn":"toute colonne","filterDefDialogTitle":"Filtrer","waiConditionSelectTemplate":"Condition pour la règle ${0}","waiFilterButton":"Soumettre le filtre","statusTipTitle":"Barre de filtre","statusTipRelPre":"Correspondance","anyColumnOption":"Toute colonne","conditionSelectLabel":"Condition","cancelButton":"Annuler","conditionNotStartWith":"ne commence pas par","conditionEndWith":"se termine par","statusTipTitleNoFilter":"Barre de filtre","columnSelectLabel":"Colonne","conditionNotContain":"ne contient pas","clearButton":"Effacer","conditionLargerEqual":"supérieur ou égal à","any":"n'importe lequel","relationMsgFront":"Répondre à","statusTipHeaderColumn":"Colonne","defaultItemsName":"éléments","conditionEqual":"égal à","relationAny":"n'importe quelle règle","trueLabelEditable":"Vérifié","or":"ou","filterBarMsgHasFilterTemplate":"${0} sur ${1} ${2} montrés.","rangeTo":"à","conditionStartsWith":"commence par","waiRelAny":"Répondre à l'une des règles suivantes :","statusTipRelPost":"règles.","relationMsgTail":"","filterBarClearButton":"Effacer le filtre","incompleteRuleTip":"Cette règle n'est pas complète.","conditionLessEqual":"inférieur ou égal à","waiFilterBarClearButton":"Effacer le filtre","conditionAfter":"après","statusTipHeaderCondition":"Règles","falseLabel":"Faux","filterButton":"Filtrer","clearFilterDialogTitle":"Effacer le filtre","statusTipTitleHasFilter":"Filtrer","addRuleButton":"Ajouter une règle","waiAddRuleButton":"Ajouter une nouvelle règle","waiClearButton":"Effacer ce filtre","conditionNotEqual":"différent de","conditionNotEndWith":"ne se termine pas","rangeTemplate":"de ${0} à ${1}","removeRuleButton":"Supprimer une règle","waiFilterBarDefButton":"Filtrer la table","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/fr/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/fr/Filter.xd.js
new file mode 100644
index 0000000..6f479e4
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/fr/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.fr.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.fr.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "fr", ({"conditionBefore":"avant","filterBarDefButton":"Définir le filtre","filterBarMsgNoFilterTemplate":"Aucun filtre appliqué","conditionContains":"contient","clearFilterMsg":"Le filtre sera supprimé et tous les enregistrements disponibles affichés.","all":"tout","waiValueBoxTemplate":"Entrez une valeur pour filtrer la règle ${0}","conditionRange":"plage","waiCancelButton":"Annuler cette boîte de dialogue","relationAll":"toutes les règles","conditionLarger":"supérieur à","valueBoxLabel":"Valeur","statusTipMsg":"Cliquez sur cette barre de filtre pour filtrer les valeurs de ${0}.","waiRelAll":"Répondre à toutes les règles suivantes :","closeFilterBarBtn":"Fermer la barre de filtre","a11yFilterBarDefButton":"Filtrer...","trueLabel":"Vrai","conditionIsNot":"n'est pas","conditionIs":"est","ruleTitleTemplate":"Règle ${0}","waiRemoveRuleButtonTemplate":"Supprimer la règle ${0}","and":"et","conditionLess":"inférieur à","waiColumnSelectTemplate":"Colonne pour la règle ${0}","anycolumn":"toute colonne","filterDefDialogTitle":"Filtrer","waiConditionSelectTemplate":"Condition pour la règle ${0}","waiFilterButton":"Soumettre le filtre","statusTipTitle":"Barre de filtre","statusTipRelPre":"Correspondance","anyColumnOption":"Toute colonne","conditionSelectLabel":"Condition","cancelButton":"Annuler","conditionNotStartWith":"ne commence pas par","conditionEndWith":"se termine par","statusTipTitleNoFilter":"Barre de filtre","columnSelectLabel":"Colonne","conditionNotContain":"ne contient pas","clearButton":"Effacer","conditionLargerEqual":"supérieur ou égal à","any":"n'importe lequel","relationMsgFront":"Répondre à","statusTipHeaderColumn":"Colonne","defaultItemsName":"éléments","conditionEqual":"égal à","relationAny":"n'importe quelle règle","trueLabelEditable":"Vérifié","or":"ou","filterBarMsgHasFilterTemplate":"${0} sur ${1} ${2} montrés.","rangeTo":"à","conditionStartsWith":"commence par","waiRelAny":"Répondre à l'une des règles suivantes :","statusTipRelPost":"règles.","relationMsgTail":"","filterBarClearButton":"Effacer le filtre","incompleteRuleTip":"Cette règle n'est pas complète.","conditionLessEqual":"inférieur ou égal à","waiFilterBarClearButton":"Effacer le filtre","conditionAfter":"après","statusTipHeaderCondition":"Règles","falseLabel":"Faux","filterButton":"Filtrer","clearFilterDialogTitle":"Effacer le filtre","statusTipTitleHasFilter":"Filtrer","addRuleButton":"Ajouter une règle","waiAddRuleButton":"Ajouter une nouvelle règle","waiClearButton":"Effacer ce filtre","conditionNotEqual":"différent de","conditionNotEndWith":"ne se termine pas","rangeTemplate":"de ${0} à ${1}","removeRuleButton":"Supprimer une règle","waiFilterBarDefButton":"Filtrer la table","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/fr/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/fr/Pagination.js
new file mode 100644
index 0000000..540fcba
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/fr/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Aller à une page spécifique","prevTip":"Page précédente","pageCountIndication":" (${0} pages)","pageStepLabelTemplate":"Page ${0}","descTemplate":"${2} - ${3} sur ${1} ${0}","lastTip":"Dernière page","nextTip":"Page suivante","pageSizeLabelTemplate":"${0} éléments par page","dialogCancel":"Annuler","itemTitle":"éléments","dialogConfirm":"Aller","firstTip":"Première page","allItemsLabelTemplate":"Tous les éléments","dialogIndication":"Spécifiez le numéro de page","dialogTitle":"Aller à la page"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/fr/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/fr/Pagination.xd.js
new file mode 100644
index 0000000..fb2c796
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/fr/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.fr.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.fr.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "fr", ({"gotoButtonTitle":"Aller à une page spécifique","prevTip":"Page précédente","pageCountIndication":" (${0} pages)","pageStepLabelTemplate":"Page ${0}","descTemplate":"${2} - ${3} sur ${1} ${0}","lastTip":"Dernière page","nextTip":"Page suivante","pageSizeLabelTemplate":"${0} éléments par page","dialogCancel":"Annuler","itemTitle":"éléments","dialogConfirm":"Aller","firstTip":"Première page","allItemsLabelTemplate":"Tous les éléments","dialogIndication":"Spécifiez le numéro de page","dialogTitle":"Aller à la page"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/he/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/he/EnhancedGrid.js
new file mode 100644
index 0000000..1e130c0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/he/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"יורד","ascending":"עולה","nestedSort":"מיון מקונן","unsorted":"לא למיין עמודה זו","singleSort":"מיון יחיד","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/he/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/he/EnhancedGrid.xd.js
new file mode 100644
index 0000000..15cd4a6
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/he/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.he.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.he.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "he", ({"descending":"יורד","ascending":"עולה","nestedSort":"מיון מקונן","unsorted":"לא למיין עמודה זו","singleSort":"מיון יחיד","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/he/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/he/Filter.js
new file mode 100644
index 0000000..25a13df
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/he/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"לפני ","filterBarDefButton":"הגדרת מסנן ","filterBarMsgNoFilterTemplate":"לא הוחל מסנן. ","conditionContains":"מכיל ","clearFilterMsg":"פעולה זו תסלק את המסנן ותציג את כל הרשומות הזמינות. ","all":"הכל","waiValueBoxTemplate":"ציינו ערך לסינון עבור הכלל ${0}","conditionRange":"טווח ","waiCancelButton":"ביטול דו-שיח זה ","relationAll":"כל הכללים ","conditionLarger":"גדול מ-","valueBoxLabel":"ערך ","statusTipMsg":"לחצנו על סרגל הסינון כאן כדי לסנן לפי ערכים בתוך ${0}.","waiRelAll":"התאמה לכל הכללים שלהלן: ","closeFilterBarBtn":"סגירת סרגל הסינון","a11yFilterBarDefButton":"סינון...‏","trueLabel":"אמיתי","conditionIsNot":"אינו ","conditionIs":"הוא","ruleTitleTemplate":"כלל ${0}","waiRemoveRuleButtonTemplate":"סילוק הכלל ${0}","and":"וגם","conditionLess":"קטן מ-","waiColumnSelectTemplate":"עמודה עבור הכלל ${0}","anycolumn":"עמודה כלשהי","filterDefDialogTitle":"מסנן","waiConditionSelectTemplate":"תנאי עבור הכלל ${0}","waiFilterButton":"הגשת המסנן","statusTipTitle":"סרגל סינון ","statusTipRelPre":"התאמה","anyColumnOption":"עמודה כלשהי","conditionSelectLabel":"תנאי ","cancelButton":"ביטול","conditionNotStartWith":"אינו מתחיל עם ","conditionEndWith":"מסתיים עם ","statusTipTitleNoFilter":"סרגל סינון","columnSelectLabel":"עמודה ","conditionNotContain":"אינו מכיל ","clearButton":"ניקוי ","conditionLargerEqual":"גדול או שווה ","any":"כלשהו","relationMsgFront":"התאמה ","statusTipHeaderColumn":"עמודה","defaultItemsName":"פריטים ","conditionEqual":"שווה ","relationAny":"כללים כלשהם","trueLabelEditable":"נבדק","or":"או","filterBarMsgHasFilterTemplate":"מוצגים ${0} מתוך ${1} ${2}.‏ ","rangeTo":"עד","conditionStartsWith":"מתחיל עם ","waiRelAny":"התאמה לכלל כלשהו הכללים שלהלן:","statusTipRelPost":"כללים.","relationMsgTail":"","filterBarClearButton":"ניקוי מסנן","incompleteRuleTip":"הכלל אינו שלם. ","conditionLessEqual":"קטן או שווה ","waiFilterBarClearButton":"ניקוי המסנן","conditionAfter":"אחרי ","statusTipHeaderCondition":"כללים ","falseLabel":"שקרי ","filterButton":"מסנן","clearFilterDialogTitle":"ניקוי מסנן ","statusTipTitleHasFilter":"מסנן","addRuleButton":"הוספת כלל","waiAddRuleButton":"הוספת כלל חדש ","waiClearButton":"ניקוי המסנן ","conditionNotEqual":"אינו שווה ","conditionNotEndWith":"אינו מסתיים עם","rangeTemplate":"מ-${0} עד ${1}","removeRuleButton":"סילוק כלל ","waiFilterBarDefButton":"סינון הטבלה ","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/he/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/he/Filter.xd.js
new file mode 100644
index 0000000..c5ab6c4
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/he/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.he.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.he.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "he", ({"conditionBefore":"לפני ","filterBarDefButton":"הגדרת מסנן ","filterBarMsgNoFilterTemplate":"לא הוחל מסנן. ","conditionContains":"מכיל ","clearFilterMsg":"פעולה זו תסלק את המסנן ותציג את כל הרשומות הזמינות. ","all":"הכל","waiValueBoxTemplate":"ציינו ערך לסינון עבור הכלל ${0}","conditionRange":"טווח ","waiCancelButton":"ביטול דו-שיח זה ","relationAll":"כל הכללים ","conditionLarger":"גדול מ-","valueBoxLabel":"ערך ","statusTipMsg":"לחצנו על סרגל הסינון כאן כדי לסנן לפי ערכים בתוך ${0}.","waiRelAll":"התאמה לכל הכללים שלהלן: ","closeFilterBarBtn":"סגירת סרגל הסינון","a11yFilterBarDefButton":"סינון...‏","trueLabel":"אמיתי","conditionIsNot":"אינו ","conditionIs":"הוא","ruleTitleTemplate":"כלל ${0}","waiRemoveRuleButtonTemplate":"סילוק הכלל ${0}","and":"וגם","conditionLess":"קטן מ-","waiColumnSelectTemplate":"עמודה עבור הכלל ${0}","anycolumn":"עמודה כלשהי","filterDefDialogTitle":"מסנן","waiConditionSelectTemplate":"תנאי עבור הכלל ${0}","waiFilterButton":"הגשת המסנן","statusTipTitle":"סרגל סינון ","statusTipRelPre":"התאמה","anyColumnOption":"עמודה כלשהי","conditionSelectLabel":"תנאי ","cancelButton":"ביטול","conditionNotStartWith":"אינו מתחיל עם ","conditionEndWith":"מסתיים עם ","statusTipTitleNoFilter":"סרגל סינון","columnSelectLabel":"עמודה ","conditionNotContain":"אינו מכיל ","clearButton":"ניקוי ","conditionLargerEqual":"גדול או שווה ","any":"כלשהו","relationMsgFront":"התאמה ","statusTipHeaderColumn":"עמודה","defaultItemsName":"פריטים ","conditionEqual":"שווה ","relationAny":"כללים כלשהם","trueLabelEditable":"נבדק","or":"או","filterBarMsgHasFilterTemplate":"מוצגים ${0} מתוך ${1} ${2}.‏ ","rangeTo":"עד","conditionStartsWith":"מתחיל עם ","waiRelAny":"התאמה לכלל כלשהו הכללים שלהלן:","statusTipRelPost":"כללים.","relationMsgTail":"","filterBarClearButton":"ניקוי מסנן","incompleteRuleTip":"הכלל אינו שלם. ","conditionLessEqual":"קטן או שווה ","waiFilterBarClearButton":"ניקוי המסנן","conditionAfter":"אחרי ","statusTipHeaderCondition":"כללים ","falseLabel":"שקרי ","filterButton":"מסנן","clearFilterDialogTitle":"ניקוי מסנן ","statusTipTitleHasFilter":"מסנן","addRuleButton":"הוספת כלל","waiAddRuleButton":"הוספת כלל חדש ","waiClearButton":"ניקוי המסנן ","conditionNotEqual":"אינו שווה ","conditionNotEndWith":"אינו מסתיים עם","rangeTemplate":"מ-${0} עד ${1}","removeRuleButton":"סילוק כלל ","waiFilterBarDefButton":"סינון הטבלה ","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/he/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/he/Pagination.js
new file mode 100644
index 0000000..fea6651
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/he/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"מעבר לעמוד מסוים ","prevTip":"העמוד הקודם ","pageCountIndication":" (${0} עמודים)","pageStepLabelTemplate":"עמוד ${0}","descTemplate":"${2} - ${3} מתוך ${1} ${0}","lastTip":"עמוד אחרון ","nextTip":"העמוד הבא ","pageSizeLabelTemplate":"${0} פריטים בעמוד ","dialogCancel":"ביטול","itemTitle":"פריטים","dialogConfirm":"ביצוע","firstTip":"עמוד ראשון ","allItemsLabelTemplate":"כל הפריטים ","dialogIndication":"ציינו מספר עמוד ","dialogTitle":"מעבר לעמוד "}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/he/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/he/Pagination.xd.js
new file mode 100644
index 0000000..c2fc421
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/he/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.he.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.he.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "he", ({"gotoButtonTitle":"מעבר לעמוד מסוים ","prevTip":"העמוד הקודם ","pageCountIndication":" (${0} עמודים)","pageStepLabelTemplate":"עמוד ${0}","descTemplate":"${2} - ${3} מתוך ${1} ${0}","lastTip":"עמוד אחרון ","nextTip":"העמוד הבא ","pageSizeLabelTemplate":"${0} פריטים בעמוד ","dialogCancel":"ביטול","itemTitle":"פריטים","dialogConfirm":"ביצוע","firstTip":"עמוד ראשון ","allItemsLabelTemplate":"כל הפריטים ","dialogIndication":"ציינו מספר עמוד ","dialogTitle":"מעבר לעמוד "})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/hu/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/hu/EnhancedGrid.js
new file mode 100644
index 0000000..5dc3115
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/hu/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Csökkenő","ascending":"Növekvő","nestedSort":"Beágyazott rendezés","unsorted":"Az oszlop nincs rendezve","singleSort":"Egyszerű rendezés","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/hu/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/hu/EnhancedGrid.xd.js
new file mode 100644
index 0000000..3793090
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/hu/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.hu.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.hu.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "hu", ({"descending":"Csökkenő","ascending":"Növekvő","nestedSort":"Beágyazott rendezés","unsorted":"Az oszlop nincs rendezve","singleSort":"Egyszerű rendezés","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/hu/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/hu/Filter.js
new file mode 100644
index 0000000..536a881
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/hu/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"előtte","filterBarDefButton":"Szűrő megadása","filterBarMsgNoFilterTemplate":"Nincs érvényben szűrő","conditionContains":"tartalmaz","clearFilterMsg":"Ez eltávolítja a szűrőt és megjelenít minden elérhető rekordot.","all":"mind","waiValueBoxTemplate":"Adja meg a szűrési értéket ${0} szabályhoz","conditionRange":"tartomány","waiCancelButton":"Párbeszédpanel visszavonása","relationAll":"minden szabály","conditionLarger":"nagyobb, mint","valueBoxLabel":"Érték","statusTipMsg":"Kattintson erre a szűrősávra ${0} értékeinek szűréséhez.","waiRelAll":"Az összes következő szabály egyeztetése:","closeFilterBarBtn":"Szűrősáv bezárása","a11yFilterBarDefButton":"Szűrő...","trueLabel":"Igaz","conditionIsNot":"nem","conditionIs":" ","ruleTitleTemplate":"Szabály: ${0}","waiRemoveRuleButtonTemplate":"Szabály eltávolítása: ${0}","and":"és","conditionLess":"kisebb, mint","waiColumnSelectTemplate":"${0} szabály oszlopa","anycolumn":"bármely oszlop","filterDefDialogTitle":"Szűrő","waiConditionSelectTemplate":"${0} szabály feltétele","waiFilterButton":"Szűrő elküldése","statusTipTitle":"Szűrősáv","statusTipRelPre":"Egyeztetés","anyColumnOption":"Bármely oszlop","conditionSelectLabel":"Feltétel","cancelButton":"Mégse","conditionNotStartWith":"kezdete nem","conditionEndWith":"vége","statusTipTitleNoFilter":"Szűrősáv","columnSelectLabel":"Oszlop","conditionNotContain":"nem tartalmaz","clearButton":"Törlés","conditionLargerEqual":"nem kisebb, mint","any":"bármely","relationMsgFront":"Egyeztetés","statusTipHeaderColumn":"Oszlop","defaultItemsName":"elem","conditionEqual":"egyenlő","relationAny":"bármely szabály","trueLabelEditable":"Bejelölve","or":"vagy","filterBarMsgHasFilterTemplate":"${0} elem megjelenítve, összesen ${1} ${2} ","rangeTo":" - ","conditionStartsWith":"kezdete","waiRelAny":"A következő szabályok bármelyikének egyeztetése:","statusTipRelPost":"szabály.","relationMsgTail":"","filterBarClearButton":"Szűrő törlése","incompleteRuleTip":"Ez a szabály nem teljes.","conditionLessEqual":"nem nagyobb, mint","waiFilterBarClearButton":"Szűrő törlése","conditionAfter":"utána","statusTipHeaderCondition":"Szabályok","falseLabel":"Hamis","filterButton":"Szűrő","clearFilterDialogTitle":"Szűrő törlése","statusTipTitleHasFilter":"Szűrő","addRuleButton":"Szabály hozzáadása","waiAddRuleButton":"Új szabály hozzáadása","waiClearButton":"Szűrő törlése","conditionNotEqual":"nem egyenlő","conditionNotEndWith":"vége nem","rangeTemplate":"${0} - ${1}","removeRuleButton":"Szabály eltávolítása","waiFilterBarDefButton":"Táblázat szűrése","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/hu/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/hu/Filter.xd.js
new file mode 100644
index 0000000..1ac60b6
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/hu/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.hu.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.hu.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "hu", ({"conditionBefore":"előtte","filterBarDefButton":"Szűrő megadása","filterBarMsgNoFilterTemplate":"Nincs érvényben szűrő","conditionContains":"tartalmaz","clearFilterMsg":"Ez eltávolítja a szűrőt és megjelenít minden elérhető rekordot.","all":"mind","waiValueBoxTemplate":"Adja meg a szűrési értéket ${0} szabályhoz","conditionRange":"tartomány","waiCancelButton":"Párbeszédpanel visszavonása","relationAll":"minden szabály","conditionLarger":"nagyobb, mint","valueBoxLabel":"Érték","statusTipMsg":"Kattintson erre a szűrősávra ${0} értékeinek szűréséhez.","waiRelAll":"Az összes következő szabály egyeztetése:","closeFilterBarBtn":"Szűrősáv bezárása","a11yFilterBarDefButton":"Szűrő...","trueLabel":"Igaz","conditionIsNot":"nem","conditionIs":" ","ruleTitleTemplate":"Szabály: ${0}","waiRemoveRuleButtonTemplate":"Szabály eltávolítása: ${0}","and":"és","conditionLess":"kisebb, mint","waiColumnSelectTemplate":"${0} szabály oszlopa","anycolumn":"bármely oszlop","filterDefDialogTitle":"Szűrő","waiConditionSelectTemplate":"${0} szabály feltétele","waiFilterButton":"Szűrő elküldése","statusTipTitle":"Szűrősáv","statusTipRelPre":"Egyeztetés","anyColumnOption":"Bármely oszlop","conditionSelectLabel":"Feltétel","cancelButton":"Mégse","conditionNotStartWith":"kezdete nem","conditionEndWith":"vége","statusTipTitleNoFilter":"Szűrősáv","columnSelectLabel":"Oszlop","conditionNotContain":"nem tartalmaz","clearButton":"Törlés","conditionLargerEqual":"nem kisebb, mint","any":"bármely","relationMsgFront":"Egyeztetés","statusTipHeaderColumn":"Oszlop","defaultItemsName":"elem","conditionEqual":"egyenlő","relationAny":"bármely szabály","trueLabelEditable":"Bejelölve","or":"vagy","filterBarMsgHasFilterTemplate":"${0} elem megjelenítve, összesen ${1} ${2} ","rangeTo":" - ","conditionStartsWith":"kezdete","waiRelAny":"A következő szabályok bármelyikének egyeztetése:","statusTipRelPost":"szabály.","relationMsgTail":"","filterBarClearButton":"Szűrő törlése","incompleteRuleTip":"Ez a szabály nem teljes.","conditionLessEqual":"nem nagyobb, mint","waiFilterBarClearButton":"Szűrő törlése","conditionAfter":"utána","statusTipHeaderCondition":"Szabályok","falseLabel":"Hamis","filterButton":"Szűrő","clearFilterDialogTitle":"Szűrő törlése","statusTipTitleHasFilter":"Szűrő","addRuleButton":"Szabály hozzáadása","waiAddRuleButton":"Új szabály hozzáadása","waiClearButton":"Szűrő törlése","conditionNotEqual":"nem egyenlő","conditionNotEndWith":"vége nem","rangeTemplate":"${0} - ${1}","removeRuleButton":"Szabály eltávolítása","waiFilterBarDefButton":"Táblázat szűrése","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/hu/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/hu/Pagination.js
new file mode 100644
index 0000000..125866d
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/hu/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Ugrás adott oldalra","prevTip":"Előző oldal","pageCountIndication":" (${0} oldal)","pageStepLabelTemplate":"${0} oldal","descTemplate":"${2} - ${3}, összesen ${1} ${0}","lastTip":"Utolsó oldal","nextTip":"Következő oldal","pageSizeLabelTemplate":"${0} elem oldalanként","dialogCancel":"Mégse","itemTitle":"elem","dialogConfirm":"Ugrás","firstTip":"Első oldal","allItemsLabelTemplate":"Minden elem","dialogIndication":"Adja meg az oldalszámot","dialogTitle":"Oldalszámhoz ugrás"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/hu/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/hu/Pagination.xd.js
new file mode 100644
index 0000000..f8e9344
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/hu/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.hu.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.hu.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "hu", ({"gotoButtonTitle":"Ugrás adott oldalra","prevTip":"Előző oldal","pageCountIndication":" (${0} oldal)","pageStepLabelTemplate":"${0} oldal","descTemplate":"${2} - ${3}, összesen ${1} ${0}","lastTip":"Utolsó oldal","nextTip":"Következő oldal","pageSizeLabelTemplate":"${0} elem oldalanként","dialogCancel":"Mégse","itemTitle":"elem","dialogConfirm":"Ugrás","firstTip":"Első oldal","allItemsLabelTemplate":"Minden elem","dialogIndication":"Adja meg az oldalszámot","dialogTitle":"Oldalszámhoz ugrás"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/it/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/it/EnhancedGrid.js
new file mode 100644
index 0000000..77623dd
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/it/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Discendente","ascending":"Ascendente","nestedSort":"Ordinamento nidificato","unsorted":"Non ordinare questa colonna","singleSort":"Ordinamento singolo","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/it/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/it/EnhancedGrid.xd.js
new file mode 100644
index 0000000..afe8fa6
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/it/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.it.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.it.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "it", ({"descending":"Discendente","ascending":"Ascendente","nestedSort":"Ordinamento nidificato","unsorted":"Non ordinare questa colonna","singleSort":"Ordinamento singolo","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/it/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/it/Filter.js
new file mode 100644
index 0000000..1a38bb3
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/it/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"prima","filterBarDefButton":"Definisci filtro","filterBarMsgNoFilterTemplate":"Nessun filtro applicato","conditionContains":"contiene","clearFilterMsg":"In tal modo il filtro verrà rimosso e verranno mostrati tutti i record disponibili.","all":"tutti","waiValueBoxTemplate":"Immettere il valore da filtrare per la regola ${0}","conditionRange":"intervallo","waiCancelButton":"Annulla questa finestra di dialogo","relationAll":"tutte le regole","conditionLarger":"maggiore di","valueBoxLabel":"Valore","statusTipMsg":"Fare clic sulla barra filtro per filtrare in base ai valori in ${0}.","waiRelAll":"Soddisfa tutte le seguenti regole:","closeFilterBarBtn":"Chiudi barra filtro","a11yFilterBarDefButton":"Filtra...","trueLabel":"True","conditionIsNot":"non è","conditionIs":"è","ruleTitleTemplate":"Regola ${0}","waiRemoveRuleButtonTemplate":"Rimuovi regola ${0}","and":"e","conditionLess":"minore di","waiColumnSelectTemplate":"Colonna per la regola ${0}","anycolumn":"qualunque colonna","filterDefDialogTitle":"Filtro","waiConditionSelectTemplate":"Condizione per la regola ${0}","waiFilterButton":"Inoltra il filtro","statusTipTitle":"Barra filtro","statusTipRelPre":"Soddisfa","anyColumnOption":"Qualunque colonna","conditionSelectLabel":"Condizione","cancelButton":"Annulla","conditionNotStartWith":"non inizia con","conditionEndWith":"termina con","statusTipTitleNoFilter":"Barra filtro","columnSelectLabel":"Colonna","conditionNotContain":"non contiene","clearButton":"Cancella","conditionLargerEqual":"maggiore o uguale a","any":"qualunque","relationMsgFront":"Soddisfa","statusTipHeaderColumn":"Colonna","defaultItemsName":"elementi","conditionEqual":"uguale","relationAny":"qualunque regola","trueLabelEditable":"Selezionato","or":"o","filterBarMsgHasFilterTemplate":"${0} di ${1} ${2} visualizzati.","rangeTo":"a","conditionStartsWith":"inizia con","waiRelAny":"Soddisfa una delle seguenti regole:","statusTipRelPost":"regole.","relationMsgTail":"","filterBarClearButton":"Cancella filtro","incompleteRuleTip":"Questa regola non è completa.","conditionLessEqual":"minore o uguale a","waiFilterBarClearButton":"Cancella il filtro","conditionAfter":"dopo","statusTipHeaderCondition":"Regole","falseLabel":"False","filterButton":"Filtro","clearFilterDialogTitle":"Cancella filtro","statusTipTitleHasFilter":"Filtro","addRuleButton":"Aggiungi regola","waiAddRuleButton":"Aggiungi una nuova regola","waiClearButton":"Cancella il filtro","conditionNotEqual":"diverso da","conditionNotEndWith":"non termina con","rangeTemplate":"da ${0} a ${1}","removeRuleButton":"Rimuovi regola","waiFilterBarDefButton":"Filtra la tabella","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/it/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/it/Filter.xd.js
new file mode 100644
index 0000000..34bbc6c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/it/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.it.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.it.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "it", ({"conditionBefore":"prima","filterBarDefButton":"Definisci filtro","filterBarMsgNoFilterTemplate":"Nessun filtro applicato","conditionContains":"contiene","clearFilterMsg":"In tal modo il filtro verrà rimosso e verranno mostrati tutti i record disponibili.","all":"tutti","waiValueBoxTemplate":"Immettere il valore da filtrare per la regola ${0}","conditionRange":"intervallo","waiCancelButton":"Annulla questa finestra di dialogo","relationAll":"tutte le regole","conditionLarger":"maggiore di","valueBoxLabel":"Valore","statusTipMsg":"Fare clic sulla barra filtro per filtrare in base ai valori in ${0}.","waiRelAll":"Soddisfa tutte le seguenti regole:","closeFilterBarBtn":"Chiudi barra filtro","a11yFilterBarDefButton":"Filtra...","trueLabel":"True","conditionIsNot":"non è","conditionIs":"è","ruleTitleTemplate":"Regola ${0}","waiRemoveRuleButtonTemplate":"Rimuovi regola ${0}","and":"e","conditionLess":"minore di","waiColumnSelectTemplate":"Colonna per la regola ${0}","anycolumn":"qualunque colonna","filterDefDialogTitle":"Filtro","waiConditionSelectTemplate":"Condizione per la regola ${0}","waiFilterButton":"Inoltra il filtro","statusTipTitle":"Barra filtro","statusTipRelPre":"Soddisfa","anyColumnOption":"Qualunque colonna","conditionSelectLabel":"Condizione","cancelButton":"Annulla","conditionNotStartWith":"non inizia con","conditionEndWith":"termina con","statusTipTitleNoFilter":"Barra filtro","columnSelectLabel":"Colonna","conditionNotContain":"non contiene","clearButton":"Cancella","conditionLargerEqual":"maggiore o uguale a","any":"qualunque","relationMsgFront":"Soddisfa","statusTipHeaderColumn":"Colonna","defaultItemsName":"elementi","conditionEqual":"uguale","relationAny":"qualunque regola","trueLabelEditable":"Selezionato","or":"o","filterBarMsgHasFilterTemplate":"${0} di ${1} ${2} visualizzati.","rangeTo":"a","conditionStartsWith":"inizia con","waiRelAny":"Soddisfa una delle seguenti regole:","statusTipRelPost":"regole.","relationMsgTail":"","filterBarClearButton":"Cancella filtro","incompleteRuleTip":"Questa regola non è completa.","conditionLessEqual":"minore o uguale a","waiFilterBarClearButton":"Cancella il filtro","conditionAfter":"dopo","statusTipHeaderCondition":"Regole","falseLabel":"False","filterButton":"Filtro","clearFilterDialogTitle":"Cancella filtro","statusTipTitleHasFilter":"Filtro","addRuleButton":"Aggiungi regola","waiAddRuleButton":"Aggiungi una nuova regola","waiClearButton":"Cancella il filtro","conditionNotEqual":"diverso da","conditionNotEndWith":"non termina con","rangeTemplate":"da ${0} a ${1}","removeRuleButton":"Rimuovi regola","waiFilterBarDefButton":"Filtra la tabella","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/it/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/it/Pagination.js
new file mode 100644
index 0000000..cfe31f7
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/it/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Vai a una pagina specifica","prevTip":"Pagina precedente","pageCountIndication":" (${0} pagine)","pageStepLabelTemplate":"Pagina ${0}","descTemplate":"${2} - ${3} di ${1} ${0}","lastTip":"Ultima pagina","nextTip":"Pagina successiva","pageSizeLabelTemplate":"${0} elementi per pagina","dialogCancel":"Annulla","itemTitle":"elementi","dialogConfirm":"Vai","firstTip":"Prima pagina","allItemsLabelTemplate":"Tutti gli elementi","dialogIndication":"Specificare il numero di pagina","dialogTitle":"Vai a pagina"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/it/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/it/Pagination.xd.js
new file mode 100644
index 0000000..6048cfa
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/it/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.it.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.it.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "it", ({"gotoButtonTitle":"Vai a una pagina specifica","prevTip":"Pagina precedente","pageCountIndication":" (${0} pagine)","pageStepLabelTemplate":"Pagina ${0}","descTemplate":"${2} - ${3} di ${1} ${0}","lastTip":"Ultima pagina","nextTip":"Pagina successiva","pageSizeLabelTemplate":"${0} elementi per pagina","dialogCancel":"Annulla","itemTitle":"elementi","dialogConfirm":"Vai","firstTip":"Prima pagina","allItemsLabelTemplate":"Tutti gli elementi","dialogIndication":"Specificare il numero di pagina","dialogTitle":"Vai a pagina"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ja/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ja/EnhancedGrid.js
new file mode 100644
index 0000000..e224c03
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ja/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"降順","ascending":"昇順","nestedSort":"ネストされたソート","unsorted":"この列はソートしないでください","singleSort":"単一ソート","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ja/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ja/EnhancedGrid.xd.js
new file mode 100644
index 0000000..6c584f1
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ja/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.ja.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.ja.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "ja", ({"descending":"降順","ascending":"昇順","nestedSort":"ネストされたソート","unsorted":"この列はソートしないでください","singleSort":"単一ソート","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ja/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ja/Filter.js
new file mode 100644
index 0000000..cd295d5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ja/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"次の値より前","filterBarDefButton":"フィルターの定義","filterBarMsgNoFilterTemplate":"フィルターが適用されていません","conditionContains":"次の値を含む","clearFilterMsg":"これにより、フィルターが削除され、使用可能なすべてのレコードが表示されます。","all":"すべて","waiValueBoxTemplate":"ルール ${0} のフィルターの値を入力","conditionRange":"次の範囲","waiCancelButton":"このダイアログのキャンセル","relationAll":"すべてのルール","conditionLarger":"次の値より大きい","valueBoxLabel":"値","statusTipMsg":"${0} の値をフィルターに掛けるには、ここのフィルター・バーをクリックしてください。","waiRelAll":"次のすべてのルールを突き合わせ:","closeFilterBarBtn":"フィルター・バーを閉じる","a11yFilterBarDefButton":"フィルター...","trueLabel":"True","conditionIsNot":" が ではありません","conditionIs":"は","ruleTitleTemplate":"ルール ${0}","waiRemoveRuleButtonTemplate":"ルール ${0} の削除","and":" および ","conditionLess":"次の値より小さい","waiColumnSelectTemplate":"ルール ${0} の列","anycolumn":"任意の列","filterDefDialogTitle":"フィルター","waiConditionSelectTemplate":"ルール ${0} の条件","waiFilterButton":"フィルターの送信","statusTipTitle":"フィルター・バー","statusTipRelPre":"次を突き合わせ","anyColumnOption":"任意の列","conditionSelectLabel":"条件","cancelButton":"キャンセル","conditionNotStartWith":"次の値で始まらない","conditionEndWith":"次の値で終わる","statusTipTitleNoFilter":"フィルター・バー","columnSelectLabel":"列","conditionNotContain":"次の値を含まない","clearButton":"クリア","conditionLargerEqual":"次の値以上","any":"任意","relationMsgFront":"次を突き合わせ","statusTipHeaderColumn":"列","defaultItemsName":"項目","conditionEqual":"次の値と等しい","relationAny":"任意のルール","trueLabelEditable":"チェックマークが付いている","or":"または","filterBarMsgHasFilterTemplate":"${1} ${2} 中 ${0} が表示されています。","rangeTo":"比較基準","conditionStartsWith":"次の値で始まる","waiRelAny":"次の任意のルールを突き合わせ:","statusTipRelPost":"ルール。","relationMsgTail":"","filterBarClearButton":"フィルターのクリア","incompleteRuleTip":"このルールは未完成です。","conditionLessEqual":"次の値以下","waiFilterBarClearButton":"フィルターのクリア","conditionAfter":"次の値より後","statusTipHeaderCondition":"ルール","falseLabel":"False","filterButton":"フィルター","clearFilterDialogTitle":"フィルターのクリア","statusTipTitleHasFilter":"フィルター","addRuleButton":"ルールの追加","waiAddRuleButton":"新規ルールの追加","waiClearButton":"フィルターのクリア","conditionNotEqual":"次の値と等しくない","conditionNotEndWith":"次の値で終わらない","rangeTemplate":"${0} から ${1} まで","removeRuleButton":"ルールの削除","waiFilterBarDefButton":"表のフィルター","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ja/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ja/Filter.xd.js
new file mode 100644
index 0000000..c5d20d4
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ja/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.ja.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.ja.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "ja", ({"conditionBefore":"次の値より前","filterBarDefButton":"フィルターの定義","filterBarMsgNoFilterTemplate":"フィルターが適用されていません","conditionContains":"次の値を含む","clearFilterMsg":"これにより、フィルターが削除され、使用可能なすべてのレコードが表示されます。","all":"すべて","waiValueBoxTemplate":"ルール ${0} のフィルターの値を入力","conditionRange":"次の範囲","waiCancelButton":"このダイアログのキャンセル","relationAll":"すべてのルール","conditionLarger":"次の値より大きい","valueBoxLabel":"値","statusTipMsg":"${0} の値をフィルターに掛けるには、ここのフィルター・バーをクリックしてください。","waiRelAll":"次のすべてのルールを突き合わせ:","closeFilterBarBtn":"フィルター・バーを閉じる","a11yFilterBarDefButton":"フィルター...","trueLabel":"True","conditionIsNot":" が ではありません","conditionIs":"は","ruleTitleTemplate":"ルール ${0}","waiRemoveRuleButtonTemplate":"ルール ${0} の削除","and":" および ","conditionLess":"次の値より小さい","waiColumnSelectTemplate":"ルール ${0} の列","anycolumn":"任意の列","filterDefDialogTitle":"フィルター","waiConditionSelectTemplate":"ルール ${0} の条件","waiFilterButton":"フィルターの送信","statusTipTitle":"フィルター・バー","statusTipRelPre":"次を突き合わせ","anyColumnOption":"任意の列","conditionSelectLabel":"条件","cancelButton":"キャンセル","conditionNotStartWith":"次の値で始まらない","conditionEndWith":"次の値で終わる","statusTipTitleNoFilter":"フィルター・バー","columnSelectLabel":"列","conditionNotContain":"次の値を含まない","clearButton":"クリア","conditionLargerEqual":"次の値以上","any":"任意","relationMsgFront":"次を突き合わせ","statusTipHeaderColumn":"列","defaultItemsName":"項目","conditionEqual":"次の値と等しい","relationAny":"任意のルール","trueLabelEditable":"チェックマークが付いている","or":"または","filterBarMsgHasFilterTemplate":"${1} ${2} 中 ${0} が表示されています。","rangeTo":"比較基準","conditionStartsWith":"次の値で始まる","waiRelAny":"次の任意のルールを突き合わせ:","statusTipRelPost":"ルール。","relationMsgTail":"","filterBarClearButton":"フィルターのクリア","incompleteRuleTip":"このルールは未完成です。","conditionLessEqual":"次の値以下","waiFilterBarClearButton":"フィルターのクリア","conditionAfter":"次の値より後","statusTipHeaderCondition":"ルール","falseLabel":"False","filterButton":"フィルター","clearFilterDialogTitle":"フィルターのクリア","statusTipTitleHasFilter":"フィルター","addRuleButton":"ルールの追加","waiAddRuleButton":"新規ルールの追加","waiClearButton":"フィルターのクリア","conditionNotEqual":"次の値と等しくない","conditionNotEndWith":"次の値で終わらない","rangeTemplate":"${0} から ${1} まで","removeRuleButton":"ルールの削除","waiFilterBarDefButton":"表のフィルター","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ja/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ja/Pagination.js
new file mode 100644
index 0000000..7f296b5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ja/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"特定のページに移動","prevTip":"前のページ","pageCountIndication":" (${0} ページ)","pageStepLabelTemplate":"ページ ${0}","descTemplate":"合計 ${1} ${0} 件の結果のうち、${2} から ${3} 件目を表示しています","lastTip":"最後のページ","nextTip":"次のページ","pageSizeLabelTemplate":"${0} 個の項目をページに表示","dialogCancel":"キャンセル","itemTitle":"項目","dialogConfirm":"実行","firstTip":"最初のページ","allItemsLabelTemplate":"すべての項目","dialogIndication":"ページ番号の指定","dialogTitle":"ページに移動"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ja/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ja/Pagination.xd.js
new file mode 100644
index 0000000..57680ce
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ja/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.ja.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.ja.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "ja", ({"gotoButtonTitle":"特定のページに移動","prevTip":"前のページ","pageCountIndication":" (${0} ページ)","pageStepLabelTemplate":"ページ ${0}","descTemplate":"合計 ${1} ${0} 件の結果のうち、${2} から ${3} 件目を表示しています","lastTip":"最後のページ","nextTip":"次のページ","pageSizeLabelTemplate":"${0} 個の項目をページに表示","dialogCancel":"キャンセル","itemTitle":"項目","dialogConfirm":"実行","firstTip":"最初のページ","allItemsLabelTemplate":"すべての項目","dialogIndication":"ページ番号の指定","dialogTitle":"ページに移動"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/kk/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/kk/EnhancedGrid.js
new file mode 100644
index 0000000..ccfb237
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/kk/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Кему","ascending":"Өсу реті бойынша","nestedSort":"Кірістірілген сұрыптау","unsorted":"Бұл бағанды сұрыптамау","singleSort":"Бір рет сұрыптау","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/kk/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/kk/EnhancedGrid.xd.js
new file mode 100644
index 0000000..3883c60
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/kk/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.kk.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.kk.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "kk", ({"descending":"Кему","ascending":"Өсу реті бойынша","nestedSort":"Кірістірілген сұрыптау","unsorted":"Бұл бағанды сұрыптамау","singleSort":"Бір рет сұрыптау","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/kk/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/kk/Filter.js
new file mode 100644
index 0000000..6d75d6c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/kk/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"алдында","filterBarDefButton":"Сүзгіні анықтау","filterBarMsgNoFilterTemplate":"Сүзгі қолданылмады","conditionContains":"құрамында бар","clearFilterMsg":"Бұл сүзгіні жояды және барлық қол жетімді жазбаларды көрсетеді.","all":"барлығы","waiValueBoxTemplate":"${0} ережесін сүзу үшін мәнді енгізу","conditionRange":"ауқым","waiCancelButton":"Осы тілқатысу терезесін болдырмау","relationAll":"барлық ережелер","conditionLarger":"үлкендеу","valueBoxLabel":"Мән","statusTipMsg":"${0} ішіндегі мәндер бойынша сүзу үшін сүзгі тақтасын нұқыңыз.","waiRelAll":"Барлық мына ережелерге сәйкес:","closeFilterBarBtn":"Сүзгі тақтасын жабу","a11yFilterBarDefButton":"Сүзгі...","trueLabel":"Шын","conditionIsNot":"емес","conditionIs":"–","ruleTitleTemplate":"${0} ережесі","waiRemoveRuleButtonTemplate":"${0} ережесін алып тастау","and":"және","conditionLess":"аздау","waiColumnSelectTemplate":"${0} ережесінің бағаны","anycolumn":"кез келген баған","filterDefDialogTitle":"Сүзгі","waiConditionSelectTemplate":"${0} ережесінің шарты","waiFilterButton":"Сүзгіні жіберу","statusTipTitle":"Сүзгі тақтасы","statusTipRelPre":"Сәйкес келу","anyColumnOption":"Кез келген баған","conditionSelectLabel":"Шарт","cancelButton":"Болдырмау","conditionNotStartWith":"басталмайды","conditionEndWith":"аяқталады","statusTipTitleNoFilter":"Сүзгі тақтасы","columnSelectLabel":"Баған","conditionNotContain":"құрамында жоқ","clearButton":"Тазалау ","conditionLargerEqual":"үлкендеу немесе тең","any":"кез келген","relationMsgFront":"Сәйкес келу","statusTipHeaderColumn":"Баған","defaultItemsName":"элементтер","conditionEqual":"тең","relationAny":"кез келген ереже","trueLabelEditable":"Белгіленген","or":"немесе","filterBarMsgHasFilterTemplate":"${1} ${2} ішінен ${0} көрсетілді.","rangeTo":"неге","conditionStartsWith":"басталады","waiRelAny":"Мына ережелерге сәйкес:","statusTipRelPost":"ережелер.","relationMsgTail":"","filterBarClearButton":"Сүзгіні тазалау","incompleteRuleTip":"Бұл ереже толық емес.","conditionLessEqual":"аздау немесе тең","waiFilterBarClearButton":"Сүзгіні тазалау","conditionAfter":"артында","statusTipHeaderCondition":"Ережелер","falseLabel":"Жалған","filterButton":"Сүзгі","clearFilterDialogTitle":"Сүзгіні тазалау","statusTipTitleHasFilter":"Сүзгі","addRuleButton":"Ереже қосу","waiAddRuleButton":"Жаңа ереже қосу","waiClearButton":"Сүзгіні тазалау","conditionNotEqual":"тең емес","conditionNotEndWith":"аяқталмайды","rangeTemplate":"${0} мәнінен ${1} мәніне","removeRuleButton":"Ережені алып тастау","waiFilterBarDefButton":"Кестені сүзу","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/kk/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/kk/Filter.xd.js
new file mode 100644
index 0000000..1e3edd2
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/kk/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.kk.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.kk.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "kk", ({"conditionBefore":"алдында","filterBarDefButton":"Сүзгіні анықтау","filterBarMsgNoFilterTemplate":"Сүзгі қолданылмады","conditionContains":"құрамында бар","clearFilterMsg":"Бұл сүзгіні жояды және барлық қол жетімді жазбаларды көрсетеді.","all":"барлығы","waiValueBoxTemplate":"${0} ережесін сүзу үшін мәнді енгізу","conditionRange":"ауқым","waiCancelButton":"Осы тілқатысу терезесін болдырмау","relationAll":"барлық ережелер","conditionLarger":"үлкендеу","valueBoxLabel":"Мән","statusTipMsg":"${0} ішіндегі мәндер бойынша сүзу үшін сүзгі тақтасын нұқыңыз.","waiRelAll":"Барлық мына ережелерге сәйкес:","closeFilterBarBtn":"Сүзгі тақтасын жабу","a11yFilterBarDefButton":"Сүзгі...","trueLabel":"Шын","conditionIsNot":"емес","conditionIs":"–","ruleTitleTemplate":"${0} ережесі","waiRemoveRuleButtonTemplate":"${0} ережесін алып тастау","and":"және","conditionLess":"аздау","waiColumnSelectTemplate":"${0} ережесінің бағаны","anycolumn":"кез келген баған","filterDefDialogTitle":"Сүзгі","waiConditionSelectTemplate":"${0} ережесінің шарты","waiFilterButton":"Сүзгіні жіберу","statusTipTitle":"Сүзгі тақтасы","statusTipRelPre":"Сәйкес келу","anyColumnOption":"Кез келген баған","conditionSelectLabel":"Шарт","cancelButton":"Болдырмау","conditionNotStartWith":"басталмайды","conditionEndWith":"аяқталады","statusTipTitleNoFilter":"Сүзгі тақтасы","columnSelectLabel":"Баған","conditionNotContain":"құрамында жоқ","clearButton":"Тазалау ","conditionLargerEqual":"үлкендеу немесе тең","any":"кез келген","relationMsgFront":"Сәйкес келу","statusTipHeaderColumn":"Баған","defaultItemsName":"элементтер","conditionEqual":"тең","relationAny":"кез келген ереже","trueLabelEditable":"Белгіленген","or":"немесе","filterBarMsgHasFilterTemplate":"${1} ${2} ішінен ${0} көрсетілді.","rangeTo":"неге","conditionStartsWith":"басталады","waiRelAny":"Мына ережелерге сәйкес:","statusTipRelPost":"ережелер.","relationMsgTail":"","filterBarClearButton":"Сүзгіні тазалау","incompleteRuleTip":"Бұл ереже толық емес.","conditionLessEqual":"аздау немесе тең","waiFilterBarClearButton":"Сүзгіні тазалау","conditionAfter":"артында","statusTipHeaderCondition":"Ережелер","falseLabel":"Жалған","filterButton":"Сүзгі","clearFilterDialogTitle":"Сүзгіні тазалау","statusTipTitleHasFilter":"Сүзгі","addRuleButton":"Ереже қосу","waiAddRuleButton":"Жаңа ереже қосу","waiClearButton":"Сүзгіні тазалау","conditionNotEqual":"тең емес","conditionNotEndWith":"аяқталмайды","rangeTemplate":"${0} мәнінен ${1} мәніне","removeRuleButton":"Ережені алып тастау","waiFilterBarDefButton":"Кестені сүзу","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/kk/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/kk/Pagination.js
new file mode 100644
index 0000000..0ac223a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/kk/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Белгілі бір бетке өту","prevTip":"Алдыңғы бет","pageCountIndication":" (${0} бет)","pageStepLabelTemplate":"Бет ${0}","descTemplate":"${1} ${0} элементтің ${2} - ${3} элементі","lastTip":"Соңғы бет","nextTip":"Келесі бет","pageSizeLabelTemplate":"Бетіне ${0} элемент","dialogCancel":"Болдырмау","itemTitle":"элементтер","dialogConfirm":"Өту","firstTip":"Бірінші бет","allItemsLabelTemplate":"Барлық элементтер","dialogIndication":"Бет нөмірін көрсету","dialogTitle":"Бетке өту"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/kk/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/kk/Pagination.xd.js
new file mode 100644
index 0000000..28c51d4
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/kk/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.kk.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.kk.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "kk", ({"gotoButtonTitle":"Белгілі бір бетке өту","prevTip":"Алдыңғы бет","pageCountIndication":" (${0} бет)","pageStepLabelTemplate":"Бет ${0}","descTemplate":"${1} ${0} элементтің ${2} - ${3} элементі","lastTip":"Соңғы бет","nextTip":"Келесі бет","pageSizeLabelTemplate":"Бетіне ${0} элемент","dialogCancel":"Болдырмау","itemTitle":"элементтер","dialogConfirm":"Өту","firstTip":"Бірінші бет","allItemsLabelTemplate":"Барлық элементтер","dialogIndication":"Бет нөмірін көрсету","dialogTitle":"Бетке өту"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ko/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ko/EnhancedGrid.js
new file mode 100644
index 0000000..175f20c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ko/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"내림차순","ascending":"오름차순","nestedSort":"중첩 정렬","unsorted":"이 열을 정렬하지 않음","singleSort":"단일 정렬","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ko/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ko/EnhancedGrid.xd.js
new file mode 100644
index 0000000..d347af9
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ko/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.ko.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.ko.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "ko", ({"descending":"내림차순","ascending":"오름차순","nestedSort":"중첩 정렬","unsorted":"이 열을 정렬하지 않음","singleSort":"단일 정렬","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ko/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ko/Filter.js
new file mode 100644
index 0000000..315dbbc
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ko/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"이전","filterBarDefButton":"필터 정의","filterBarMsgNoFilterTemplate":"적용된 필터 없음","conditionContains":"포함","clearFilterMsg":"이렇게 하면 필터가 제거되며 사용 가능한 모든 레코드가 표시됩니다.","all":"모두","waiValueBoxTemplate":"규칙 ${0}에 대해 필터링할 값 입력","conditionRange":"범위","waiCancelButton":"이 대화 상자 취소","relationAll":"모든 규칙","conditionLarger":"보다 큼","valueBoxLabel":"값","statusTipMsg":"${0}에서 값에 대해 필터링하려면 여기서 필터 막대를 클릭하십시오.","waiRelAll":"다음 모든 규칙과 일치:","closeFilterBarBtn":"필터 막대 닫기","a11yFilterBarDefButton":"필터링...","trueLabel":"True","conditionIsNot":"동일하지 않음","conditionIs":"동일함","ruleTitleTemplate":"규칙 ${0}","waiRemoveRuleButtonTemplate":"규칙 ${0} 제거","and":"및","conditionLess":"보다 작음","waiColumnSelectTemplate":"규칙 ${0}에 대한 열","anycolumn":"임의의 열","filterDefDialogTitle":"필터","waiConditionSelectTemplate":"규칙 ${0}의 조건","waiFilterButton":"필터 제출","statusTipTitle":"필터 막대","statusTipRelPre":"일치","anyColumnOption":"임의의 열","conditionSelectLabel":"조건","cancelButton":"취소","conditionNotStartWith":"다음으로 시작하지 않음","conditionEndWith":"다음으로 종료","statusTipTitleNoFilter":"필터 막대","columnSelectLabel":"열","conditionNotContain":"포함하지 않음","clearButton":"지우기","conditionLargerEqual":"크거나 같음","any":"임의","relationMsgFront":"일치","statusTipHeaderColumn":"열","defaultItemsName":"항목","conditionEqual":"같음","relationAny":"임의의 규칙","trueLabelEditable":"확인됨","or":"또는","filterBarMsgHasFilterTemplate":"표시된 ${1} ${2} 중 ${0}입니다.","rangeTo":"까지","conditionStartsWith":"다음으로 시작","waiRelAny":"다음 중 임의의 규칙과 일치:","statusTipRelPost":"규칙.","relationMsgTail":"","filterBarClearButton":"필터 지우기","incompleteRuleTip":"이 규칙은 완전하지 않습니다.","conditionLessEqual":"작거나 같음","waiFilterBarClearButton":"필터 지우기","conditionAfter":"이후","statusTipHeaderCondition":"규칙","falseLabel":"False","filterButton":"필터","clearFilterDialogTitle":"필터 지우기","statusTipTitleHasFilter":"필터","addRuleButton":"규칙 추가","waiAddRuleButton":"새 규칙 추가","waiClearButton":"필터 지우기","conditionNotEqual":"같지 않음","conditionNotEndWith":"다음으로 종료되지 않음","rangeTemplate":"${0}부터 ${1}까지","removeRuleButton":"규칙 제거","waiFilterBarDefButton":"테이블 필터링","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ko/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ko/Filter.xd.js
new file mode 100644
index 0000000..b02877f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ko/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.ko.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.ko.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "ko", ({"conditionBefore":"이전","filterBarDefButton":"필터 정의","filterBarMsgNoFilterTemplate":"적용된 필터 없음","conditionContains":"포함","clearFilterMsg":"이렇게 하면 필터가 제거되며 사용 가능한 모든 레코드가 표시됩니다.","all":"모두","waiValueBoxTemplate":"규칙 ${0}에 대해 필터링할 값 입력","conditionRange":"범위","waiCancelButton":"이 대화 상자 취소","relationAll":"모든 규칙","conditionLarger":"보다 큼","valueBoxLabel":"값","statusTipMsg":"${0}에서 값에 대해 필터링하려면 여기서 필터 막대를 클릭하십시오.","waiRelAll":"다음 모든 규칙과 일치:","closeFilterBarBtn":"필터 막대 닫기","a11yFilterBarDefButton":"필터링...","trueLabel":"True","conditionIsNot":"동일하지 않음","conditionIs":"동일함","ruleTitleTemplate":"규칙 ${0}","waiRemoveRuleButtonTemplate":"규칙 ${0} 제거","and":"및","conditionLess":"보다 작음","waiColumnSelectTemplate":"규칙 ${0}에 대한 열","anycolumn":"임의의 열","filterDefDialogTitle":"필터","waiConditionSelectTemplate":"규칙 ${0}의 조건","waiFilterButton":"필터 제출","statusTipTitle":"필터 막대","statusTipRelPre":"일치","anyColumnOption":"임의의 열","conditionSelectLabel":"조건","cancelButton":"취소","conditionNotStartWith":"다음으로 시작하지 않음","conditionEndWith":"다음으로 종료","statusTipTitleNoFilter":"필터 막대","columnSelectLabel":"열","conditionNotContain":"포함하지 않음","clearButton":"지우기","conditionLargerEqual":"크거나 같음","any":"임의","relationMsgFront":"일치","statusTipHeaderColumn":"열","defaultItemsName":"항목","conditionEqual":"같음","relationAny":"임의의 규칙","trueLabelEditable":"확인됨","or":"또는","filterBarMsgHasFilterTemplate":"표시된 ${1} ${2} 중 ${0}입니다.","rangeTo":"까지","conditionStartsWith":"다음으로 시작","waiRelAny":"다음 중 임의의 규칙과 일치:","statusTipRelPost":"규칙.","relationMsgTail":"","filterBarClearButton":"필터 지우기","incompleteRuleTip":"이 규칙은 완전하지 않습니다.","conditionLessEqual":"작거나 같음","waiFilterBarClearButton":"필터 지우기","conditionAfter":"이후","statusTipHeaderCondition":"규칙","falseLabel":"False","filterButton":"필터","clearFilterDialogTitle":"필터 지우기","statusTipTitleHasFilter":"필터","addRuleButton":"규칙 추가","waiAddRuleButton":"새 규칙 추가","waiClearButton":"필터 지우기","conditionNotEqual":"같지 않음","conditionNotEndWith":"다음으로 종료되지 않음","rangeTemplate":"${0}부터 ${1}까지","removeRuleButton":"규칙 제거","waiFilterBarDefButton":"테이블 필터링","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ko/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ko/Pagination.js
new file mode 100644
index 0000000..c742362
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ko/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"특정 페이지 찾아가기","prevTip":"이전 페이지","pageCountIndication":"(${0}페이지)","pageStepLabelTemplate":"${0}페이지","descTemplate":"${2} - ${1} ${0} 중 ${3}","lastTip":"마지막 페이지","nextTip":"다음 페이지","pageSizeLabelTemplate":"페이지당 ${0}개 항목","dialogCancel":"취소","itemTitle":"항목","dialogConfirm":"이동","firstTip":"첫 페이지","allItemsLabelTemplate":"모든 항목","dialogIndication":"페이지 번호 지정","dialogTitle":"페이지 찾아가기"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ko/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ko/Pagination.xd.js
new file mode 100644
index 0000000..c0b277f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ko/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.ko.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.ko.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "ko", ({"gotoButtonTitle":"특정 페이지 찾아가기","prevTip":"이전 페이지","pageCountIndication":"(${0}페이지)","pageStepLabelTemplate":"${0}페이지","descTemplate":"${2} - ${1} ${0} 중 ${3}","lastTip":"마지막 페이지","nextTip":"다음 페이지","pageSizeLabelTemplate":"페이지당 ${0}개 항목","dialogCancel":"취소","itemTitle":"항목","dialogConfirm":"이동","firstTip":"첫 페이지","allItemsLabelTemplate":"모든 항목","dialogIndication":"페이지 번호 지정","dialogTitle":"페이지 찾아가기"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/nb/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/nb/EnhancedGrid.js
new file mode 100644
index 0000000..96f3f3d
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/nb/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Synkende","ascending":"Stigende","nestedSort":"Nestet sortering","unsorted":"Ikke sorter denne kolonnen","singleSort":"Enkel sortering","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/nb/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/nb/EnhancedGrid.xd.js
new file mode 100644
index 0000000..bd58f46
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/nb/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.nb.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.nb.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "nb", ({"descending":"Synkende","ascending":"Stigende","nestedSort":"Nestet sortering","unsorted":"Ikke sorter denne kolonnen","singleSort":"Enkel sortering","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/nb/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/nb/Filter.js
new file mode 100644
index 0000000..44c3eba
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/nb/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"før","filterBarDefButton":"Definer filter","filterBarMsgNoFilterTemplate":"Det er ikke brukt filter","conditionContains":"inneholder","clearFilterMsg":"Dette fjerner filteret og viser alle tilgjengelig poster.","all":"alle","waiValueBoxTemplate":"Angi verdi som skal filtreres for regel ${0}","conditionRange":"område","waiCancelButton":"Avbryt denne dialogboksen","relationAll":"alle regler","conditionLarger":"er større enn","valueBoxLabel":"Verdi","statusTipMsg":"Klikk på filterlinjen her for å filtrere på verdier i ${0}.","waiRelAll":"Samsvar med alle følgende regler:","closeFilterBarBtn":"Lukk filterlinje","a11yFilterBarDefButton":"Filtrer...","trueLabel":"Sann","conditionIsNot":"er ikke","conditionIs":"er","ruleTitleTemplate":"Regel ${0}","waiRemoveRuleButtonTemplate":"Fjern regel ${0}","and":"og","conditionLess":"er mindre enn","waiColumnSelectTemplate":"Kolonne for regel ${0}","anycolumn":"enhver kolonne","filterDefDialogTitle":"Filter","waiConditionSelectTemplate":"Betingelse for regel ${0}","waiFilterButton":"Send filteret","statusTipTitle":"Filterlinje","statusTipRelPre":"Samsvar","anyColumnOption":"Enhver kolonne","conditionSelectLabel":"Betingelse","cancelButton":"Avbryt","conditionNotStartWith":"begynner ikke med","conditionEndWith":"slutter med","statusTipTitleNoFilter":"Filterlinje","columnSelectLabel":"Kolonne","conditionNotContain":"inneholder ikke","clearButton":"Tøm","conditionLargerEqual":"større enn eller lik","any":"minst en","relationMsgFront":"Samsvar","statusTipHeaderColumn":"Kolonne","defaultItemsName":"elementer","conditionEqual":"er lik","relationAny":"minst en regel","trueLabelEditable":"Valgt","or":"eller","filterBarMsgHasFilterTemplate":"${0} av ${1} ${2} vist.","rangeTo":"til","conditionStartsWith":"begynner med","waiRelAny":"Samsvar med minst en av følgende regler:","statusTipRelPost":"regler.","relationMsgTail":"","filterBarClearButton":"Tøm filter","incompleteRuleTip":"Denne regelen er ikke fullstendig.","conditionLessEqual":"mindre enn eller lik","waiFilterBarClearButton":"Tøm filteret","conditionAfter":"etter","statusTipHeaderCondition":"Regler","falseLabel":"Usann","filterButton":"Filter","clearFilterDialogTitle":"Tøm filter","statusTipTitleHasFilter":"Filter","addRuleButton":"Legg til regel","waiAddRuleButton":"Legg til en ny regel","waiClearButton":"Tøm filteret","conditionNotEqual":"er ikke lik","conditionNotEndWith":"slutter ikke med","rangeTemplate":"fra ${0} til ${1}","removeRuleButton":"Fjern regel","waiFilterBarDefButton":"Filtrer tabellen","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/nb/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/nb/Filter.xd.js
new file mode 100644
index 0000000..f3ebd4d
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/nb/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.nb.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.nb.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "nb", ({"conditionBefore":"før","filterBarDefButton":"Definer filter","filterBarMsgNoFilterTemplate":"Det er ikke brukt filter","conditionContains":"inneholder","clearFilterMsg":"Dette fjerner filteret og viser alle tilgjengelig poster.","all":"alle","waiValueBoxTemplate":"Angi verdi som skal filtreres for regel ${0}","conditionRange":"område","waiCancelButton":"Avbryt denne dialogboksen","relationAll":"alle regler","conditionLarger":"er større enn","valueBoxLabel":"Verdi","statusTipMsg":"Klikk på filterlinjen her for å filtrere på verdier i ${0}.","waiRelAll":"Samsvar med alle følgende regler:","closeFilterBarBtn":"Lukk filterlinje","a11yFilterBarDefButton":"Filtrer...","trueLabel":"Sann","conditionIsNot":"er ikke","conditionIs":"er","ruleTitleTemplate":"Regel ${0}","waiRemoveRuleButtonTemplate":"Fjern regel ${0}","and":"og","conditionLess":"er mindre enn","waiColumnSelectTemplate":"Kolonne for regel ${0}","anycolumn":"enhver kolonne","filterDefDialogTitle":"Filter","waiConditionSelectTemplate":"Betingelse for regel ${0}","waiFilterButton":"Send filteret","statusTipTitle":"Filterlinje","statusTipRelPre":"Samsvar","anyColumnOption":"Enhver kolonne","conditionSelectLabel":"Betingelse","cancelButton":"Avbryt","conditionNotStartWith":"begynner ikke med","conditionEndWith":"slutter med","statusTipTitleNoFilter":"Filterlinje","columnSelectLabel":"Kolonne","conditionNotContain":"inneholder ikke","clearButton":"Tøm","conditionLargerEqual":"større enn eller lik","any":"minst en","relationMsgFront":"Samsvar","statusTipHeaderColumn":"Kolonne","defaultItemsName":"elementer","conditionEqual":"er lik","relationAny":"minst en regel","trueLabelEditable":"Valgt","or":"eller","filterBarMsgHasFilterTemplate":"${0} av ${1} ${2} vist.","rangeTo":"til","conditionStartsWith":"begynner med","waiRelAny":"Samsvar med minst en av følgende regler:","statusTipRelPost":"regler.","relationMsgTail":"","filterBarClearButton":"Tøm filter","incompleteRuleTip":"Denne regelen er ikke fullstendig.","conditionLessEqual":"mindre enn eller lik","waiFilterBarClearButton":"Tøm filteret","conditionAfter":"etter","statusTipHeaderCondition":"Regler","falseLabel":"Usann","filterButton":"Filter","clearFilterDialogTitle":"Tøm filter","statusTipTitleHasFilter":"Filter","addRuleButton":"Legg til regel","waiAddRuleButton":"Legg til en ny regel","waiClearButton":"Tøm filteret","conditionNotEqual":"er ikke lik","conditionNotEndWith":"slutter ikke med","rangeTemplate":"fra ${0} til ${1}","removeRuleButton":"Fjern regel","waiFilterBarDefButton":"Filtrer tabellen","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/nb/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/nb/Pagination.js
new file mode 100644
index 0000000..23729dc
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/nb/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Gå til en bestemt side","prevTip":"Forrige side","pageCountIndication":" (${0} sider)","pageStepLabelTemplate":"Side ${0}","descTemplate":"${2} - ${3} av ${1} ${0}","lastTip":"Siste side","nextTip":"Neste side","pageSizeLabelTemplate":"${0} elementer per side","dialogCancel":"Avbryt","itemTitle":"elementer","dialogConfirm":"OK","firstTip":"Første side","allItemsLabelTemplate":"Alle elementer","dialogIndication":"Angi sidetall","dialogTitle":"Gå til side"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/nb/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/nb/Pagination.xd.js
new file mode 100644
index 0000000..d526c81
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/nb/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.nb.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.nb.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "nb", ({"gotoButtonTitle":"Gå til en bestemt side","prevTip":"Forrige side","pageCountIndication":" (${0} sider)","pageStepLabelTemplate":"Side ${0}","descTemplate":"${2} - ${3} av ${1} ${0}","lastTip":"Siste side","nextTip":"Neste side","pageSizeLabelTemplate":"${0} elementer per side","dialogCancel":"Avbryt","itemTitle":"elementer","dialogConfirm":"OK","firstTip":"Første side","allItemsLabelTemplate":"Alle elementer","dialogIndication":"Angi sidetall","dialogTitle":"Gå til side"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/nl/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/nl/EnhancedGrid.js
new file mode 100644
index 0000000..5316922
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/nl/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Aflopend","ascending":"Oplopend","nestedSort":"Geneste sorteerbewerking","unsorted":"Deze kolom niet sorteren","singleSort":"Enkele sorteerbewerking","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/nl/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/nl/EnhancedGrid.xd.js
new file mode 100644
index 0000000..615798a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/nl/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.nl.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.nl.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "nl", ({"descending":"Aflopend","ascending":"Oplopend","nestedSort":"Geneste sorteerbewerking","unsorted":"Deze kolom niet sorteren","singleSort":"Enkele sorteerbewerking","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/nl/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/nl/Filter.js
new file mode 100644
index 0000000..f0f4ef4
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/nl/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"voor","filterBarDefButton":"Filter definiëren","filterBarMsgNoFilterTemplate":"Geen filter gebruikt","conditionContains":"bevat","clearFilterMsg":"Hiermee verwijdert u het filter en worden alle beschikbare records afgebeeld.","all":"alle","waiValueBoxTemplate":"Geef een filterwaarde op voor regel ${0}","conditionRange":"bereik","waiCancelButton":"Dit venster sluiten","relationAll":"alle regels","conditionLarger":"is groter dan","valueBoxLabel":"Waarde","statusTipMsg":"Klik op de filterbalk om te filterne op waarden in ${0}.","waiRelAll":"Voldoen aan alle volgende regels:","closeFilterBarBtn":"Filterbalk sluiten","a11yFilterBarDefButton":"Filteren...","trueLabel":"Waar","conditionIsNot":"is niet","conditionIs":"is","ruleTitleTemplate":"Regel ${0}","waiRemoveRuleButtonTemplate":"Regel ${0} verwijderen","and":"en","conditionLess":"is kleiner dan","waiColumnSelectTemplate":"Kolom voor regel ${0}","anycolumn":"een kolom","filterDefDialogTitle":"Filteren","waiConditionSelectTemplate":"Voorwaarde voor regel ${0}","waiFilterButton":"Filter activeren","statusTipTitle":"Filterbalk","statusTipRelPre":"Voldoen","anyColumnOption":"Een kolom","conditionSelectLabel":"Voorwaarde","cancelButton":"Annuleren","conditionNotStartWith":"begint niet met","conditionEndWith":"eindigt met","statusTipTitleNoFilter":"Filterbalk","columnSelectLabel":"Kolom","conditionNotContain":"bevat niet","clearButton":"Wissen","conditionLargerEqual":"ggroter dan of gelijk aan","any":"elke","relationMsgFront":"Voldoen","statusTipHeaderColumn":"Kolom","defaultItemsName":"items","conditionEqual":"gelijk aan","relationAny":"een regel","trueLabelEditable":"Geselecteerd","or":"of","filterBarMsgHasFilterTemplate":"${0} van ${1} ${2} wordt afgebeeld.","rangeTo":"tot","conditionStartsWith":"begint met","waiRelAny":"Voldoen aan een van de volgende regels:","statusTipRelPost":"regels","relationMsgTail":"","filterBarClearButton":"Filter wissen","incompleteRuleTip":"Deze regel is onvolledig.","conditionLessEqual":"kleiner dan of gelijk aan","waiFilterBarClearButton":"Filter wissen","conditionAfter":"na","statusTipHeaderCondition":"Regels","falseLabel":"Onwaar","filterButton":"Filteren","clearFilterDialogTitle":"Filter wissen","statusTipTitleHasFilter":"Filteren","addRuleButton":"Regel toevoegen","waiAddRuleButton":"Nieuwe regel toevoegen","waiClearButton":"Filter wissen","conditionNotEqual":"niet gelijk aan","conditionNotEndWith":"eindigt niet met","rangeTemplate":"van ${0} tot ${1}","removeRuleButton":"Regel verwijderen","waiFilterBarDefButton":"Tabel filteren","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/nl/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/nl/Filter.xd.js
new file mode 100644
index 0000000..80a6eaf
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/nl/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.nl.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.nl.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "nl", ({"conditionBefore":"voor","filterBarDefButton":"Filter definiëren","filterBarMsgNoFilterTemplate":"Geen filter gebruikt","conditionContains":"bevat","clearFilterMsg":"Hiermee verwijdert u het filter en worden alle beschikbare records afgebeeld.","all":"alle","waiValueBoxTemplate":"Geef een filterwaarde op voor regel ${0}","conditionRange":"bereik","waiCancelButton":"Dit venster sluiten","relationAll":"alle regels","conditionLarger":"is groter dan","valueBoxLabel":"Waarde","statusTipMsg":"Klik op de filterbalk om te filterne op waarden in ${0}.","waiRelAll":"Voldoen aan alle volgende regels:","closeFilterBarBtn":"Filterbalk sluiten","a11yFilterBarDefButton":"Filteren...","trueLabel":"Waar","conditionIsNot":"is niet","conditionIs":"is","ruleTitleTemplate":"Regel ${0}","waiRemoveRuleButtonTemplate":"Regel ${0} verwijderen","and":"en","conditionLess":"is kleiner dan","waiColumnSelectTemplate":"Kolom voor regel ${0}","anycolumn":"een kolom","filterDefDialogTitle":"Filteren","waiConditionSelectTemplate":"Voorwaarde voor regel ${0}","waiFilterButton":"Filter activeren","statusTipTitle":"Filterbalk","statusTipRelPre":"Voldoen","anyColumnOption":"Een kolom","conditionSelectLabel":"Voorwaarde","cancelButton":"Annuleren","conditionNotStartWith":"begint niet met","conditionEndWith":"eindigt met","statusTipTitleNoFilter":"Filterbalk","columnSelectLabel":"Kolom","conditionNotContain":"bevat niet","clearButton":"Wissen","conditionLargerEqual":"ggroter dan of gelijk aan","any":"elke","relationMsgFront":"Voldoen","statusTipHeaderColumn":"Kolom","defaultItemsName":"items","conditionEqual":"gelijk aan","relationAny":"een regel","trueLabelEditable":"Geselecteerd","or":"of","filterBarMsgHasFilterTemplate":"${0} van ${1} ${2} wordt afgebeeld.","rangeTo":"tot","conditionStartsWith":"begint met","waiRelAny":"Voldoen aan een van de volgende regels:","statusTipRelPost":"regels","relationMsgTail":"","filterBarClearButton":"Filter wissen","incompleteRuleTip":"Deze regel is onvolledig.","conditionLessEqual":"kleiner dan of gelijk aan","waiFilterBarClearButton":"Filter wissen","conditionAfter":"na","statusTipHeaderCondition":"Regels","falseLabel":"Onwaar","filterButton":"Filteren","clearFilterDialogTitle":"Filter wissen","statusTipTitleHasFilter":"Filteren","addRuleButton":"Regel toevoegen","waiAddRuleButton":"Nieuwe regel toevoegen","waiClearButton":"Filter wissen","conditionNotEqual":"niet gelijk aan","conditionNotEndWith":"eindigt niet met","rangeTemplate":"van ${0} tot ${1}","removeRuleButton":"Regel verwijderen","waiFilterBarDefButton":"Tabel filteren","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/nl/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/nl/Pagination.js
new file mode 100644
index 0000000..09e0a0a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/nl/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Naar specifieke pagina","prevTip":"Vorige pagina","pageCountIndication":" (${0} pagina's)","pageStepLabelTemplate":"Pagina ${0}","descTemplate":"${2} - ${3} van ${1} ${0}","lastTip":"Laatste pagina","nextTip":"Volgende pagina","pageSizeLabelTemplate":"${0} items per pagina","dialogCancel":"Annuleren","itemTitle":"items","dialogConfirm":"Go","firstTip":"Eerste pagina","allItemsLabelTemplate":"Alle items","dialogIndication":"Geef het paginanummer op","dialogTitle":"Naar pagina"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/nl/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/nl/Pagination.xd.js
new file mode 100644
index 0000000..37257d5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/nl/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.nl.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.nl.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "nl", ({"gotoButtonTitle":"Naar specifieke pagina","prevTip":"Vorige pagina","pageCountIndication":" (${0} pagina's)","pageStepLabelTemplate":"Pagina ${0}","descTemplate":"${2} - ${3} van ${1} ${0}","lastTip":"Laatste pagina","nextTip":"Volgende pagina","pageSizeLabelTemplate":"${0} items per pagina","dialogCancel":"Annuleren","itemTitle":"items","dialogConfirm":"Go","firstTip":"Eerste pagina","allItemsLabelTemplate":"Alle items","dialogIndication":"Geef het paginanummer op","dialogTitle":"Naar pagina"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pl/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pl/EnhancedGrid.js
new file mode 100644
index 0000000..b06a7e9
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pl/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Malejąco","ascending":"Rosnąco","nestedSort":"Sortowanie zagnieżdżone","unsorted":"Nie sortuj tej kolumny","singleSort":"Sortowanie pojedyncze","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pl/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pl/EnhancedGrid.xd.js
new file mode 100644
index 0000000..942a2cd
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pl/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.pl.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.pl.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "pl", ({"descending":"Malejąco","ascending":"Rosnąco","nestedSort":"Sortowanie zagnieżdżone","unsorted":"Nie sortuj tej kolumny","singleSort":"Sortowanie pojedyncze","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pl/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pl/Filter.js
new file mode 100644
index 0000000..a2e0132
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pl/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"przed","filterBarDefButton":"Zdefiniuj filtr","filterBarMsgNoFilterTemplate":"Nie zastosowano żadnego filtru","conditionContains":"zawiera","clearFilterMsg":"Spowoduje to usunięcie filtru oraz wyświetlenie wszystkich dostępnych rekordów. ","all":"wszystkie","waiValueBoxTemplate":"Wprowadź wartość filtru dla reguły ${0}","conditionRange":"zakres","waiCancelButton":"Anuluj to okno dialogowe","relationAll":"wszystkie reguły","conditionLarger":"jest większe niż","valueBoxLabel":"Wartość","statusTipMsg":"Kliknij pasek filtru w tym miejscu, aby filtrować wartości znajdujące się w ${0}. ","waiRelAll":"Dopasuj wszystkie następujące reguły:","closeFilterBarBtn":"Zamknij pasek filtru","a11yFilterBarDefButton":"Filtruj...","trueLabel":"Prawda","conditionIsNot":"nie jest","conditionIs":"jest","ruleTitleTemplate":"Reguła ${0}","waiRemoveRuleButtonTemplate":"Usuń regułę ${0}","and":"oraz","conditionLess":"jest mniejsze niż","waiColumnSelectTemplate":"Kolumna reguły ${0}","anycolumn":"dowolna kolumna","filterDefDialogTitle":"Filtr","waiConditionSelectTemplate":"Warunek reguły ${0}","waiFilterButton":"Wyślij filtr","statusTipTitle":"Pasek filtru","statusTipRelPre":"Zgodne","anyColumnOption":"Dowolna kolumna","conditionSelectLabel":"Warunek","cancelButton":"Anuluj","conditionNotStartWith":"nie zaczyna się od","conditionEndWith":"kończy się na","statusTipTitleNoFilter":"Pasek filtru","columnSelectLabel":"Kolumna","conditionNotContain":"nie zawiera","clearButton":"Wyczyść","conditionLargerEqual":"większe lub równe","any":"dowolne","relationMsgFront":"Zgodne","statusTipHeaderColumn":"Kolumna","defaultItemsName":"elementy","conditionEqual":"równe","relationAny":"dowolne reguły","trueLabelEditable":"Sprawdzone","or":"lub","filterBarMsgHasFilterTemplate":"Liczba wyświetlanych elementów ${2}: ${0} z ${1}. ","rangeTo":"do","conditionStartsWith":"zaczyna się od","waiRelAny":"Dopasuj dowolne z następujących reguł:","statusTipRelPost":"reguły. ","relationMsgTail":"","filterBarClearButton":"Wyczyść filtr","incompleteRuleTip":"Ta reguła nie jest kompletna. ","conditionLessEqual":"mniejsze lub równe","waiFilterBarClearButton":"Wyczyść filtr","conditionAfter":"po","statusTipHeaderCondition":"Reguły","falseLabel":"Fałsz","filterButton":"Filtr","clearFilterDialogTitle":"Wyczyść filtr","statusTipTitleHasFilter":"Filtr","addRuleButton":"Dodaj regułę","waiAddRuleButton":"Dodaj nową regułę","waiClearButton":"Wyczyść filtr","conditionNotEqual":"nie jest równe","conditionNotEndWith":"nie kończy się na","rangeTemplate":"od ${0} do ${1}","removeRuleButton":"Usuń regułę","waiFilterBarDefButton":"Filtruj tabelę","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pl/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pl/Filter.xd.js
new file mode 100644
index 0000000..0f88461
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pl/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.pl.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.pl.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "pl", ({"conditionBefore":"przed","filterBarDefButton":"Zdefiniuj filtr","filterBarMsgNoFilterTemplate":"Nie zastosowano żadnego filtru","conditionContains":"zawiera","clearFilterMsg":"Spowoduje to usunięcie filtru oraz wyświetlenie wszystkich dostępnych rekordów. ","all":"wszystkie","waiValueBoxTemplate":"Wprowadź wartość filtru dla reguły ${0}","conditionRange":"zakres","waiCancelButton":"Anuluj to okno dialogowe","relationAll":"wszystkie reguły","conditionLarger":"jest większe niż","valueBoxLabel":"Wartość","statusTipMsg":"Kliknij pasek filtru w tym miejscu, aby filtrować wartości znajdujące się w ${0}. ","waiRelAll":"Dopasuj wszystkie następujące reguły:","closeFilterBarBtn":"Zamknij pasek filtru","a11yFilterBarDefButton":"Filtruj...","trueLabel":"Prawda","conditionIsNot":"nie jest","conditionIs":"jest","ruleTitleTemplate":"Reguła ${0}","waiRemoveRuleButtonTemplate":"Usuń regułę ${0}","and":"oraz","conditionLess":"jest mniejsze niż","waiColumnSelectTemplate":"Kolumna reguły ${0}","anycolumn":"dowolna kolumna","filterDefDialogTitle":"Filtr","waiConditionSelectTemplate":"Warunek reguły ${0}","waiFilterButton":"Wyślij filtr","statusTipTitle":"Pasek filtru","statusTipRelPre":"Zgodne","anyColumnOption":"Dowolna kolumna","conditionSelectLabel":"Warunek","cancelButton":"Anuluj","conditionNotStartWith":"nie zaczyna się od","conditionEndWith":"kończy się na","statusTipTitleNoFilter":"Pasek filtru","columnSelectLabel":"Kolumna","conditionNotContain":"nie zawiera","clearButton":"Wyczyść","conditionLargerEqual":"większe lub równe","any":"dowolne","relationMsgFront":"Zgodne","statusTipHeaderColumn":"Kolumna","defaultItemsName":"elementy","conditionEqual":"równe","relationAny":"dowolne reguły","trueLabelEditable":"Sprawdzone","or":"lub","filterBarMsgHasFilterTemplate":"Liczba wyświetlanych elementów ${2}: ${0} z ${1}. ","rangeTo":"do","conditionStartsWith":"zaczyna się od","waiRelAny":"Dopasuj dowolne z następujących reguł:","statusTipRelPost":"reguły. ","relationMsgTail":"","filterBarClearButton":"Wyczyść filtr","incompleteRuleTip":"Ta reguła nie jest kompletna. ","conditionLessEqual":"mniejsze lub równe","waiFilterBarClearButton":"Wyczyść filtr","conditionAfter":"po","statusTipHeaderCondition":"Reguły","falseLabel":"Fałsz","filterButton":"Filtr","clearFilterDialogTitle":"Wyczyść filtr","statusTipTitleHasFilter":"Filtr","addRuleButton":"Dodaj regułę","waiAddRuleButton":"Dodaj nową regułę","waiClearButton":"Wyczyść filtr","conditionNotEqual":"nie jest równe","conditionNotEndWith":"nie kończy się na","rangeTemplate":"od ${0} do ${1}","removeRuleButton":"Usuń regułę","waiFilterBarDefButton":"Filtruj tabelę","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pl/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pl/Pagination.js
new file mode 100644
index 0000000..ef66d0c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pl/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Przejdź do konkretnej strony","prevTip":"Poprzednia strona","pageCountIndication":" (liczba stron: ${0})","pageStepLabelTemplate":"Strona ${0}","descTemplate":"Od ${2} do ${3} z ${1} ${0}","lastTip":"Ostatnia strona","nextTip":"Następna strona","pageSizeLabelTemplate":"Liczba elementów na stronę: ${0}","dialogCancel":"Anuluj","itemTitle":"elementy","dialogConfirm":"Przejdź","firstTip":"Pierwsza strona","allItemsLabelTemplate":"Wszystkie elementy","dialogIndication":"Określ numer strony","dialogTitle":"Przechodzenie do strony"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pl/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pl/Pagination.xd.js
new file mode 100644
index 0000000..58d2743
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pl/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.pl.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.pl.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "pl", ({"gotoButtonTitle":"Przejdź do konkretnej strony","prevTip":"Poprzednia strona","pageCountIndication":" (liczba stron: ${0})","pageStepLabelTemplate":"Strona ${0}","descTemplate":"Od ${2} do ${3} z ${1} ${0}","lastTip":"Ostatnia strona","nextTip":"Następna strona","pageSizeLabelTemplate":"Liczba elementów na stronę: ${0}","dialogCancel":"Anuluj","itemTitle":"elementy","dialogConfirm":"Przejdź","firstTip":"Pierwsza strona","allItemsLabelTemplate":"Wszystkie elementy","dialogIndication":"Określ numer strony","dialogTitle":"Przechodzenie do strony"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js
new file mode 100644
index 0000000..d5da247
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Descendente","ascending":"Ascendente","nestedSort":"Ordenação imbricada","unsorted":"Não ordenar esta coluna","singleSort":"Ordenação única","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.xd.js
new file mode 100644
index 0000000..4c1c062
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.pt-pt.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.pt-pt.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "pt-pt", ({"descending":"Descendente","ascending":"Ascendente","nestedSort":"Ordenação imbricada","unsorted":"Não ordenar esta coluna","singleSort":"Ordenação única","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/Filter.js
new file mode 100644
index 0000000..28a03cc
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"antes","filterBarDefButton":"Definir filtro","filterBarMsgNoFilterTemplate":"Nenhum filtro aplicado","conditionContains":"contém","clearFilterMsg":"Este procedimento irá remover o filtro e apresentar todos os registos disponíveis.","all":"tudo","waiValueBoxTemplate":"Introduzir valor para filtrar para a regra ${0}","conditionRange":"intervalo","waiCancelButton":"Cancelar esta caixa de diálogo","relationAll":"todas as regras","conditionLarger":"é maior do que","valueBoxLabel":"Valor","statusTipMsg":"Faça clique na barra de filtro para filtrar os valores em ${0}.","waiRelAll":"Corresponder a todas as seguintes regras:","closeFilterBarBtn":"Fechar barra de filtro","a11yFilterBarDefButton":"Filtrar...","trueLabel":"True","conditionIsNot":"não é","conditionIs":"é","ruleTitleTemplate":"Regra ${0}","waiRemoveRuleButtonTemplate":"Remover regra ${0}","and":"and","conditionLess":"é menor do que","waiColumnSelectTemplate":"Coluna para a regra ${0}","anycolumn":"qualquer coluna","filterDefDialogTitle":"Filtro","waiConditionSelectTemplate":"Condição para a regra ${0}","waiFilterButton":"Submeter o filtro","statusTipTitle":"Barra do filtro","statusTipRelPre":"Correspondência","anyColumnOption":"Qualquer coluna","conditionSelectLabel":"Condição","cancelButton":"Cancelar","conditionNotStartWith":"não começa com","conditionEndWith":"termina com","statusTipTitleNoFilter":"Barra do filtro","columnSelectLabel":"Coluna","conditionNotContain":"não contém","clearButton":"Limpar","conditionLargerEqual":"maior ou igual","any":"qualquer","relationMsgFront":"Corresponder","statusTipHeaderColumn":"Coluna","defaultItemsName":"itens","conditionEqual":"igual","relationAny":"quaisquer regras","trueLabelEditable":"Verificado","or":"or","filterBarMsgHasFilterTemplate":"${0} de ${1} ${2} apresentado(s).","rangeTo":"a","conditionStartsWith":"começa com","waiRelAny":"Corresponder a qualquer uma das seguintes regras:","statusTipRelPost":"regras.","relationMsgTail":"","filterBarClearButton":"Limpar filtro","incompleteRuleTip":"Esta regra não está completa.","conditionLessEqual":"menor ou igual","waiFilterBarClearButton":"Limpar o filtro","conditionAfter":"após","statusTipHeaderCondition":"Regras","falseLabel":"False","filterButton":"Filtro","clearFilterDialogTitle":"Limpar filtro","statusTipTitleHasFilter":"Filtro","addRuleButton":"Adicionar regra","waiAddRuleButton":"Adicionar uma nova regra","waiClearButton":"Limpar o filtro","conditionNotEqual":"não é igual","conditionNotEndWith":"não termina com","rangeTemplate":"de ${0} a ${1}","removeRuleButton":"Remover regra","waiFilterBarDefButton":"Filtrar a tabela","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/Filter.xd.js
new file mode 100644
index 0000000..9df6178
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.pt-pt.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.pt-pt.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "pt-pt", ({"conditionBefore":"antes","filterBarDefButton":"Definir filtro","filterBarMsgNoFilterTemplate":"Nenhum filtro aplicado","conditionContains":"contém","clearFilterMsg":"Este procedimento irá remover o filtro e apresentar todos os registos disponíveis.","all":"tudo","waiValueBoxTemplate":"Introduzir valor para filtrar para a regra ${0}","conditionRange":"intervalo","waiCancelButton":"Cancelar esta caixa de diálogo","relationAll":"todas as regras","conditionLarger":"é maior do que","valueBoxLabel":"Valor","statusTipMsg":"Faça clique na barra de filtro para filtrar os valores em ${0}.","waiRelAll":"Corresponder a todas as seguintes regras:","closeFilterBarBtn":"Fechar barra de filtro","a11yFilterBarDefButton":"Filtrar...","trueLabel":"True","conditionIsNot":"não é","conditionIs":"é","ruleTitleTemplate":"Regra ${0}","waiRemoveRuleButtonTemplate":"Remover regra ${0}","and":"and","conditionLess":"é menor do que","waiColumnSelectTemplate":"Coluna para a regra ${0}","anycolumn":"qualquer coluna","filterDefDialogTitle":"Filtro","waiConditionSelectTemplate":"Condição para a regra ${0}","waiFilterButton":"Submeter o filtro","statusTipTitle":"Barra do filtro","statusTipRelPre":"Correspondência","anyColumnOption":"Qualquer coluna","conditionSelectLabel":"Condição","cancelButton":"Cancelar","conditionNotStartWith":"não começa com","conditionEndWith":"termina com","statusTipTitleNoFilter":"Barra do filtro","columnSelectLabel":"Coluna","conditionNotContain":"não contém","clearButton":"Limpar","conditionLargerEqual":"maior ou igual","any":"qualquer","relationMsgFront":"Corresponder","statusTipHeaderColumn":"Coluna","defaultItemsName":"itens","conditionEqual":"igual","relationAny":"quaisquer regras","trueLabelEditable":"Verificado","or":"or","filterBarMsgHasFilterTemplate":"${0} de ${1} ${2} apresentado(s).","rangeTo":"a","conditionStartsWith":"começa com","waiRelAny":"Corresponder a qualquer uma das seguintes regras:","statusTipRelPost":"regras.","relationMsgTail":"","filterBarClearButton":"Limpar filtro","incompleteRuleTip":"Esta regra não está completa.","conditionLessEqual":"menor ou igual","waiFilterBarClearButton":"Limpar o filtro","conditionAfter":"após","statusTipHeaderCondition":"Regras","falseLabel":"False","filterButton":"Filtro","clearFilterDialogTitle":"Limpar filtro","statusTipTitleHasFilter":"Filtro","addRuleButton":"Adicionar regra","waiAddRuleButton":"Adicionar uma nova regra","waiClearButton":"Limpar o filtro","conditionNotEqual":"não é igual","conditionNotEndWith":"não termina com","rangeTemplate":"de ${0} a ${1}","removeRuleButton":"Remover regra","waiFilterBarDefButton":"Filtrar a tabela","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/Pagination.js
new file mode 100644
index 0000000..f6b6542
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Avançar para uma página específica","prevTip":"Página anterior","pageCountIndication":" (${0} páginas)","pageStepLabelTemplate":"Página ${0}","descTemplate":"${2} - ${3} de ${1} ${0}","lastTip":"Última página","nextTip":"Página seguinte","pageSizeLabelTemplate":"${0} itens por página","dialogCancel":"Cancelar","itemTitle":"itens","dialogConfirm":"Ir","firstTip":"Primeira página","allItemsLabelTemplate":"Todos os itens","dialogIndication":"Especificar o número de página","dialogTitle":"Avançar para a página"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/Pagination.xd.js
new file mode 100644
index 0000000..93a7f21
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pt-pt/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.pt-pt.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.pt-pt.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "pt-pt", ({"gotoButtonTitle":"Avançar para uma página específica","prevTip":"Página anterior","pageCountIndication":" (${0} páginas)","pageStepLabelTemplate":"Página ${0}","descTemplate":"${2} - ${3} de ${1} ${0}","lastTip":"Última página","nextTip":"Página seguinte","pageSizeLabelTemplate":"${0} itens por página","dialogCancel":"Cancelar","itemTitle":"itens","dialogConfirm":"Ir","firstTip":"Primeira página","allItemsLabelTemplate":"Todos os itens","dialogIndication":"Especificar o número de página","dialogTitle":"Avançar para a página"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pt/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pt/EnhancedGrid.js
new file mode 100644
index 0000000..5669cb0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pt/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Descendente","ascending":"Ascendente","nestedSort":"Classificação Aninhada","unsorted":"Não classificar esta coluna","singleSort":"Classificação Única","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pt/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pt/EnhancedGrid.xd.js
new file mode 100644
index 0000000..e643dc9
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pt/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.pt.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.pt.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "pt", ({"descending":"Descendente","ascending":"Ascendente","nestedSort":"Classificação Aninhada","unsorted":"Não classificar esta coluna","singleSort":"Classificação Única","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pt/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pt/Filter.js
new file mode 100644
index 0000000..88b5758
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pt/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"antes","filterBarDefButton":"Definir filtro","filterBarMsgNoFilterTemplate":"Nenhum filtro aplicado","conditionContains":"contém","clearFilterMsg":"Isso removerá o filtro e mostrará todos os registros disponíveis.","all":"todos","waiValueBoxTemplate":"Insira o valor para filtragem da regra ${0}","conditionRange":"intervalo","waiCancelButton":"Cancelar este diálogo","relationAll":"todas as regras","conditionLarger":"é maior que","valueBoxLabel":"Valor","statusTipMsg":"Clique na barra de filtragem aqui para filtrar os valores de ${0}.","waiRelAll":"Corresponder a todas as seguintes regras:","closeFilterBarBtn":"Fechar a barra de filtragem","a11yFilterBarDefButton":"Filtrar...","trueLabel":"Verdadeiro","conditionIsNot":"não é","conditionIs":"é","ruleTitleTemplate":"Regra ${0}","waiRemoveRuleButtonTemplate":"Remover regra ${0}","and":"e","conditionLess":"é menor que","waiColumnSelectTemplate":"Coluna para a regra ${0}","anycolumn":"qualquer coluna","filterDefDialogTitle":"Filtrar","waiConditionSelectTemplate":"Condição para a regra ${0}","waiFilterButton":"Enviar o filtro","statusTipTitle":"Barra de Filtragem","statusTipRelPre":"Corresponder","anyColumnOption":"Qualquer Coluna","conditionSelectLabel":"Condição","cancelButton":"Cancelar","conditionNotStartWith":"não inicia com","conditionEndWith":"termina com","statusTipTitleNoFilter":"Barra de Filtragem","columnSelectLabel":"Coluna","conditionNotContain":"não contém","clearButton":"Limpar","conditionLargerEqual":"maior ou igual a","any":"qualquer um","relationMsgFront":"Corresponder","statusTipHeaderColumn":"Coluna","defaultItemsName":"itens","conditionEqual":"igual","relationAny":"qualquer regra","trueLabelEditable":"Verificado","or":"ou","filterBarMsgHasFilterTemplate":"${0} de ${1} ${2} mostrados.","rangeTo":"a","conditionStartsWith":"inicia com","waiRelAny":"Corresponder a qualquer uma das seguintes regras:","statusTipRelPost":"regras.","relationMsgTail":"","filterBarClearButton":"Limpar filtro","incompleteRuleTip":"Esta regra não está completa.","conditionLessEqual":"menor ou igual a","waiFilterBarClearButton":"Limpar o filtro","conditionAfter":"depois","statusTipHeaderCondition":"Regras","falseLabel":"Falso","filterButton":"Filtrar","clearFilterDialogTitle":"Limpar Filtro","statusTipTitleHasFilter":"Filtrar","addRuleButton":"Incluir Regra","waiAddRuleButton":"Incluir uma nova regra","waiClearButton":"Limpar o filtro","conditionNotEqual":"não é igual","conditionNotEndWith":"não termina com","rangeTemplate":"de ${0} a ${1}","removeRuleButton":"Remover Regra","waiFilterBarDefButton":"Filtrar a tabela","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pt/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pt/Filter.xd.js
new file mode 100644
index 0000000..c770508
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pt/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.pt.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.pt.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "pt", ({"conditionBefore":"antes","filterBarDefButton":"Definir filtro","filterBarMsgNoFilterTemplate":"Nenhum filtro aplicado","conditionContains":"contém","clearFilterMsg":"Isso removerá o filtro e mostrará todos os registros disponíveis.","all":"todos","waiValueBoxTemplate":"Insira o valor para filtragem da regra ${0}","conditionRange":"intervalo","waiCancelButton":"Cancelar este diálogo","relationAll":"todas as regras","conditionLarger":"é maior que","valueBoxLabel":"Valor","statusTipMsg":"Clique na barra de filtragem aqui para filtrar os valores de ${0}.","waiRelAll":"Corresponder a todas as seguintes regras:","closeFilterBarBtn":"Fechar a barra de filtragem","a11yFilterBarDefButton":"Filtrar...","trueLabel":"Verdadeiro","conditionIsNot":"não é","conditionIs":"é","ruleTitleTemplate":"Regra ${0}","waiRemoveRuleButtonTemplate":"Remover regra ${0}","and":"e","conditionLess":"é menor que","waiColumnSelectTemplate":"Coluna para a regra ${0}","anycolumn":"qualquer coluna","filterDefDialogTitle":"Filtrar","waiConditionSelectTemplate":"Condição para a regra ${0}","waiFilterButton":"Enviar o filtro","statusTipTitle":"Barra de Filtragem","statusTipRelPre":"Corresponder","anyColumnOption":"Qualquer Coluna","conditionSelectLabel":"Condição","cancelButton":"Cancelar","conditionNotStartWith":"não inicia com","conditionEndWith":"termina com","statusTipTitleNoFilter":"Barra de Filtragem","columnSelectLabel":"Coluna","conditionNotContain":"não contém","clearButton":"Limpar","conditionLargerEqual":"maior ou igual a","any":"qualquer um","relationMsgFront":"Corresponder","statusTipHeaderColumn":"Coluna","defaultItemsName":"itens","conditionEqual":"igual","relationAny":"qualquer regra","trueLabelEditable":"Verificado","or":"ou","filterBarMsgHasFilterTemplate":"${0} de ${1} ${2} mostrados.","rangeTo":"a","conditionStartsWith":"inicia com","waiRelAny":"Corresponder a qualquer uma das seguintes regras:","statusTipRelPost":"regras.","relationMsgTail":"","filterBarClearButton":"Limpar filtro","incompleteRuleTip":"Esta regra não está completa.","conditionLessEqual":"menor ou igual a","waiFilterBarClearButton":"Limpar o filtro","conditionAfter":"depois","statusTipHeaderCondition":"Regras","falseLabel":"Falso","filterButton":"Filtrar","clearFilterDialogTitle":"Limpar Filtro","statusTipTitleHasFilter":"Filtrar","addRuleButton":"Incluir Regra","waiAddRuleButton":"Incluir uma nova regra","waiClearButton":"Limpar o filtro","conditionNotEqual":"não é igual","conditionNotEndWith":"não termina com","rangeTemplate":"de ${0} a ${1}","removeRuleButton":"Remover Regra","waiFilterBarDefButton":"Filtrar a tabela","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pt/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pt/Pagination.js
new file mode 100644
index 0000000..d4f2578
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pt/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Acesse uma página específica","prevTip":"Página anterior","pageCountIndication":" (${0} páginas)","pageStepLabelTemplate":"Página ${0}","descTemplate":"${2} - ${3} de ${1} ${0}","lastTip":"Última Página","nextTip":"Próxima página","pageSizeLabelTemplate":"${0} itens por página","dialogCancel":"Cancelar","itemTitle":"itens","dialogConfirm":"Ir","firstTip":"Primeira Página","allItemsLabelTemplate":"Todos os itens","dialogIndication":"Especifique o número da página","dialogTitle":"Acesse a Página"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/pt/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/pt/Pagination.xd.js
new file mode 100644
index 0000000..242b92a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/pt/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.pt.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.pt.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "pt", ({"gotoButtonTitle":"Acesse uma página específica","prevTip":"Página anterior","pageCountIndication":" (${0} páginas)","pageStepLabelTemplate":"Página ${0}","descTemplate":"${2} - ${3} de ${1} ${0}","lastTip":"Última Página","nextTip":"Próxima página","pageSizeLabelTemplate":"${0} itens por página","dialogCancel":"Cancelar","itemTitle":"itens","dialogConfirm":"Ir","firstTip":"Primeira Página","allItemsLabelTemplate":"Todos os itens","dialogIndication":"Especifique o número da página","dialogTitle":"Acesse a Página"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ro/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ro/EnhancedGrid.js
new file mode 100644
index 0000000..8537735
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ro/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Descrescător","ascending":"Crescător","nestedSort":"Sortare imbricată","unsorted":"Nu sortaţi această coloană","singleSort":"Sortare singură","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ro/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ro/EnhancedGrid.xd.js
new file mode 100644
index 0000000..056264f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ro/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.ro.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.ro.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "ro", ({"descending":"Descrescător","ascending":"Crescător","nestedSort":"Sortare imbricată","unsorted":"Nu sortaţi această coloană","singleSort":"Sortare singură","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ru/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ru/EnhancedGrid.js
new file mode 100644
index 0000000..8cd9c74
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ru/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"По убыванию","ascending":"По возрастанию","nestedSort":"Вложенная сортировка","unsorted":"Не сортировать этот столбец","singleSort":"Однократная сортировка","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ru/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ru/EnhancedGrid.xd.js
new file mode 100644
index 0000000..529d4a6
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ru/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.ru.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.ru.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "ru", ({"descending":"По убыванию","ascending":"По возрастанию","nestedSort":"Вложенная сортировка","unsorted":"Не сортировать этот столбец","singleSort":"Однократная сортировка","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ru/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ru/Filter.js
new file mode 100644
index 0000000..e257c24
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ru/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"до","filterBarDefButton":"Определить фильтр","filterBarMsgNoFilterTemplate":"Фильтры не используются","conditionContains":"содержит","clearFilterMsg":"Эта опция удалит фильтр и будут показаны все доступные записи.","all":"все","waiValueBoxTemplate":"Введите значение в фильтр правила ${0}","conditionRange":"диапазон","waiCancelButton":"Отменить этот диалог","relationAll":"все правила","conditionLarger":"больше чем","valueBoxLabel":"Значение","statusTipMsg":"Нажмите на панель фильтров для фильтрации по значениям в ${0}.","waiRelAll":"Соответствует всем следующим правилам:","closeFilterBarBtn":"Закрыть панель фильтров","a11yFilterBarDefButton":"Фильтровать...","trueLabel":"Истина","conditionIsNot":"не соответствует","conditionIs":"-","ruleTitleTemplate":"Правило ${0}","waiRemoveRuleButtonTemplate":"Удалить правило ${0}","and":"и","conditionLess":"меньше чем","waiColumnSelectTemplate":"Столбец правила ${0}","anycolumn":"любой столбец","filterDefDialogTitle":"Фильтр","waiConditionSelectTemplate":"Условие правила ${0}","waiFilterButton":"Применить фильтр","statusTipTitle":"Панель фильтров","statusTipRelPre":"Соответствует","anyColumnOption":"Любой столбец","conditionSelectLabel":"Условие","cancelButton":"Отменить","conditionNotStartWith":"не начинается с","conditionEndWith":"заканчивается","statusTipTitleNoFilter":"Панель фильтров","columnSelectLabel":"Столбец","conditionNotContain":"не содержит","clearButton":"Очистить","conditionLargerEqual":"не больше чем","any":"любое","relationMsgFront":"Соответствует","statusTipHeaderColumn":"Столбец","defaultItemsName":"элементов","conditionEqual":"равно","relationAny":"любые правила","trueLabelEditable":"Отмечено","or":"или","filterBarMsgHasFilterTemplate":"Показано ${0} из ${1} ${2}.","rangeTo":"к","conditionStartsWith":"начинается с","waiRelAny":"Соответствует любому из следующих правил:","statusTipRelPost":"правила.","relationMsgTail":"","filterBarClearButton":"Очистить фильтр","incompleteRuleTip":"Это правило не выполнено.","conditionLessEqual":"не меньше чем","waiFilterBarClearButton":"Очистить фильтр","conditionAfter":"после","statusTipHeaderCondition":"Правила","falseLabel":"Ложь","filterButton":"Фильтр","clearFilterDialogTitle":"Очистить фильтр","statusTipTitleHasFilter":"Фильтр","addRuleButton":"Добавить правило","waiAddRuleButton":"Добавить новое правило","waiClearButton":"Очистить фильтр","conditionNotEqual":"не равно","conditionNotEndWith":"не заканчивается","rangeTemplate":"от ${0} до ${1}","removeRuleButton":"Удалить правило","waiFilterBarDefButton":"Фильтровать таблицу","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ru/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ru/Filter.xd.js
new file mode 100644
index 0000000..5481984
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ru/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.ru.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.ru.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "ru", ({"conditionBefore":"до","filterBarDefButton":"Определить фильтр","filterBarMsgNoFilterTemplate":"Фильтры не используются","conditionContains":"содержит","clearFilterMsg":"Эта опция удалит фильтр и будут показаны все доступные записи.","all":"все","waiValueBoxTemplate":"Введите значение в фильтр правила ${0}","conditionRange":"диапазон","waiCancelButton":"Отменить этот диалог","relationAll":"все правила","conditionLarger":"больше чем","valueBoxLabel":"Значение","statusTipMsg":"Нажмите на панель фильтров для фильтрации по значениям в ${0}.","waiRelAll":"Соответствует всем следующим правилам:","closeFilterBarBtn":"Закрыть панель фильтров","a11yFilterBarDefButton":"Фильтровать...","trueLabel":"Истина","conditionIsNot":"не соответствует","conditionIs":"-","ruleTitleTemplate":"Правило ${0}","waiRemoveRuleButtonTemplate":"Удалить правило ${0}","and":"и","conditionLess":"меньше чем","waiColumnSelectTemplate":"Столбец правила ${0}","anycolumn":"любой столбец","filterDefDialogTitle":"Фильтр","waiConditionSelectTemplate":"Условие правила ${0}","waiFilterButton":"Применить фильтр","statusTipTitle":"Панель фильтров","statusTipRelPre":"Соответствует","anyColumnOption":"Любой столбец","conditionSelectLabel":"Условие","cancelButton":"Отменить","conditionNotStartWith":"не начинается с","conditionEndWith":"заканчивается","statusTipTitleNoFilter":"Панель фильтров","columnSelectLabel":"Столбец","conditionNotContain":"не содержит","clearButton":"Очистить","conditionLargerEqual":"не больше чем","any":"любое","relationMsgFront":"Соответствует","statusTipHeaderColumn":"Столбец","defaultItemsName":"элементов","conditionEqual":"равно","relationAny":"любые правила","trueLabelEditable":"Отмечено","or":"или","filterBarMsgHasFilterTemplate":"Показано ${0} из ${1} ${2}.","rangeTo":"к","conditionStartsWith":"начинается с","waiRelAny":"Соответствует любому из следующих правил:","statusTipRelPost":"правила.","relationMsgTail":"","filterBarClearButton":"Очистить фильтр","incompleteRuleTip":"Это правило не выполнено.","conditionLessEqual":"не меньше чем","waiFilterBarClearButton":"Очистить фильтр","conditionAfter":"после","statusTipHeaderCondition":"Правила","falseLabel":"Ложь","filterButton":"Фильтр","clearFilterDialogTitle":"Очистить фильтр","statusTipTitleHasFilter":"Фильтр","addRuleButton":"Добавить правило","waiAddRuleButton":"Добавить новое правило","waiClearButton":"Очистить фильтр","conditionNotEqual":"не равно","conditionNotEndWith":"не заканчивается","rangeTemplate":"от ${0} до ${1}","removeRuleButton":"Удалить правило","waiFilterBarDefButton":"Фильтровать таблицу","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ru/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ru/Pagination.js
new file mode 100644
index 0000000..ceead99
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ru/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Перейти на указанную страницу","prevTip":"Предыдущая страница","pageCountIndication":" (${0} страниц)","pageStepLabelTemplate":"Страница ${0}","descTemplate":"${2} - ${3} из ${1} ${0}","lastTip":"Последняя страница","nextTip":"Следующая страница","pageSizeLabelTemplate":"${0} элементов на странице","dialogCancel":"Отменить","itemTitle":"элементов","dialogConfirm":"Перейти","firstTip":"Первая страница","allItemsLabelTemplate":"Все элементы","dialogIndication":"Укажите номер страницы","dialogTitle":"Перейти на страницу"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/ru/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/ru/Pagination.xd.js
new file mode 100644
index 0000000..cbf3492
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/ru/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.ru.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.ru.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "ru", ({"gotoButtonTitle":"Перейти на указанную страницу","prevTip":"Предыдущая страница","pageCountIndication":" (${0} страниц)","pageStepLabelTemplate":"Страница ${0}","descTemplate":"${2} - ${3} из ${1} ${0}","lastTip":"Последняя страница","nextTip":"Следующая страница","pageSizeLabelTemplate":"${0} элементов на странице","dialogCancel":"Отменить","itemTitle":"элементов","dialogConfirm":"Перейти","firstTip":"Первая страница","allItemsLabelTemplate":"Все элементы","dialogIndication":"Укажите номер страницы","dialogTitle":"Перейти на страницу"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/sk/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/sk/EnhancedGrid.js
new file mode 100644
index 0000000..7966159
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/sk/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Zostupne ","ascending":"Vzostupne ","nestedSort":"Vnorené triedenie ","unsorted":"Netriediť tento stĺpec ","singleSort":"Jednoduché triedenie ","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/sk/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/sk/EnhancedGrid.xd.js
new file mode 100644
index 0000000..c21f4cc
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/sk/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.sk.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.sk.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "sk", ({"descending":"Zostupne ","ascending":"Vzostupne ","nestedSort":"Vnorené triedenie ","unsorted":"Netriediť tento stĺpec ","singleSort":"Jednoduché triedenie ","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/sl/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/sl/EnhancedGrid.js
new file mode 100644
index 0000000..1a75e0c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/sl/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Padajoče","ascending":"Naraščajoče","nestedSort":"Ugnezdena razvrstitev","unsorted":"Ne razvrsti tega stolpca","singleSort":"Posamezna razvrstitev","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/sl/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/sl/EnhancedGrid.xd.js
new file mode 100644
index 0000000..f24fa95
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/sl/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.sl.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.sl.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "sl", ({"descending":"Padajoče","ascending":"Naraščajoče","nestedSort":"Ugnezdena razvrstitev","unsorted":"Ne razvrsti tega stolpca","singleSort":"Posamezna razvrstitev","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/sl/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/sl/Filter.js
new file mode 100644
index 0000000..87d16f3
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/sl/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"pred ","filterBarDefButton":"Definiraj filter ","filterBarMsgNoFilterTemplate":"Ni uveljavljenih filtrov ","conditionContains":"vsebuje ","clearFilterMsg":"S tem boste odstranili filter in prikazali vse razpoložljive zapise. ","all":"vse","waiValueBoxTemplate":"Vnesite vrednost za filtriranje za pravilo ${0}","conditionRange":"obseg","waiCancelButton":"Prekliči to pogovorno okno ","relationAll":"vsa pravila ","conditionLarger":"je večje kot ","valueBoxLabel":"Vrednost ","statusTipMsg":"Kliknite to vrstico filtra, da filtrirate vrednosti v ${0}.","waiRelAll":"Ujemanje z vsemi naslednjimi pravilo:","closeFilterBarBtn":"Zapri vrstico filtra ","a11yFilterBarDefButton":"Filter...","trueLabel":"True","conditionIsNot":"ni ","conditionIs":"je","ruleTitleTemplate":"Pravilo ${0}","waiRemoveRuleButtonTemplate":"Odstrani pravilo ${0}","and":"in ","conditionLess":"je manjše kot ","waiColumnSelectTemplate":"Stolpec za pravilo ${0}","anycolumn":"katerikoli stolpec ","filterDefDialogTitle":"Filter","waiConditionSelectTemplate":"Pogoj za pravilo ${0}","waiFilterButton":"Predloži filter ","statusTipTitle":"Vrstica filtra ","statusTipRelPre":"Ujemanje ","anyColumnOption":"Katerikoli stolpec ","conditionSelectLabel":"Pogoj ","cancelButton":"Prekliči","conditionNotStartWith":"se ne začne z ","conditionEndWith":"konča se z ","statusTipTitleNoFilter":"Vrstica filtra ","columnSelectLabel":"Stolpec ","conditionNotContain":"ne vsebuje","clearButton":"Počisti ","conditionLargerEqual":"večje ali enako ","any":"karkoli","relationMsgFront":"Ujemanje ","statusTipHeaderColumn":"Stolpec ","defaultItemsName":"postavke ","conditionEqual":"je enako kot ","relationAny":"katerakoli pravila ","trueLabelEditable":"Označeno ","or":"ali ","filterBarMsgHasFilterTemplate":"${0} od ${1} prikazanih ${2} ","rangeTo":"do","conditionStartsWith":"začne se z ","waiRelAny":"Ujemanje s katerimkoli od naslednjih pravil: ","statusTipRelPost":"pravila. ","relationMsgTail":"","filterBarClearButton":"Počisti filter","incompleteRuleTip":"To pravilo ni dokončano.","conditionLessEqual":"manjše ali enako kot ","waiFilterBarClearButton":"Počisti filter ","conditionAfter":"za ","statusTipHeaderCondition":"Pravila ","falseLabel":"False","filterButton":"Filter","clearFilterDialogTitle":"Počisti filter ","statusTipTitleHasFilter":"Filter","addRuleButton":"Dodaj pravilo ","waiAddRuleButton":"Dodaj novo pravilo ","waiClearButton":"Počisti filter ","conditionNotEqual":"ni enako ","conditionNotEndWith":"se ne konča z ","rangeTemplate":"od ${0} do ${1}","removeRuleButton":"Odstrani pravilo ","waiFilterBarDefButton":"Filtriraj tabelo ","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/sl/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/sl/Filter.xd.js
new file mode 100644
index 0000000..fbfa2a9
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/sl/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.sl.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.sl.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "sl", ({"conditionBefore":"pred ","filterBarDefButton":"Definiraj filter ","filterBarMsgNoFilterTemplate":"Ni uveljavljenih filtrov ","conditionContains":"vsebuje ","clearFilterMsg":"S tem boste odstranili filter in prikazali vse razpoložljive zapise. ","all":"vse","waiValueBoxTemplate":"Vnesite vrednost za filtriranje za pravilo ${0}","conditionRange":"obseg","waiCancelButton":"Prekliči to pogovorno okno ","relationAll":"vsa pravila ","conditionLarger":"je večje kot ","valueBoxLabel":"Vrednost ","statusTipMsg":"Kliknite to vrstico filtra, da filtrirate vrednosti v ${0}.","waiRelAll":"Ujemanje z vsemi naslednjimi pravilo:","closeFilterBarBtn":"Zapri vrstico filtra ","a11yFilterBarDefButton":"Filter...","trueLabel":"True","conditionIsNot":"ni ","conditionIs":"je","ruleTitleTemplate":"Pravilo ${0}","waiRemoveRuleButtonTemplate":"Odstrani pravilo ${0}","and":"in ","conditionLess":"je manjše kot ","waiColumnSelectTemplate":"Stolpec za pravilo ${0}","anycolumn":"katerikoli stolpec ","filterDefDialogTitle":"Filter","waiConditionSelectTemplate":"Pogoj za pravilo ${0}","waiFilterButton":"Predloži filter ","statusTipTitle":"Vrstica filtra ","statusTipRelPre":"Ujemanje ","anyColumnOption":"Katerikoli stolpec ","conditionSelectLabel":"Pogoj ","cancelButton":"Prekliči","conditionNotStartWith":"se ne začne z ","conditionEndWith":"konča se z ","statusTipTitleNoFilter":"Vrstica filtra ","columnSelectLabel":"Stolpec ","conditionNotContain":"ne vsebuje","clearButton":"Počisti ","conditionLargerEqual":"večje ali enako ","any":"karkoli","relationMsgFront":"Ujemanje ","statusTipHeaderColumn":"Stolpec ","defaultItemsName":"postavke ","conditionEqual":"je enako kot ","relationAny":"katerakoli pravila ","trueLabelEditable":"Označeno ","or":"ali ","filterBarMsgHasFilterTemplate":"${0} od ${1} prikazanih ${2} ","rangeTo":"do","conditionStartsWith":"začne se z ","waiRelAny":"Ujemanje s katerimkoli od naslednjih pravil: ","statusTipRelPost":"pravila. ","relationMsgTail":"","filterBarClearButton":"Počisti filter","incompleteRuleTip":"To pravilo ni dokončano.","conditionLessEqual":"manjše ali enako kot ","waiFilterBarClearButton":"Počisti filter ","conditionAfter":"za ","statusTipHeaderCondition":"Pravila ","falseLabel":"False","filterButton":"Filter","clearFilterDialogTitle":"Počisti filter ","statusTipTitleHasFilter":"Filter","addRuleButton":"Dodaj pravilo ","waiAddRuleButton":"Dodaj novo pravilo ","waiClearButton":"Počisti filter ","conditionNotEqual":"ni enako ","conditionNotEndWith":"se ne konča z ","rangeTemplate":"od ${0} do ${1}","removeRuleButton":"Odstrani pravilo ","waiFilterBarDefButton":"Filtriraj tabelo ","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/sl/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/sl/Pagination.js
new file mode 100644
index 0000000..eafe8bd
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/sl/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Pojdi na specifično stran","prevTip":"Prejšnja stran","pageCountIndication":" (${0} strani) ","pageStepLabelTemplate":"Stran ${0}","descTemplate":"${2} - ${3} od ${1} ${0}","lastTip":"Zadnja stran","nextTip":"Naslednja stran","pageSizeLabelTemplate":"${0} postavk na stran ","dialogCancel":"Prekliči","itemTitle":"postavk","dialogConfirm":"Pojdi","firstTip":"Prva stran","allItemsLabelTemplate":"Vse postavke ","dialogIndication":"Podajte številko strani ","dialogTitle":"Pojdi na stran "}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/sl/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/sl/Pagination.xd.js
new file mode 100644
index 0000000..632187e
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/sl/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.sl.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.sl.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "sl", ({"gotoButtonTitle":"Pojdi na specifično stran","prevTip":"Prejšnja stran","pageCountIndication":" (${0} strani) ","pageStepLabelTemplate":"Stran ${0}","descTemplate":"${2} - ${3} od ${1} ${0}","lastTip":"Zadnja stran","nextTip":"Naslednja stran","pageSizeLabelTemplate":"${0} postavk na stran ","dialogCancel":"Prekliči","itemTitle":"postavk","dialogConfirm":"Pojdi","firstTip":"Prva stran","allItemsLabelTemplate":"Vse postavke ","dialogIndication":"Podajte številko strani ","dialogTitle":"Pojdi na stran "})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/sv/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/sv/EnhancedGrid.js
new file mode 100644
index 0000000..4ff9f25
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/sv/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"fallande","ascending":"stigande","nestedSort":"nästlad sortering","unsorted":"Sortera inte den här kolumnen","singleSort":"enkel sortering","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/sv/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/sv/EnhancedGrid.xd.js
new file mode 100644
index 0000000..f83918f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/sv/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.sv.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.sv.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "sv", ({"descending":"fallande","ascending":"stigande","nestedSort":"nästlad sortering","unsorted":"Sortera inte den här kolumnen","singleSort":"enkel sortering","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/sv/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/sv/Filter.js
new file mode 100644
index 0000000..ea7b30b
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/sv/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"före","filterBarDefButton":"Definiera filter","filterBarMsgNoFilterTemplate":"Inga filter har använts","conditionContains":"innehåller","clearFilterMsg":"Filtret kommer att tas bort och alla tillgängliga poster kommer att visas.","all":"alla","waiValueBoxTemplate":"Ange värdet för regeln ${0}","conditionRange":"intervall","waiCancelButton":"Stäng den här dialogrutan","relationAll":"alla regler","conditionLarger":"är större än","valueBoxLabel":"Värde","statusTipMsg":"Om du vill filtret efter värden i ${0} klickar du på filterfältet.","waiRelAll":"Matcha följande regler:","closeFilterBarBtn":"Stäng filterfältet","a11yFilterBarDefButton":"Filter...","trueLabel":"Sant","conditionIsNot":"är inte","conditionIs":"är","ruleTitleTemplate":"Regeln ${0}","waiRemoveRuleButtonTemplate":"Ta bort regeln ${0}","and":"och","conditionLess":"är mindre än","waiColumnSelectTemplate":"Kolumn för regeln ${0}","anycolumn":"någon kolumn","filterDefDialogTitle":"Filter","waiConditionSelectTemplate":"Villkor för regeln ${0}","waiFilterButton":"Lämna in filtret","statusTipTitle":"Filterfält","statusTipRelPre":"Matchar","anyColumnOption":"Någon kolumn","conditionSelectLabel":"Villkor","cancelButton":"Avbryt","conditionNotStartWith":"börjar inte med","conditionEndWith":"slutar med","statusTipTitleNoFilter":"Filterfält","columnSelectLabel":"Kolumn","conditionNotContain":"innehåller inte","clearButton":"Rensa","conditionLargerEqual":"är större än eller lika med","any":"någon","relationMsgFront":"Matcha","statusTipHeaderColumn":"Kolumn","defaultItemsName":"objekt","conditionEqual":"är lika med","relationAny":"någon regel","trueLabelEditable":"Markerat","or":"eller","filterBarMsgHasFilterTemplate":"${0} av ${1} ${2} visas","rangeTo":"till","conditionStartsWith":"börjar med","waiRelAny":"Matcha någon av följande regler:","statusTipRelPost":"regler.","relationMsgTail":"","filterBarClearButton":"Rensa filtret","incompleteRuleTip":"Den här regeln är inte fullständig","conditionLessEqual":"är mindre än eller lika med","waiFilterBarClearButton":"Rensa filtret","conditionAfter":"efter","statusTipHeaderCondition":"Regler","falseLabel":"Falskt","filterButton":"Filter","clearFilterDialogTitle":"Rensa filtret","statusTipTitleHasFilter":"Filter","addRuleButton":"Lägg till regel","waiAddRuleButton":"Lägg till en ny regel","waiClearButton":"Rensa filtret","conditionNotEqual":"är inte lika med","conditionNotEndWith":"slutar inte med","rangeTemplate":"från ${0} till ${1}","removeRuleButton":"Ta bort regel","waiFilterBarDefButton":"Filtrera tabellen","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/sv/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/sv/Filter.xd.js
new file mode 100644
index 0000000..fa4b1ec
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/sv/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.sv.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.sv.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "sv", ({"conditionBefore":"före","filterBarDefButton":"Definiera filter","filterBarMsgNoFilterTemplate":"Inga filter har använts","conditionContains":"innehåller","clearFilterMsg":"Filtret kommer att tas bort och alla tillgängliga poster kommer att visas.","all":"alla","waiValueBoxTemplate":"Ange värdet för regeln ${0}","conditionRange":"intervall","waiCancelButton":"Stäng den här dialogrutan","relationAll":"alla regler","conditionLarger":"är större än","valueBoxLabel":"Värde","statusTipMsg":"Om du vill filtret efter värden i ${0} klickar du på filterfältet.","waiRelAll":"Matcha följande regler:","closeFilterBarBtn":"Stäng filterfältet","a11yFilterBarDefButton":"Filter...","trueLabel":"Sant","conditionIsNot":"är inte","conditionIs":"är","ruleTitleTemplate":"Regeln ${0}","waiRemoveRuleButtonTemplate":"Ta bort regeln ${0}","and":"och","conditionLess":"är mindre än","waiColumnSelectTemplate":"Kolumn för regeln ${0}","anycolumn":"någon kolumn","filterDefDialogTitle":"Filter","waiConditionSelectTemplate":"Villkor för regeln ${0}","waiFilterButton":"Lämna in filtret","statusTipTitle":"Filterfält","statusTipRelPre":"Matchar","anyColumnOption":"Någon kolumn","conditionSelectLabel":"Villkor","cancelButton":"Avbryt","conditionNotStartWith":"börjar inte med","conditionEndWith":"slutar med","statusTipTitleNoFilter":"Filterfält","columnSelectLabel":"Kolumn","conditionNotContain":"innehåller inte","clearButton":"Rensa","conditionLargerEqual":"är större än eller lika med","any":"någon","relationMsgFront":"Matcha","statusTipHeaderColumn":"Kolumn","defaultItemsName":"objekt","conditionEqual":"är lika med","relationAny":"någon regel","trueLabelEditable":"Markerat","or":"eller","filterBarMsgHasFilterTemplate":"${0} av ${1} ${2} visas","rangeTo":"till","conditionStartsWith":"börjar med","waiRelAny":"Matcha någon av följande regler:","statusTipRelPost":"regler.","relationMsgTail":"","filterBarClearButton":"Rensa filtret","incompleteRuleTip":"Den här regeln är inte fullständig","conditionLessEqual":"är mindre än eller lika med","waiFilterBarClearButton":"Rensa filtret","conditionAfter":"efter","statusTipHeaderCondition":"Regler","falseLabel":"Falskt","filterButton":"Filter","clearFilterDialogTitle":"Rensa filtret","statusTipTitleHasFilter":"Filter","addRuleButton":"Lägg till regel","waiAddRuleButton":"Lägg till en ny regel","waiClearButton":"Rensa filtret","conditionNotEqual":"är inte lika med","conditionNotEndWith":"slutar inte med","rangeTemplate":"från ${0} till ${1}","removeRuleButton":"Ta bort regel","waiFilterBarDefButton":"Filtrera tabellen","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/sv/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/sv/Pagination.js
new file mode 100644
index 0000000..959285c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/sv/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Gå till en viss sida","prevTip":"Föregående sida","pageCountIndication":" (${0} sidor)","pageStepLabelTemplate":"Sidan ${0}","descTemplate":"${2} - ${3} av ${1} ${0}","lastTip":"Sista sidan","nextTip":"Nästa sida","pageSizeLabelTemplate":"${0} objekt per sida","dialogCancel":"Avbryt","itemTitle":"objekt","dialogConfirm":"OK","firstTip":"Första sidan","allItemsLabelTemplate":"Alla objekt","dialogIndication":"Ange sidnumret","dialogTitle":"Gå till sida"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/sv/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/sv/Pagination.xd.js
new file mode 100644
index 0000000..2148fb7
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/sv/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.sv.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.sv.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "sv", ({"gotoButtonTitle":"Gå till en viss sida","prevTip":"Föregående sida","pageCountIndication":" (${0} sidor)","pageStepLabelTemplate":"Sidan ${0}","descTemplate":"${2} - ${3} av ${1} ${0}","lastTip":"Sista sidan","nextTip":"Nästa sida","pageSizeLabelTemplate":"${0} objekt per sida","dialogCancel":"Avbryt","itemTitle":"objekt","dialogConfirm":"OK","firstTip":"Första sidan","allItemsLabelTemplate":"Alla objekt","dialogIndication":"Ange sidnumret","dialogTitle":"Gå till sida"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/th/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/th/EnhancedGrid.js
new file mode 100644
index 0000000..974bed6
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/th/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"จากมากไปหาน้อย","ascending":"จากน้อยไปหามาก","nestedSort":"เรียงลำดับที่ซับซ้อน","unsorted":"ห้ามเรียงลำดับคอลัมน์นี้","singleSort":"เรียงลำดับแบบเดี่ยว","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/th/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/th/EnhancedGrid.xd.js
new file mode 100644
index 0000000..36829ca
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/th/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.th.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.th.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "th", ({"descending":"จากมากไปหาน้อย","ascending":"จากน้อยไปหามาก","nestedSort":"เรียงลำดับที่ซับซ้อน","unsorted":"ห้ามเรียงลำดับคอลัมน์นี้","singleSort":"เรียงลำดับแบบเดี่ยว","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/th/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/th/Filter.js
new file mode 100644
index 0000000..2cb537a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/th/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"ก่อน","filterBarDefButton":"กำหนดตัวกรอง","filterBarMsgNoFilterTemplate":"ไม่นำตัวกรองไปใช้","conditionContains":"ประกอบด้วย","clearFilterMsg":"ซึ่งจะลบตัวกรองออกและแสดงเร็กคอร์ดที่พร้อมใช้งานทั้งหมด","all":"ทั้งหมด","waiValueBoxTemplate":"ป้อนค่าให้กับตัวกรองสำหรับกฏ ${0}","conditionRange":"ช่วง","waiCancelButton":"ยกเลิกไดอะล็อกนี้","relationAll":"กฏทั้งหมด","conditionLarger":"มากกว่า","valueBoxLabel":"ค่า","statusTipMsg":"คลิกที่แถบตัวกรองที่นี่เพื่อกรองค่าใน ${0}","waiRelAll":"ตรงกับกฏทั้งหมดต่อไปนี้:","closeFilterBarBtn":"ปิดแถบตัวกรอง","a11yFilterBarDefButton":"ตัวกรอง...","trueLabel":"จริง","conditionIsNot":"ไม่","conditionIs":"เป็น","ruleTitleTemplate":"กฏ ${0}","waiRemoveRuleButtonTemplate":"ลบกฏ ${0}","and":"และ","conditionLess":"น้อยกว่า","waiColumnSelectTemplate":"คอลัมน์สำหรับกฏ ${0}","anycolumn":"คอลัมน์ใดๆ","filterDefDialogTitle":"ตัวกรอง","waiConditionSelectTemplate":"เงื่อนไขสำหรับกฏ ${0}","waiFilterButton":"ส่งตัวกรอง","statusTipTitle":"แถบตัวกรอง","statusTipRelPre":"ตรงกับ","anyColumnOption":"คอลัมน์ใดๆ","conditionSelectLabel":"เงื่อนไข","cancelButton":"ยกเลิก","conditionNotStartWith":"ไม่เริ่มต้นด้วย","conditionEndWith":"ลงท้ายด้วย","statusTipTitleNoFilter":"แถบตัวกรอง","columnSelectLabel":"คอลัมน์","conditionNotContain":"ไม่ประกอบด้วย","clearButton":"ลบ","conditionLargerEqual":"มากกว่าหรือเท่ากับ","any":"ใด","relationMsgFront":"ตรงกับ","statusTipHeaderColumn":"คอลัมน์","defaultItemsName":"ไอเท็ม","conditionEqual":"เท่ากับ","relationAny":"กฏใดๆ","trueLabelEditable":"ได้รับการตรวจสอบ","or":"หรือ","filterBarMsgHasFilterTemplate":"${0} ของ ${1} ${2} จะถูกแสดง","rangeTo":"ถึง","conditionStartsWith":"เริ่มต้นด้วย","waiRelAny":"ตรงกับกฏใดๆต่อไปนี้:","statusTipRelPost":"กฏ","relationMsgTail":"","filterBarClearButton":"ลบตัวกรอง","incompleteRuleTip":"กฏนี้ยังไม่สมบูรณ์","conditionLessEqual":"น้อยกว่าหรือเท่ากับ","waiFilterBarClearButton":"ลบตัวกรอง","conditionAfter":"หลัง","statusTipHeaderCondition":"กฏ","falseLabel":"เท็จ","filterButton":"ตัวกรอง","clearFilterDialogTitle":"ลบตัวกรอง","statusTipTitleHasFilter":"ตัวกรอง","addRuleButton":"เพิ่มกฏ","waiAddRuleButton":"เพิ่มกฏใหม่","waiClearButton":"ลบตัวกรอง","conditionNotEqual":"ไม่เท่ากับ","conditionNotEndWith":"ไม่ลงท้ายด้วย","rangeTemplate":"จาก ${0} ถึง ${1}","removeRuleButton":"ลบกฏ","waiFilterBarDefButton":"กรองตาราง","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/th/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/th/Filter.xd.js
new file mode 100644
index 0000000..3a8dfa0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/th/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.th.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.th.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "th", ({"conditionBefore":"ก่อน","filterBarDefButton":"กำหนดตัวกรอง","filterBarMsgNoFilterTemplate":"ไม่นำตัวกรองไปใช้","conditionContains":"ประกอบด้วย","clearFilterMsg":"ซึ่งจะลบตัวกรองออกและแสดงเร็กคอร์ดที่พร้อมใช้งานทั้งหมด","all":"ทั้งหมด","waiValueBoxTemplate":"ป้อนค่าให้กับตัวกรองสำหรับกฏ ${0}","conditionRange":"ช่วง","waiCancelButton":"ยกเลิกไดอะล็อกนี้","relationAll":"กฏทั้งหมด","conditionLarger":"มากกว่า","valueBoxLabel":"ค่า","statusTipMsg":"คลิกที่แถบตัวกรองที่นี่เพื่อกรองค่าใน ${0}","waiRelAll":"ตรงกับกฏทั้งหมดต่อไปนี้:","closeFilterBarBtn":"ปิดแถบตัวกรอง","a11yFilterBarDefButton":"ตัวกรอง...","trueLabel":"จริง","conditionIsNot":"ไม่","conditionIs":"เป็น","ruleTitleTemplate":"กฏ ${0}","waiRemoveRuleButtonTemplate":"ลบกฏ ${0}","and":"และ","conditionLess":"น้อยกว่า","waiColumnSelectTemplate":"คอลัมน์สำหรับกฏ ${0}","anycolumn":"คอลัมน์ใดๆ","filterDefDialogTitle":"ตัวกรอง","waiConditionSelectTemplate":"เงื่อนไขสำหรับกฏ ${0}","waiFilterButton":"ส่งตัวกรอง","statusTipTitle":"แถบตัวกรอง","statusTipRelPre":"ตรงกับ","anyColumnOption":"คอลัมน์ใดๆ","conditionSelectLabel":"เงื่อนไข","cancelButton":"ยกเลิก","conditionNotStartWith":"ไม่เริ่มต้นด้วย","conditionEndWith":"ลงท้ายด้วย","statusTipTitleNoFilter":"แถบตัวกรอง","columnSelectLabel":"คอลัมน์","conditionNotContain":"ไม่ประกอบด้วย","clearButton":"ลบ","conditionLargerEqual":"มากกว่าหรือเท่ากับ","any":"ใด","relationMsgFront":"ตรงกับ","statusTipHeaderColumn":"คอลัมน์","defaultItemsName":"ไอเท็ม","conditionEqual":"เท่ากับ","relationAny":"กฏใดๆ","trueLabelEditable":"ได้รับการตรวจสอบ","or":"หรือ","filterBarMsgHasFilterTemplate":"${0} ของ ${1} ${2} จะถูกแสดง","rangeTo":"ถึง","conditionStartsWith":"เริ่มต้นด้วย","waiRelAny":"ตรงกับกฏใดๆต่อไปนี้:","statusTipRelPost":"กฏ","relationMsgTail":"","filterBarClearButton":"ลบตัวกรอง","incompleteRuleTip":"กฏนี้ยังไม่สมบูรณ์","conditionLessEqual":"น้อยกว่าหรือเท่ากับ","waiFilterBarClearButton":"ลบตัวกรอง","conditionAfter":"หลัง","statusTipHeaderCondition":"กฏ","falseLabel":"เท็จ","filterButton":"ตัวกรอง","clearFilterDialogTitle":"ลบตัวกรอง","statusTipTitleHasFilter":"ตัวกรอง","addRuleButton":"เพิ่มกฏ","waiAddRuleButton":"เพิ่มกฏใหม่","waiClearButton":"ลบตัวกรอง","conditionNotEqual":"ไม่เท่ากับ","conditionNotEndWith":"ไม่ลงท้ายด้วย","rangeTemplate":"จาก ${0} ถึง ${1}","removeRuleButton":"ลบกฏ","waiFilterBarDefButton":"กรองตาราง","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/th/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/th/Pagination.js
new file mode 100644
index 0000000..6b1d554
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/th/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"ไปที่หน้าที่ระบุ","prevTip":"หน้าก่อนหน้านี้","pageCountIndication":" (${0} หน้า)","pageStepLabelTemplate":"หน้า ${0}","descTemplate":"${2} - ${3} จาก ${1} ${0}","lastTip":"หน้าสุดท้าย","nextTip":"หน้าถัดไป","pageSizeLabelTemplate":"${0} ไอเท็มต่อหน้า","dialogCancel":"ยกเลิก","itemTitle":"ไอเท็ม","dialogConfirm":"ไปที่","firstTip":"หน้าแรก","allItemsLabelTemplate":"รายการ ทั้งหมด","dialogIndication":"ระบุหมายเลขหน้า","dialogTitle":"ไปที่หน้า"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/th/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/th/Pagination.xd.js
new file mode 100644
index 0000000..2d1a7cf
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/th/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.th.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.th.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "th", ({"gotoButtonTitle":"ไปที่หน้าที่ระบุ","prevTip":"หน้าก่อนหน้านี้","pageCountIndication":" (${0} หน้า)","pageStepLabelTemplate":"หน้า ${0}","descTemplate":"${2} - ${3} จาก ${1} ${0}","lastTip":"หน้าสุดท้าย","nextTip":"หน้าถัดไป","pageSizeLabelTemplate":"${0} ไอเท็มต่อหน้า","dialogCancel":"ยกเลิก","itemTitle":"ไอเท็ม","dialogConfirm":"ไปที่","firstTip":"หน้าแรก","allItemsLabelTemplate":"รายการ ทั้งหมด","dialogIndication":"ระบุหมายเลขหน้า","dialogTitle":"ไปที่หน้า"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/tr/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/tr/EnhancedGrid.js
new file mode 100644
index 0000000..8bf4c94
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/tr/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"Azalan","ascending":"Artan","nestedSort":"İç İçe Sıralama","unsorted":"Bu sütunu sıralama","singleSort":"Tek Sıralama","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/tr/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/tr/EnhancedGrid.xd.js
new file mode 100644
index 0000000..d4268f2
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/tr/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.tr.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.tr.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "tr", ({"descending":"Azalan","ascending":"Artan","nestedSort":"İç İçe Sıralama","unsorted":"Bu sütunu sıralama","singleSort":"Tek Sıralama","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/tr/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/tr/Filter.js
new file mode 100644
index 0000000..e5f881a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/tr/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"önce","filterBarDefButton":"Süzgeç tanımla","filterBarMsgNoFilterTemplate":"Süzgeç uygulanmadı","conditionContains":"içerir","clearFilterMsg":"Bu işlem sonucunda süzgeç kaldırılacak ve kullanılabilir tüm kayıtlar gösterilecek.","all":"tümü","waiValueBoxTemplate":"${0} kuralını süzmek için değer girin","conditionRange":"aralık","waiCancelButton":"Bu iletişim kutusunu iptal et","relationAll":"tüm kurallar","conditionLarger":"büyüktür","valueBoxLabel":"Değer","statusTipMsg":"${0} öğesindeki değerleri süzmek için burada süzgeç çubuğunu tıklatın.","waiRelAll":"Aşağıdaki kuralların tümüyle eşleştir:","closeFilterBarBtn":"Süzgeç çubuğunu kapat","a11yFilterBarDefButton":"Süz...","trueLabel":"Doğru","conditionIsNot":"değildir","conditionIs":"eşittir","ruleTitleTemplate":"Kural ${0}","waiRemoveRuleButtonTemplate":"${0} kuralını kaldır","and":"ve","conditionLess":"küçüktür","waiColumnSelectTemplate":"${0} kuralı için sütun","anycolumn":"herhangi bir sütun","filterDefDialogTitle":"Süzgeç","waiConditionSelectTemplate":"${0} kuralı için koşul","waiFilterButton":"Süzgeci gönder","statusTipTitle":"Süzgeç Çubuğu","statusTipRelPre":"Eşleştir","anyColumnOption":"Herhangi Bir Sütun","conditionSelectLabel":"Koşul","cancelButton":"İptal","conditionNotStartWith":"ile başlamaz","conditionEndWith":"ile biter","statusTipTitleNoFilter":"Süzgeç Çubuğu","columnSelectLabel":"Sütun","conditionNotContain":"içermez","clearButton":"Temizle","conditionLargerEqual":"büyüktür ya da eşittir","any":"herhangi biri","relationMsgFront":"Eşleştir","statusTipHeaderColumn":"Sütun","defaultItemsName":"öğeler","conditionEqual":"eşittir","relationAny":"kurallardan herhangi biri","trueLabelEditable":"Denetlendi","or":"veya","filterBarMsgHasFilterTemplate":"${0} /f ${1} ${2} gösteriliyor.","rangeTo":"-","conditionStartsWith":"ile başlar","waiRelAny":"Aşağıdaki kurallardan herhangi biriyle eşleştir:","statusTipRelPost":"kurallar.","relationMsgTail":"","filterBarClearButton":"Süzgeci kaldır","incompleteRuleTip":"Bu kural tamamlanmamış.","conditionLessEqual":"küçüktür ya da eşittir","waiFilterBarClearButton":"Süzgeci kaldır","conditionAfter":"sonra","statusTipHeaderCondition":"Kurallar","falseLabel":"Yanlış","filterButton":"Süzgeç","clearFilterDialogTitle":"Süzgeci Kaldır","statusTipTitleHasFilter":"Süzgeç","addRuleButton":"Kural Ekle","waiAddRuleButton":"Yeni kural ekle","waiClearButton":"Süzgeci kaldır","conditionNotEqual":"eşit değildir","conditionNotEndWith":"ile bitmez","rangeTemplate":"${0} - ${1}","removeRuleButton":"Kural Kaldır","waiFilterBarDefButton":"Tabloyu süz","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/tr/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/tr/Filter.xd.js
new file mode 100644
index 0000000..74a6894
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/tr/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.tr.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.tr.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "tr", ({"conditionBefore":"önce","filterBarDefButton":"Süzgeç tanımla","filterBarMsgNoFilterTemplate":"Süzgeç uygulanmadı","conditionContains":"içerir","clearFilterMsg":"Bu işlem sonucunda süzgeç kaldırılacak ve kullanılabilir tüm kayıtlar gösterilecek.","all":"tümü","waiValueBoxTemplate":"${0} kuralını süzmek için değer girin","conditionRange":"aralık","waiCancelButton":"Bu iletişim kutusunu iptal et","relationAll":"tüm kurallar","conditionLarger":"büyüktür","valueBoxLabel":"Değer","statusTipMsg":"${0} öğesindeki değerleri süzmek için burada süzgeç çubuğunu tıklatın.","waiRelAll":"Aşağıdaki kuralların tümüyle eşleştir:","closeFilterBarBtn":"Süzgeç çubuğunu kapat","a11yFilterBarDefButton":"Süz...","trueLabel":"Doğru","conditionIsNot":"değildir","conditionIs":"eşittir","ruleTitleTemplate":"Kural ${0}","waiRemoveRuleButtonTemplate":"${0} kuralını kaldır","and":"ve","conditionLess":"küçüktür","waiColumnSelectTemplate":"${0} kuralı için sütun","anycolumn":"herhangi bir sütun","filterDefDialogTitle":"Süzgeç","waiConditionSelectTemplate":"${0} kuralı için koşul","waiFilterButton":"Süzgeci gönder","statusTipTitle":"Süzgeç Çubuğu","statusTipRelPre":"Eşleştir","anyColumnOption":"Herhangi Bir Sütun","conditionSelectLabel":"Koşul","cancelButton":"İptal","conditionNotStartWith":"ile başlamaz","conditionEndWith":"ile biter","statusTipTitleNoFilter":"Süzgeç Çubuğu","columnSelectLabel":"Sütun","conditionNotContain":"içermez","clearButton":"Temizle","conditionLargerEqual":"büyüktür ya da eşittir","any":"herhangi biri","relationMsgFront":"Eşleştir","statusTipHeaderColumn":"Sütun","defaultItemsName":"öğeler","conditionEqual":"eşittir","relationAny":"kurallardan herhangi biri","trueLabelEditable":"Denetlendi","or":"veya","filterBarMsgHasFilterTemplate":"${0} /f ${1} ${2} gösteriliyor.","rangeTo":"-","conditionStartsWith":"ile başlar","waiRelAny":"Aşağıdaki kurallardan herhangi biriyle eşleştir:","statusTipRelPost":"kurallar.","relationMsgTail":"","filterBarClearButton":"Süzgeci kaldır","incompleteRuleTip":"Bu kural tamamlanmamış.","conditionLessEqual":"küçüktür ya da eşittir","waiFilterBarClearButton":"Süzgeci kaldır","conditionAfter":"sonra","statusTipHeaderCondition":"Kurallar","falseLabel":"Yanlış","filterButton":"Süzgeç","clearFilterDialogTitle":"Süzgeci Kaldır","statusTipTitleHasFilter":"Süzgeç","addRuleButton":"Kural Ekle","waiAddRuleButton":"Yeni kural ekle","waiClearButton":"Süzgeci kaldır","conditionNotEqual":"eşit değildir","conditionNotEndWith":"ile bitmez","rangeTemplate":"${0} - ${1}","removeRuleButton":"Kural Kaldır","waiFilterBarDefButton":"Tabloyu süz","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/tr/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/tr/Pagination.js
new file mode 100644
index 0000000..5f17f0d
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/tr/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"Belli bir sayfaya git","prevTip":"Önceki Sayfa","pageCountIndication":" (${0} sayfa)","pageStepLabelTemplate":"Sayfa ${0}","descTemplate":"${2} - ${3} / ${1} ${0}","lastTip":"Son Sayfa","nextTip":"Sonraki Sayfa","pageSizeLabelTemplate":"Sayfa başına ${0} öğe","dialogCancel":"İptal","itemTitle":"öğeler","dialogConfirm":"Git","firstTip":"İlk Sayfa","allItemsLabelTemplate":"Tüm öğeler","dialogIndication":"Sayfa numarasını belirt","dialogTitle":"Sayfaya Git"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/tr/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/tr/Pagination.xd.js
new file mode 100644
index 0000000..1303117
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/tr/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.tr.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.tr.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "tr", ({"gotoButtonTitle":"Belli bir sayfaya git","prevTip":"Önceki Sayfa","pageCountIndication":" (${0} sayfa)","pageStepLabelTemplate":"Sayfa ${0}","descTemplate":"${2} - ${3} / ${1} ${0}","lastTip":"Son Sayfa","nextTip":"Sonraki Sayfa","pageSizeLabelTemplate":"Sayfa başına ${0} öğe","dialogCancel":"İptal","itemTitle":"öğeler","dialogConfirm":"Git","firstTip":"İlk Sayfa","allItemsLabelTemplate":"Tüm öğeler","dialogIndication":"Sayfa numarasını belirt","dialogTitle":"Sayfaya Git"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js
new file mode 100644
index 0000000..3166f9c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"降冪","ascending":"遞增","nestedSort":"巢狀排序","unsorted":"本欄不進行排序","singleSort":"單一排序","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.xd.js
new file mode 100644
index 0000000..c7ca624
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.zh-tw.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.zh-tw.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "zh-tw", ({"descending":"降冪","ascending":"遞增","nestedSort":"巢狀排序","unsorted":"本欄不進行排序","singleSort":"單一排序","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/Filter.js
new file mode 100644
index 0000000..f50a1e9
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"之前","filterBarDefButton":"定義過濾器","filterBarMsgNoFilterTemplate":"未套用任何過濾器","conditionContains":"包含","clearFilterMsg":"這將會移除過濾器並顯示所有可用的記錄。","all":"全部","waiValueBoxTemplate":"輸入要過濾規則 ${0} 的值","conditionRange":"範圍","waiCancelButton":"取消此對話框","relationAll":"所有規則","conditionLarger":"為大於","valueBoxLabel":"值","statusTipMsg":"按一下過濾器列以過濾 ${0} 中的值。","waiRelAll":"符合下列的所有規則:","closeFilterBarBtn":"關閉過濾器列","a11yFilterBarDefButton":"過濾...","trueLabel":"True","conditionIsNot":"為不是","conditionIs":"為","ruleTitleTemplate":"規則 ${0}","waiRemoveRuleButtonTemplate":"移除規則 ${0}","and":"及","conditionLess":"為小於","waiColumnSelectTemplate":"規則 ${0} 的直欄","anycolumn":"任何直欄","filterDefDialogTitle":"過濾器","waiConditionSelectTemplate":"規則 ${0} 的條件","waiFilterButton":"提交過濾器","statusTipTitle":"過濾器列","statusTipRelPre":"符合","anyColumnOption":"任何直欄","conditionSelectLabel":"條件","cancelButton":"取消","conditionNotStartWith":"不起始於","conditionEndWith":"結束於","statusTipTitleNoFilter":"過濾器列","columnSelectLabel":"直欄","conditionNotContain":"不包含","clearButton":"清除","conditionLargerEqual":"大於或等於","any":"任何","relationMsgFront":"符合","statusTipHeaderColumn":"直欄","defaultItemsName":"項目","conditionEqual":"等於","relationAny":"任何規則","trueLabelEditable":"已勾選","or":"或","filterBarMsgHasFilterTemplate":"顯示 ${1} ${2} 之 ${0}。","rangeTo":"到","conditionStartsWith":"開始於","waiRelAny":"符合下列的任何規則:","statusTipRelPost":"規則。","relationMsgTail":"","filterBarClearButton":"清除過濾器","incompleteRuleTip":"此規則不完整。","conditionLessEqual":"小於或等於","waiFilterBarClearButton":"清除過濾器","conditionAfter":"之後","statusTipHeaderCondition":"規則","falseLabel":"False","filterButton":"過濾器","clearFilterDialogTitle":"清除過濾器","statusTipTitleHasFilter":"過濾器","addRuleButton":"新增規則","waiAddRuleButton":"新增規則","waiClearButton":"清除過濾器","conditionNotEqual":"不等於","conditionNotEndWith":"不結束於","rangeTemplate":"從 ${0} 到 ${1}","removeRuleButton":"移除規則","waiFilterBarDefButton":"過濾表格","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/Filter.xd.js
new file mode 100644
index 0000000..e461e36
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.zh-tw.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.zh-tw.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "zh-tw", ({"conditionBefore":"之前","filterBarDefButton":"定義過濾器","filterBarMsgNoFilterTemplate":"未套用任何過濾器","conditionContains":"包含","clearFilterMsg":"這將會移除過濾器並顯示所有可用的記錄。","all":"全部","waiValueBoxTemplate":"輸入要過濾規則 ${0} 的值","conditionRange":"範圍","waiCancelButton":"取消此對話框","relationAll":"所有規則","conditionLarger":"為大於","valueBoxLabel":"值","statusTipMsg":"按一下過濾器列以過濾 ${0} 中的值。","waiRelAll":"符合下列的所有規則:","closeFilterBarBtn":"關閉過濾器列","a11yFilterBarDefButton":"過濾...","trueLabel":"True","conditionIsNot":"為不是","conditionIs":"為","ruleTitleTemplate":"規則 ${0}","waiRemoveRuleButtonTemplate":"移除規則 ${0}","and":"及","conditionLess":"為小於","waiColumnSelectTemplate":"規則 ${0} 的直欄","anycolumn":"任何直欄","filterDefDialogTitle":"過濾器","waiConditionSelectTemplate":"規則 ${0} 的條件","waiFilterButton":"提交過濾器","statusTipTitle":"過濾器列","statusTipRelPre":"符合","anyColumnOption":"任何直欄","conditionSelectLabel":"條件","cancelButton":"取消","conditionNotStartWith":"不起始於","conditionEndWith":"結束於","statusTipTitleNoFilter":"過濾器列","columnSelectLabel":"直欄","conditionNotContain":"不包含","clearButton":"清除","conditionLargerEqual":"大於或等於","any":"任何","relationMsgFront":"符合","statusTipHeaderColumn":"直欄","defaultItemsName":"項目","conditionEqual":"等於","relationAny":"任何規則","trueLabelEditable":"已勾選","or":"或","filterBarMsgHasFilterTemplate":"顯示 ${1} ${2} 之 ${0}。","rangeTo":"到","conditionStartsWith":"開始於","waiRelAny":"符合下列的任何規則:","statusTipRelPost":"規則。","relationMsgTail":"","filterBarClearButton":"清除過濾器","incompleteRuleTip":"此規則不完整。","conditionLessEqual":"小於或等於","waiFilterBarClearButton":"清除過濾器","conditionAfter":"之後","statusTipHeaderCondition":"規則","falseLabel":"False","filterButton":"過濾器","clearFilterDialogTitle":"清除過濾器","statusTipTitleHasFilter":"過濾器","addRuleButton":"新增規則","waiAddRuleButton":"新增規則","waiClearButton":"清除過濾器","conditionNotEqual":"不等於","conditionNotEndWith":"不結束於","rangeTemplate":"從 ${0} 到 ${1}","removeRuleButton":"移除規則","waiFilterBarDefButton":"過濾表格","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/Pagination.js
new file mode 100644
index 0000000..f681cdf
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"跳至特定的頁面","prevTip":"上一頁","pageCountIndication":" (${0} 個頁面)","pageStepLabelTemplate":"頁面 ${0}","descTemplate":"${2} - ${1} ${0} 之 ${3}","lastTip":"末頁","nextTip":"下一頁","pageSizeLabelTemplate":"每頁 ${0} 個項目","dialogCancel":"取消","itemTitle":"項目","dialogConfirm":"執行","firstTip":"首頁","allItemsLabelTemplate":"所有項目","dialogIndication":"指定頁碼","dialogTitle":"跳至頁面"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/Pagination.xd.js
new file mode 100644
index 0000000..0180d46
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/zh-tw/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.zh-tw.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.zh-tw.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "zh-tw", ({"gotoButtonTitle":"跳至特定的頁面","prevTip":"上一頁","pageCountIndication":" (${0} 個頁面)","pageStepLabelTemplate":"頁面 ${0}","descTemplate":"${2} - ${1} ${0} 之 ${3}","lastTip":"末頁","nextTip":"下一頁","pageSizeLabelTemplate":"每頁 ${0} 個項目","dialogCancel":"取消","itemTitle":"項目","dialogConfirm":"執行","firstTip":"首頁","allItemsLabelTemplate":"所有項目","dialogIndication":"指定頁碼","dialogTitle":"跳至頁面"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/zh/EnhancedGrid.js b/js/dojo-1.6/dojox/grid/enhanced/nls/zh/EnhancedGrid.js
new file mode 100644
index 0000000..d6433e9
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/zh/EnhancedGrid.js
@@ -0,0 +1 @@
+({"descending":"降序","ascending":"升序","nestedSort":"嵌套排序","unsorted":"请勿对此列排序","singleSort":"单一排序","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/zh/EnhancedGrid.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/zh/EnhancedGrid.xd.js
new file mode 100644
index 0000000..0e7d607
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/zh/EnhancedGrid.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.zh.EnhancedGrid"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.zh.EnhancedGrid");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "EnhancedGrid", "zh", ({"descending":"降序","ascending":"升序","nestedSort":"嵌套排序","unsorted":"请勿对此列排序","singleSort":"单一排序","indirectSelectionRadio":"Row ${0}, single selection, radio box","indirectSelectionCheckBox":"Row ${0}, multiple selection, check box","selectAll":"Select all","sortingState":"${0} - ${1}"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/zh/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/nls/zh/Filter.js
new file mode 100644
index 0000000..67f2850
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/zh/Filter.js
@@ -0,0 +1 @@
+({"conditionBefore":"前","filterBarDefButton":"定义过滤器","filterBarMsgNoFilterTemplate":"未应用过滤器","conditionContains":"包含","clearFilterMsg":"将除去过滤器并显示所有可用记录。","all":"所有","waiValueBoxTemplate":"为 ${0} 规则向过滤器输入值","conditionRange":"范围","waiCancelButton":"取消此对话","relationAll":"所有规则","conditionLarger":"大于","valueBoxLabel":"值","statusTipMsg":"在此处单击过滤器栏以根据 ${0} 中的值进行过滤。","waiRelAll":"与以下所有规则匹配:","closeFilterBarBtn":"关闭过滤器栏","a11yFilterBarDefButton":"过滤器...","trueLabel":"True","conditionIsNot":"不是","conditionIs":"是","ruleTitleTemplate":"规则 ${0}","waiRemoveRuleButtonTemplate":"除去规则 ${0}","and":"和","conditionLess":"小于","waiColumnSelectTemplate":"${0} 规则列","anycolumn":"任意列","filterDefDialogTitle":"过滤器","waiConditionSelectTemplate":"${0} 规则条件","waiFilterButton":"提交过滤器","statusTipTitle":"过滤器栏","statusTipRelPre":"匹配","anyColumnOption":"任意列","conditionSelectLabel":"条件","cancelButton":"取消","conditionNotStartWith":"不是开始于","conditionEndWith":"结束于","statusTipTitleNoFilter":"过滤器栏","columnSelectLabel":"列","conditionNotContain":"不包含","clearButton":"清除","conditionLargerEqual":"大于等于","any":"任意","relationMsgFront":"匹配","statusTipHeaderColumn":"列","defaultItemsName":"项","conditionEqual":"等于","relationAny":"任意规则","trueLabelEditable":"已检查","or":"或","filterBarMsgHasFilterTemplate":"${0} of ${1} ${2} shown.","rangeTo":"到","conditionStartsWith":"开始于","waiRelAny":"与以下任意规则匹配:","statusTipRelPost":"规则。","relationMsgTail":"","filterBarClearButton":"清除过滤器","incompleteRuleTip":"此规则不完整。","conditionLessEqual":"小于等于","waiFilterBarClearButton":"清除过滤器","conditionAfter":"后","statusTipHeaderCondition":"规则","falseLabel":"False","filterButton":"过滤器","clearFilterDialogTitle":"清除过滤器","statusTipTitleHasFilter":"过滤器","addRuleButton":"添加规则","waiAddRuleButton":"新增规则","waiClearButton":"清除过滤器","conditionNotEqual":"不等于","conditionNotEndWith":"不是结束于","rangeTemplate":"从 ${0} 到 ${1}","removeRuleButton":"除去规则","waiFilterBarDefButton":"过滤表","conditionIsEmpty":"is empty"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/zh/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/zh/Filter.xd.js
new file mode 100644
index 0000000..eb760b1
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/zh/Filter.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.zh.Filter"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.zh.Filter");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Filter", "zh", ({"conditionBefore":"前","filterBarDefButton":"定义过滤器","filterBarMsgNoFilterTemplate":"未应用过滤器","conditionContains":"包含","clearFilterMsg":"将除去过滤器并显示所有可用记录。","all":"所有","waiValueBoxTemplate":"为 ${0} 规则向过滤器输入值","conditionRange":"范围","waiCancelButton":"取消此对话","relationAll":"所有规则","conditionLarger":"大于","valueBoxLabel":"值","statusTipMsg":"在此处单击过滤器栏以根据 ${0} 中的值进行过滤。","waiRelAll":"与以下所有规则匹配:","closeFilterBarBtn":"关闭过滤器栏","a11yFilterBarDefButton":"过滤器...","trueLabel":"True","conditionIsNot":"不是","conditionIs":"是","ruleTitleTemplate":"规则 ${0}","waiRemoveRuleButtonTemplate":"除去规则 ${0}","and":"和","conditionLess":"小于","waiColumnSelectTemplate":"${0} 规则列","anycolumn":"任意列","filterDefDialogTitle":"过滤器","waiConditionSelectTemplate":"${0} 规则条件","waiFilterButton":"提交过滤器","statusTipTitle":"过滤器栏","statusTipRelPre":"匹配","anyColumnOption":"任意列","conditionSelectLabel":"条件","cancelButton":"取消","conditionNotStartWith":"不是开始于","conditionEndWith":"结束于","statusTipTitleNoFilter":"过滤器栏","columnSelectLabel":"列","conditionNotContain":"不包含","clearButton":"清除","conditionLargerEqual":"大于等于","any":"任意","relationMsgFront":"匹配","statusTipHeaderColumn":"列","defaultItemsName":"项","conditionEqual":"等于","relationAny":"任意规则","trueLabelEditable":"已检查","or":"或","filterBarMsgHasFilterTemplate":"${0} of ${1} ${2} shown.","rangeTo":"到","conditionStartsWith":"开始于","waiRelAny":"与以下任意规则匹配:","statusTipRelPost":"规则。","relationMsgTail":"","filterBarClearButton":"清除过滤器","incompleteRuleTip":"此规则不完整。","conditionLessEqual":"小于等于","waiFilterBarClearButton":"清除过滤器","conditionAfter":"后","statusTipHeaderCondition":"规则","falseLabel":"False","filterButton":"过滤器","clearFilterDialogTitle":"清除过滤器","statusTipTitleHasFilter":"过滤器","addRuleButton":"添加规则","waiAddRuleButton":"新增规则","waiClearButton":"清除过滤器","conditionNotEqual":"不等于","conditionNotEndWith":"不是结束于","rangeTemplate":"从 ${0} 到 ${1}","removeRuleButton":"除去规则","waiFilterBarDefButton":"过滤表","conditionIsEmpty":"is empty"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/zh/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/nls/zh/Pagination.js
new file mode 100644
index 0000000..8668514
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/zh/Pagination.js
@@ -0,0 +1 @@
+({"gotoButtonTitle":"访问指定页面","prevTip":"上一页","pageCountIndication":"(共 ${0} 页)","pageStepLabelTemplate":"第 ${0} 页","descTemplate":"${2} - ${3} of ${1} ${0}","lastTip":"末页","nextTip":"下一页","pageSizeLabelTemplate":"每页 ${0} 项","dialogCancel":"取消","itemTitle":"项","dialogConfirm":"访问","firstTip":"首页","allItemsLabelTemplate":"所有项","dialogIndication":"指定页码","dialogTitle":"访问页面"}) \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/nls/zh/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/nls/zh/Pagination.xd.js
new file mode 100644
index 0000000..1383ec0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/nls/zh/Pagination.xd.js
@@ -0,0 +1,5 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.nls.zh.Pagination"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.enhanced.nls.zh.Pagination");dojo._xdLoadFlattenedBundle("dojox.grid.enhanced", "Pagination", "zh", ({"gotoButtonTitle":"访问指定页面","prevTip":"上一页","pageCountIndication":"(共 ${0} 页)","pageStepLabelTemplate":"第 ${0} 页","descTemplate":"${2} - ${3} of ${1} ${0}","lastTip":"末页","nextTip":"下一页","pageSizeLabelTemplate":"每页 ${0} 项","dialogCancel":"取消","itemTitle":"项","dialogConfirm":"访问","firstTip":"首页","allItemsLabelTemplate":"所有项","dialogIndication":"指定页码","dialogTitle":"访问页面"})
+);
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/AutoScroll.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/AutoScroll.js
new file mode 100644
index 0000000..a64128f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/AutoScroll.js
@@ -0,0 +1,182 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.AutoScroll"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.AutoScroll"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.AutoScroll");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid._RowSelector");
+
+dojo.declare("dojox.grid.enhanced.plugins.AutoScroll", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provides horizontal and vertical auto-scroll for grid.
+
+ // name: String
+ // Plugin name
+ name: "autoScroll",
+
+ // autoScrollInterval: Integer
+ // The time interval (in miliseconds) between 2 scrolling.
+ autoScrollInterval: 1000,
+
+ // autoScrollMargin: Integer
+ // The width (in pixel) of the margin area where autoscroll can be triggered.
+ autoScrollMargin: 30,
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ this.readyForAutoScroll = false;
+ this._scrolling = false;
+ args = dojo.isObject(args) ? args : {};
+ if("interval" in args){
+ this.autoScrollInterval = args.interval;
+ }
+ if("margin" in args){
+ this.autoScrollMargin = args.margin;
+ }
+ this._initEvents();
+ this._mixinGrid();
+ },
+ _initEvents: function(){
+ var g = this.grid;
+ this.connect(g, "onCellMouseDown", function(){
+ this.readyForAutoScroll = true;
+ });
+ this.connect(g, "onHeaderCellMouseDown", function(){
+ this.readyForAutoScroll = true;
+ });
+ this.connect(g, "onRowSelectorMouseDown", function(){
+ this.readyForAutoScroll = true;
+ });
+ this.connect(dojo.doc, "onmouseup", function(evt){
+ this._manageAutoScroll(true);
+ this.readyForAutoScroll = false;
+ });
+ this.connect(dojo.doc, "onmousemove", function(evt){
+ if(this.readyForAutoScroll){
+ this._event = evt;
+ var gridPos = dojo.position(g.domNode),
+ hh = g._getHeaderHeight(),
+ margin = this.autoScrollMargin,
+ ey = evt.clientY, ex = evt.clientX,
+ gy = gridPos.y, gx = gridPos.x,
+ gh = gridPos.h, gw = gridPos.w;
+ if(ex >= gx && ex <= gx + gw){
+ if(ey >= gy + hh && ey < gy + hh + margin){
+ this._manageAutoScroll(false, true, false);
+ return;
+ }else if(ey > gy + gh - margin && ey <= gy + gh){
+ this._manageAutoScroll(false, true, true);
+ return;
+ }else if(ey >= gy && ey <= gy + gh){
+ var withinSomeview = dojo.some(g.views.views, function(view, i){
+ if(view instanceof dojox.grid._RowSelector){
+ return false;
+ }
+ var viewPos = dojo.position(view.domNode);
+ if(ex < viewPos.x + margin && ex >= viewPos.x){
+ this._manageAutoScroll(false, false, false, view);
+ return true;
+ }else if(ex > viewPos.x + viewPos.w - margin && ex < viewPos.x + viewPos.w){
+ this._manageAutoScroll(false, false, true, view);
+ return true;
+ }
+ return false;
+ }, this);
+ if(withinSomeview){
+ return;
+ }
+ }
+ }
+ //stop autoscroll.
+ this._manageAutoScroll(true);
+ }
+ });
+ },
+ _mixinGrid: function(){
+ var g = this.grid;
+ g.onStartAutoScroll = function(/*isVertical, isForward*/){};
+ g.onEndAutoScroll = function(/*isVertical, isForward, view, scrollToRowIndex, event*/){};
+ },
+ _fireEvent: function(eventName, args){
+ var g = this.grid;
+ switch(eventName){
+ case "start":
+ g.onStartAutoScroll.apply(g, args);
+ break;
+ case "end":
+ g.onEndAutoScroll.apply(g, args);
+ break;
+ }
+ },
+ _manageAutoScroll: function(toStop, isVertical, isForward, view){
+ if(toStop){
+ this._scrolling = false;
+ clearInterval(this._handler);
+ }else if(!this._scrolling){
+ this._scrolling = true;
+ this._fireEvent("start", [isVertical, isForward, view]);
+ this._autoScroll(isVertical, isForward, view);
+ this._handler = setInterval(dojo.hitch(this, "_autoScroll", isVertical, isForward, view), this.autoScrollInterval);
+ }
+ },
+ _autoScroll: function(isVertical, isForward, view){
+ var g = this.grid,
+ target = null;
+ if(isVertical){
+ var targetRow = g.scroller.firstVisibleRow + (isForward ? 1 : -1);
+ if(targetRow >= 0 && targetRow < g.rowCount){
+ g.scrollToRow(targetRow);
+ target = targetRow;
+ }
+ }else{
+ target = this._scrollColumn(isForward, view);
+ }
+ if(target !== null){
+ this._fireEvent("end", [isVertical, isForward, view, target, this._event]);
+ }
+ },
+ _scrollColumn: function(isForward, view){
+ var node = view.scrollboxNode,
+ target = null;
+ if(node.clientWidth < node.scrollWidth){
+ var cells = dojo.filter(this.grid.layout.cells, function(cell){
+ return !cell.hidden;
+ });
+ var viewPos = dojo.position(view.domNode);
+ var limit, edge, headerPos, i;
+ if(isForward){
+ limit = node.clientWidth;
+ for(i = 0; i < cells.length; ++i){
+ headerPos = dojo.position(cells[i].getHeaderNode());
+ edge = headerPos.x - viewPos.x + headerPos.w;
+ if(edge > limit){
+ target = cells[i].index;
+ node.scrollLeft += edge - limit + 10;
+ break;
+ }
+ }
+ }else{
+ limit = 0;
+ for(i = cells.length - 1; i >= 0; --i){
+ headerPos = dojo.position(cells[i].getHeaderNode());
+ edge = headerPos.x - viewPos.x;
+ if(edge < limit){
+ target = cells[i].index;
+ node.scrollLeft += edge - limit - 10;
+ break;
+ }
+ }
+ }
+ }
+ return target;
+ }
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.AutoScroll/*name:'autoScroll'*/);
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/AutoScroll.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/AutoScroll.xd.js
new file mode 100644
index 0000000..0afebe6
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/AutoScroll.xd.js
@@ -0,0 +1,188 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.AutoScroll"],
+["require", "dojox.grid.enhanced._Plugin"],
+["require", "dojox.grid._RowSelector"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.AutoScroll"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.AutoScroll"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.AutoScroll");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid._RowSelector");
+
+dojo.declare("dojox.grid.enhanced.plugins.AutoScroll", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provides horizontal and vertical auto-scroll for grid.
+
+ // name: String
+ // Plugin name
+ name: "autoScroll",
+
+ // autoScrollInterval: Integer
+ // The time interval (in miliseconds) between 2 scrolling.
+ autoScrollInterval: 1000,
+
+ // autoScrollMargin: Integer
+ // The width (in pixel) of the margin area where autoscroll can be triggered.
+ autoScrollMargin: 30,
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ this.readyForAutoScroll = false;
+ this._scrolling = false;
+ args = dojo.isObject(args) ? args : {};
+ if("interval" in args){
+ this.autoScrollInterval = args.interval;
+ }
+ if("margin" in args){
+ this.autoScrollMargin = args.margin;
+ }
+ this._initEvents();
+ this._mixinGrid();
+ },
+ _initEvents: function(){
+ var g = this.grid;
+ this.connect(g, "onCellMouseDown", function(){
+ this.readyForAutoScroll = true;
+ });
+ this.connect(g, "onHeaderCellMouseDown", function(){
+ this.readyForAutoScroll = true;
+ });
+ this.connect(g, "onRowSelectorMouseDown", function(){
+ this.readyForAutoScroll = true;
+ });
+ this.connect(dojo.doc, "onmouseup", function(evt){
+ this._manageAutoScroll(true);
+ this.readyForAutoScroll = false;
+ });
+ this.connect(dojo.doc, "onmousemove", function(evt){
+ if(this.readyForAutoScroll){
+ this._event = evt;
+ var gridPos = dojo.position(g.domNode),
+ hh = g._getHeaderHeight(),
+ margin = this.autoScrollMargin,
+ ey = evt.clientY, ex = evt.clientX,
+ gy = gridPos.y, gx = gridPos.x,
+ gh = gridPos.h, gw = gridPos.w;
+ if(ex >= gx && ex <= gx + gw){
+ if(ey >= gy + hh && ey < gy + hh + margin){
+ this._manageAutoScroll(false, true, false);
+ return;
+ }else if(ey > gy + gh - margin && ey <= gy + gh){
+ this._manageAutoScroll(false, true, true);
+ return;
+ }else if(ey >= gy && ey <= gy + gh){
+ var withinSomeview = dojo.some(g.views.views, function(view, i){
+ if(view instanceof dojox.grid._RowSelector){
+ return false;
+ }
+ var viewPos = dojo.position(view.domNode);
+ if(ex < viewPos.x + margin && ex >= viewPos.x){
+ this._manageAutoScroll(false, false, false, view);
+ return true;
+ }else if(ex > viewPos.x + viewPos.w - margin && ex < viewPos.x + viewPos.w){
+ this._manageAutoScroll(false, false, true, view);
+ return true;
+ }
+ return false;
+ }, this);
+ if(withinSomeview){
+ return;
+ }
+ }
+ }
+ //stop autoscroll.
+ this._manageAutoScroll(true);
+ }
+ });
+ },
+ _mixinGrid: function(){
+ var g = this.grid;
+ g.onStartAutoScroll = function(/*isVertical, isForward*/){};
+ g.onEndAutoScroll = function(/*isVertical, isForward, view, scrollToRowIndex, event*/){};
+ },
+ _fireEvent: function(eventName, args){
+ var g = this.grid;
+ switch(eventName){
+ case "start":
+ g.onStartAutoScroll.apply(g, args);
+ break;
+ case "end":
+ g.onEndAutoScroll.apply(g, args);
+ break;
+ }
+ },
+ _manageAutoScroll: function(toStop, isVertical, isForward, view){
+ if(toStop){
+ this._scrolling = false;
+ clearInterval(this._handler);
+ }else if(!this._scrolling){
+ this._scrolling = true;
+ this._fireEvent("start", [isVertical, isForward, view]);
+ this._autoScroll(isVertical, isForward, view);
+ this._handler = setInterval(dojo.hitch(this, "_autoScroll", isVertical, isForward, view), this.autoScrollInterval);
+ }
+ },
+ _autoScroll: function(isVertical, isForward, view){
+ var g = this.grid,
+ target = null;
+ if(isVertical){
+ var targetRow = g.scroller.firstVisibleRow + (isForward ? 1 : -1);
+ if(targetRow >= 0 && targetRow < g.rowCount){
+ g.scrollToRow(targetRow);
+ target = targetRow;
+ }
+ }else{
+ target = this._scrollColumn(isForward, view);
+ }
+ if(target !== null){
+ this._fireEvent("end", [isVertical, isForward, view, target, this._event]);
+ }
+ },
+ _scrollColumn: function(isForward, view){
+ var node = view.scrollboxNode,
+ target = null;
+ if(node.clientWidth < node.scrollWidth){
+ var cells = dojo.filter(this.grid.layout.cells, function(cell){
+ return !cell.hidden;
+ });
+ var viewPos = dojo.position(view.domNode);
+ var limit, edge, headerPos, i;
+ if(isForward){
+ limit = node.clientWidth;
+ for(i = 0; i < cells.length; ++i){
+ headerPos = dojo.position(cells[i].getHeaderNode());
+ edge = headerPos.x - viewPos.x + headerPos.w;
+ if(edge > limit){
+ target = cells[i].index;
+ node.scrollLeft += edge - limit + 10;
+ break;
+ }
+ }
+ }else{
+ limit = 0;
+ for(i = cells.length - 1; i >= 0; --i){
+ headerPos = dojo.position(cells[i].getHeaderNode());
+ edge = headerPos.x - viewPos.x;
+ if(edge < limit){
+ target = cells[i].index;
+ node.scrollLeft += edge - limit - 10;
+ break;
+ }
+ }
+ }
+ }
+ return target;
+ }
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.AutoScroll/*name:'autoScroll'*/);
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/CellMerge.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/CellMerge.js
new file mode 100644
index 0000000..1bfb408
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/CellMerge.js
@@ -0,0 +1,277 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.CellMerge"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.CellMerge"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.CellMerge");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+
+dojo.declare("dojox.grid.enhanced.plugins.CellMerge", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // This plugin provides functions to merge(un-merge) adjacent cells within one row.
+ // Acceptable plugin paramters:
+ // 1. mergedCells: Array
+ // An array of objects with structure:
+ // {
+ // row: function(Integer)|Integer
+ // If it's a function, it's a predicate to decide which rows are to be merged.
+ // It takes an integer (the row index), and should return true or false;
+ // start: Integer
+ // The column index of the left most cell that shall be merged.
+ // end: Integer
+ // The column index of the right most cell that shall be merged.
+ // major: Integer
+ // The column index of the cell whose content should be used as the content of the merged cell.
+ // It must be larger than or equal to the startColumnIndex, and less than or equal to the endColumnIndex.
+ // If it is omitted, the content of the leading edge (left-most for ltr, right most for rtl) cell will be used.
+ // }
+
+ // name: String
+ // Plugin name
+ name: "cellMerge",
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ this._records = [];
+ this._merged = {};
+ if(args && dojo.isObject(args)){
+ this._setupConfig(args.mergedCells);
+ }
+ this._initEvents();
+ this._mixinGrid();
+ },
+ //----------------Public----------------------------
+ mergeCells: function(rowTester, startColumnIndex, endColumnIndex, majorColumnIndex){
+ // summary:
+ // Merge cells from *startColumnIndex* to *endColumnIndex* at rows that make *rowTester* return true,
+ // using the content of the cell at *majorColumnIndex*
+ // tags:
+ // public
+ // rowTester: function(Integer)|Integer
+ // If it's a function, it's a predicate to decide which rows are to be merged.
+ // It takes an integer (the row index), and should return true or false;
+ // startColumnIndex: Integer
+ // The column index of the left most cell that shall be merged.
+ // endColumnIndex: Integer
+ // The column index of the right most cell that shall be merged.
+ // majorColumnIndex: Integer?
+ // The column index of the cell whose content should be used as the content of the merged cell.
+ // It must be larger than or equal to the startColumnIndex, and less than or equal to the endColumnIndex.
+ // If it is omitted, the content of the leading edge (left-most for ltr, right most for rtl) cell will be used.
+ // return: Object | null
+ // A handler for the merged cells created by a call of this function.
+ // This handler can be used later to unmerge cells using the function unmergeCells
+ // If the merge is not valid, returns null;
+ var item = this._createRecord({
+ "row": rowTester,
+ "start": startColumnIndex,
+ "end": endColumnIndex,
+ "major": majorColumnIndex
+ });
+ if(item){
+ this._updateRows(item);
+ }
+ return item;
+ },
+ unmergeCells: function(mergeHandler){
+ // summary:
+ // Unmerge the cells that are merged by the *mergeHandler*, which represents a call to the function mergeCells.
+ // tags:
+ // public
+ // mergeHandler: object
+ // A handler for the merged cells created by a call of function mergeCells.
+ var idx;
+ if(mergeHandler && (idx = dojo.indexOf(this._records, mergeHandler)) >= 0){
+ this._records.splice(idx, 1);
+ this._updateRows(mergeHandler);
+ }
+ },
+ getMergedCells: function(){
+ // summary:
+ // Get all records of currently merged cells.
+ // tags:
+ // public
+ // return: Array
+ // An array of records for merged-cells.
+ // The record has the following structure:
+ // {
+ // "row": 1, //the row index
+ // "start": 2, //the start column index
+ // "end": 4, //the end column index
+ // "major": 3, //the major column index
+ // "handle": someHandle, //The handler that covers this merge cell record.
+ // }
+ var res = [];
+ for(var i in this._merged){
+ res = res.concat(this._merged[i]);
+ }
+ return res;
+ },
+ getMergedCellsByRow: function(rowIndex){
+ // summary:
+ // Get the records of currently merged cells at the given row.
+ // tags:
+ // public
+ // return: Array
+ // An array of records for merged-cells. See docs of getMergedCells.
+ return this._merged[rowIndex] || [];
+ },
+
+ //----------------Private--------------------------
+ _setupConfig: function(config){
+ dojo.forEach(config, this._createRecord, this);
+ },
+ _initEvents: function(){
+ dojo.forEach(this.grid.views.views, function(view){
+ this.connect(view, "onAfterRow", dojo.hitch(this, "_onAfterRow", view.index));
+ }, this);
+ },
+ _mixinGrid: function(){
+ var g = this.grid;
+ g.mergeCells = dojo.hitch(this, "mergeCells");
+ g.unmergeCells = dojo.hitch(this, "unmergeCells");
+ g.getMergedCells = dojo.hitch(this, "getMergedCells");
+ g.getMergedCellsByRow = dojo.hitch(this, "getMergedCellsByRow");
+ },
+ _getWidth: function(colIndex){
+ var node = this.grid.layout.cells[colIndex].getHeaderNode();
+ return dojo.position(node).w;
+ },
+ _onAfterRow: function(viewIdx, rowIndex, subrows){
+ try{
+ if(rowIndex < 0){
+ return;
+ }
+ var result = [], i, j, len = this._records.length,
+ cells = this.grid.layout.cells;
+ //Apply merge-cell requests one by one.
+ for(i = 0; i < len; ++i){
+ var item = this._records[i];
+ var storeItem = this.grid._by_idx[rowIndex];
+ if(item.view == viewIdx && item.row(rowIndex, storeItem && storeItem.item, this.grid.store)){
+ var res = {
+ record: item,
+ hiddenCells: [],
+ totalWidth: 0,
+ majorNode: cells[item.major].getNode(rowIndex),
+ majorHeaderNode: cells[item.major].getHeaderNode()
+ };
+ //Calculated the width of merged cell.
+ for(j = item.start; j <= item.end; ++j){
+ var w = this._getWidth(j, rowIndex);
+ res.totalWidth += w;
+ if(j != item.major){
+ res.hiddenCells.push(cells[j].getNode(rowIndex));
+ }
+ }
+ //If width is valid, remember it. There may be multiple merges within one row.
+ if(subrows.length != 1 || res.totalWidth > 0){
+ //Remove conflicted merges.
+ for(j = result.length - 1; j >= 0; --j){
+ var r = result[j].record;
+ if((r.start >= item.start && r.start <= item.end) ||
+ (r.end >= item.start && r.end <= item.end)){
+ result.splice(j, 1);
+ }
+ }
+ result.push(res);
+ }
+ }
+ }
+ this._merged[rowIndex] = [];
+ dojo.forEach(result, function(res){
+ dojo.forEach(res.hiddenCells, function(node){
+ dojo.style(node, "display", "none");
+ });
+ var pbm = dojo.marginBox(res.majorHeaderNode).w - dojo.contentBox(res.majorHeaderNode).w;
+ var tw = res.totalWidth;
+
+ //Tricky for WebKit.
+ if(!dojo.isWebKit){
+ tw -= pbm;
+ }
+
+ dojo.style(res.majorNode, "width", tw + "px");
+ //In case we're dealing with multiple subrows.
+ dojo.attr(res.majorNode, "colspan", res.hiddenCells.length + 1);
+
+ this._merged[rowIndex].push({
+ "row": rowIndex,
+ "start": res.record.start,
+ "end": res.record.end,
+ "major": res.record.major,
+ "handle": res.record
+ });
+ }, this);
+ }catch(e){
+ console.warn("CellMerge._onAfterRow() error: ", rowIndex, e);
+ }
+ },
+ _createRecord: function(item){
+ if(this._isValid(item)){
+ item = {
+ "row": item.row,
+ "start": item.start,
+ "end": item.end,
+ "major": item.major
+ };
+ var cells = this.grid.layout.cells;
+ item.view = cells[item.start].view.index;
+ item.major = typeof item.major == "number" && !isNaN(item.major) ? item.major : item.start;
+ if(typeof item.row == "number"){
+ var r = item.row;
+ item.row = function(rowIndex){
+ return rowIndex === r;
+ };
+ }else if(typeof item.row == "string"){
+ var id = item.row;
+ item.row = function(rowIndex, storeItem, store){
+ try{
+ if(store && storeItem && store.getFeatures()['dojo.data.api.Identity']){
+ return store.getIdentity(storeItem) == id;
+ }
+ }catch(e){
+ console.error(e);
+ }
+ return false;
+ };
+ }
+ if(dojo.isFunction(item.row)){
+ this._records.push(item);
+ return item;
+ }
+ }
+ return null;
+ },
+ _isValid: function(item){
+ var cells = this.grid.layout.cells,
+ colCount = cells.length;
+ return (dojo.isObject(item) && ("row" in item) && ("start" in item) && ("end" in item) &&
+ item.start >= 0 && item.start < colCount &&
+ item.end > item.start && item.end < colCount &&
+ cells[item.start].view.index == cells[item.end].view.index &&
+ cells[item.start].subrow == cells[item.end].subrow &&
+ !(typeof item.major == "number" && (item.major < item.start || item.major > item.end)));
+ },
+ _updateRows: function(item){
+ var min = null;
+ for(var i = 0, count = this.grid.rowCount; i < count; ++i){
+ var storeItem = this.grid._by_idx[i];
+ if(storeItem && item.row(i, storeItem && storeItem.item, this.grid.store)){
+ this.grid.views.updateRow(i);
+ if(min === null){ min = i; }
+ }
+ }
+ if(min >= 0){
+ this.grid.scroller.rowHeightChanged(min);
+ }
+ }
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.CellMerge/*name:'cellMerge'*/);
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/CellMerge.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/CellMerge.xd.js
new file mode 100644
index 0000000..72e7f15
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/CellMerge.xd.js
@@ -0,0 +1,282 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.CellMerge"],
+["require", "dojox.grid.enhanced._Plugin"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.CellMerge"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.CellMerge"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.CellMerge");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+
+dojo.declare("dojox.grid.enhanced.plugins.CellMerge", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // This plugin provides functions to merge(un-merge) adjacent cells within one row.
+ // Acceptable plugin paramters:
+ // 1. mergedCells: Array
+ // An array of objects with structure:
+ // {
+ // row: function(Integer)|Integer
+ // If it's a function, it's a predicate to decide which rows are to be merged.
+ // It takes an integer (the row index), and should return true or false;
+ // start: Integer
+ // The column index of the left most cell that shall be merged.
+ // end: Integer
+ // The column index of the right most cell that shall be merged.
+ // major: Integer
+ // The column index of the cell whose content should be used as the content of the merged cell.
+ // It must be larger than or equal to the startColumnIndex, and less than or equal to the endColumnIndex.
+ // If it is omitted, the content of the leading edge (left-most for ltr, right most for rtl) cell will be used.
+ // }
+
+ // name: String
+ // Plugin name
+ name: "cellMerge",
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ this._records = [];
+ this._merged = {};
+ if(args && dojo.isObject(args)){
+ this._setupConfig(args.mergedCells);
+ }
+ this._initEvents();
+ this._mixinGrid();
+ },
+ //----------------Public----------------------------
+ mergeCells: function(rowTester, startColumnIndex, endColumnIndex, majorColumnIndex){
+ // summary:
+ // Merge cells from *startColumnIndex* to *endColumnIndex* at rows that make *rowTester* return true,
+ // using the content of the cell at *majorColumnIndex*
+ // tags:
+ // public
+ // rowTester: function(Integer)|Integer
+ // If it's a function, it's a predicate to decide which rows are to be merged.
+ // It takes an integer (the row index), and should return true or false;
+ // startColumnIndex: Integer
+ // The column index of the left most cell that shall be merged.
+ // endColumnIndex: Integer
+ // The column index of the right most cell that shall be merged.
+ // majorColumnIndex: Integer?
+ // The column index of the cell whose content should be used as the content of the merged cell.
+ // It must be larger than or equal to the startColumnIndex, and less than or equal to the endColumnIndex.
+ // If it is omitted, the content of the leading edge (left-most for ltr, right most for rtl) cell will be used.
+ // return: Object | null
+ // A handler for the merged cells created by a call of this function.
+ // This handler can be used later to unmerge cells using the function unmergeCells
+ // If the merge is not valid, returns null;
+ var item = this._createRecord({
+ "row": rowTester,
+ "start": startColumnIndex,
+ "end": endColumnIndex,
+ "major": majorColumnIndex
+ });
+ if(item){
+ this._updateRows(item);
+ }
+ return item;
+ },
+ unmergeCells: function(mergeHandler){
+ // summary:
+ // Unmerge the cells that are merged by the *mergeHandler*, which represents a call to the function mergeCells.
+ // tags:
+ // public
+ // mergeHandler: object
+ // A handler for the merged cells created by a call of function mergeCells.
+ var idx;
+ if(mergeHandler && (idx = dojo.indexOf(this._records, mergeHandler)) >= 0){
+ this._records.splice(idx, 1);
+ this._updateRows(mergeHandler);
+ }
+ },
+ getMergedCells: function(){
+ // summary:
+ // Get all records of currently merged cells.
+ // tags:
+ // public
+ // return: Array
+ // An array of records for merged-cells.
+ // The record has the following structure:
+ // {
+ // "row": 1, //the row index
+ // "start": 2, //the start column index
+ // "end": 4, //the end column index
+ // "major": 3, //the major column index
+ // "handle": someHandle, //The handler that covers this merge cell record.
+ // }
+ var res = [];
+ for(var i in this._merged){
+ res = res.concat(this._merged[i]);
+ }
+ return res;
+ },
+ getMergedCellsByRow: function(rowIndex){
+ // summary:
+ // Get the records of currently merged cells at the given row.
+ // tags:
+ // public
+ // return: Array
+ // An array of records for merged-cells. See docs of getMergedCells.
+ return this._merged[rowIndex] || [];
+ },
+
+ //----------------Private--------------------------
+ _setupConfig: function(config){
+ dojo.forEach(config, this._createRecord, this);
+ },
+ _initEvents: function(){
+ dojo.forEach(this.grid.views.views, function(view){
+ this.connect(view, "onAfterRow", dojo.hitch(this, "_onAfterRow", view.index));
+ }, this);
+ },
+ _mixinGrid: function(){
+ var g = this.grid;
+ g.mergeCells = dojo.hitch(this, "mergeCells");
+ g.unmergeCells = dojo.hitch(this, "unmergeCells");
+ g.getMergedCells = dojo.hitch(this, "getMergedCells");
+ g.getMergedCellsByRow = dojo.hitch(this, "getMergedCellsByRow");
+ },
+ _getWidth: function(colIndex){
+ var node = this.grid.layout.cells[colIndex].getHeaderNode();
+ return dojo.position(node).w;
+ },
+ _onAfterRow: function(viewIdx, rowIndex, subrows){
+ try{
+ if(rowIndex < 0){
+ return;
+ }
+ var result = [], i, j, len = this._records.length,
+ cells = this.grid.layout.cells;
+ //Apply merge-cell requests one by one.
+ for(i = 0; i < len; ++i){
+ var item = this._records[i];
+ var storeItem = this.grid._by_idx[rowIndex];
+ if(item.view == viewIdx && item.row(rowIndex, storeItem && storeItem.item, this.grid.store)){
+ var res = {
+ record: item,
+ hiddenCells: [],
+ totalWidth: 0,
+ majorNode: cells[item.major].getNode(rowIndex),
+ majorHeaderNode: cells[item.major].getHeaderNode()
+ };
+ //Calculated the width of merged cell.
+ for(j = item.start; j <= item.end; ++j){
+ var w = this._getWidth(j, rowIndex);
+ res.totalWidth += w;
+ if(j != item.major){
+ res.hiddenCells.push(cells[j].getNode(rowIndex));
+ }
+ }
+ //If width is valid, remember it. There may be multiple merges within one row.
+ if(subrows.length != 1 || res.totalWidth > 0){
+ //Remove conflicted merges.
+ for(j = result.length - 1; j >= 0; --j){
+ var r = result[j].record;
+ if((r.start >= item.start && r.start <= item.end) ||
+ (r.end >= item.start && r.end <= item.end)){
+ result.splice(j, 1);
+ }
+ }
+ result.push(res);
+ }
+ }
+ }
+ this._merged[rowIndex] = [];
+ dojo.forEach(result, function(res){
+ dojo.forEach(res.hiddenCells, function(node){
+ dojo.style(node, "display", "none");
+ });
+ var pbm = dojo.marginBox(res.majorHeaderNode).w - dojo.contentBox(res.majorHeaderNode).w;
+ var tw = res.totalWidth;
+
+ //Tricky for WebKit.
+ if(!dojo.isWebKit){
+ tw -= pbm;
+ }
+
+ dojo.style(res.majorNode, "width", tw + "px");
+ //In case we're dealing with multiple subrows.
+ dojo.attr(res.majorNode, "colspan", res.hiddenCells.length + 1);
+
+ this._merged[rowIndex].push({
+ "row": rowIndex,
+ "start": res.record.start,
+ "end": res.record.end,
+ "major": res.record.major,
+ "handle": res.record
+ });
+ }, this);
+ }catch(e){
+ console.warn("CellMerge._onAfterRow() error: ", rowIndex, e);
+ }
+ },
+ _createRecord: function(item){
+ if(this._isValid(item)){
+ item = {
+ "row": item.row,
+ "start": item.start,
+ "end": item.end,
+ "major": item.major
+ };
+ var cells = this.grid.layout.cells;
+ item.view = cells[item.start].view.index;
+ item.major = typeof item.major == "number" && !isNaN(item.major) ? item.major : item.start;
+ if(typeof item.row == "number"){
+ var r = item.row;
+ item.row = function(rowIndex){
+ return rowIndex === r;
+ };
+ }else if(typeof item.row == "string"){
+ var id = item.row;
+ item.row = function(rowIndex, storeItem, store){
+ try{
+ if(store && storeItem && store.getFeatures()['dojo.data.api.Identity']){
+ return store.getIdentity(storeItem) == id;
+ }
+ }catch(e){
+ console.error(e);
+ }
+ return false;
+ };
+ }
+ if(dojo.isFunction(item.row)){
+ this._records.push(item);
+ return item;
+ }
+ }
+ return null;
+ },
+ _isValid: function(item){
+ var cells = this.grid.layout.cells,
+ colCount = cells.length;
+ return (dojo.isObject(item) && ("row" in item) && ("start" in item) && ("end" in item) &&
+ item.start >= 0 && item.start < colCount &&
+ item.end > item.start && item.end < colCount &&
+ cells[item.start].view.index == cells[item.end].view.index &&
+ cells[item.start].subrow == cells[item.end].subrow &&
+ !(typeof item.major == "number" && (item.major < item.start || item.major > item.end)));
+ },
+ _updateRows: function(item){
+ var min = null;
+ for(var i = 0, count = this.grid.rowCount; i < count; ++i){
+ var storeItem = this.grid._by_idx[i];
+ if(storeItem && item.row(i, storeItem && storeItem.item, this.grid.store)){
+ this.grid.views.updateRow(i);
+ if(min === null){ min = i; }
+ }
+ }
+ if(min >= 0){
+ this.grid.scroller.rowHeightChanged(min);
+ }
+ }
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.CellMerge/*name:'cellMerge'*/);
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Cookie.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Cookie.js
new file mode 100644
index 0000000..8e0bc88
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Cookie.js
@@ -0,0 +1,356 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.Cookie"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Cookie"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Cookie");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojo.cookie");
+dojo.require("dojox.grid._RowSelector");
+dojo.require("dojox.grid.cells._base");
+
+(function(){
+ // Generate a cookie key for the given grid.
+ var _cookieKeyBuilder = function(grid){
+ return window.location + "/" + grid.id;
+ };
+
+ //Utilities:
+ var _getCellsFromStructure = function(structure){
+ var cells = [];
+ if(!dojo.isArray(structure)){
+ structure = [structure];
+ }
+ dojo.forEach(structure,function(viewDef){
+ if(dojo.isArray(viewDef)){
+ viewDef = {"cells" : viewDef};
+ }
+ var rows = viewDef.rows || viewDef.cells;
+ if(dojo.isArray(rows)){
+ if(!dojo.isArray(rows[0])){
+ rows = [rows];
+ }
+ dojo.forEach(rows, function(row){
+ if(dojo.isArray(row)){
+ dojo.forEach(row, function(cell){
+ cells.push(cell);
+ });
+ }
+ });
+ }
+ });
+ return cells;
+ };
+
+ // Persist column width
+ var _loadColWidth = function(colWidths, grid){
+ if(dojo.isArray(colWidths)){
+ var oldFunc = grid._setStructureAttr;
+ grid._setStructureAttr = function(structure){
+ if(!grid._colWidthLoaded){
+ grid._colWidthLoaded = true;
+ var cells = _getCellsFromStructure(structure);
+ for(var i = cells.length - 1; i >= 0; --i){
+ if(typeof colWidths[i] == "number"){
+ cells[i].width = colWidths[i] + "px";
+ }
+ }
+ }
+ oldFunc.call(grid, structure);
+ grid._setStructureAttr = oldFunc;
+ };
+ }
+ };
+
+ var _saveColWidth = function(grid){
+ return dojo.map(dojo.filter(grid.layout.cells, function(cell){
+ return !(cell.isRowSelector || cell instanceof dojox.grid.cells.RowIndex);
+ }), function(cell){
+ return dojo[dojo.isWebKit ? "marginBox" : "contentBox"](cell.getHeaderNode()).w;
+ });
+ };
+
+ // Persist column order
+ var _loadColumnOrder = function(colOrder, grid){
+ if(colOrder && dojo.every(colOrder, function(viewInfo){
+ return dojo.isArray(viewInfo) && dojo.every(viewInfo, function(subrowInfo){
+ return dojo.isArray(subrowInfo) && subrowInfo.length > 0;
+ });
+ })){
+ var oldFunc = grid._setStructureAttr;
+ var isCell = function(def){
+ return ("name" in def || "field" in def || "get" in def);
+ };
+ var isView = function(def){
+ return (def !== null && dojo.isObject(def) &&
+ ("cells" in def || "rows" in def || ("type" in def && !isCell(def))));
+ };
+ grid._setStructureAttr = function(structure){
+ if(!grid._colOrderLoaded){
+ grid._colOrderLoaded = true;
+ grid._setStructureAttr = oldFunc;
+ structure = dojo.clone(structure);
+ if(dojo.isArray(structure) && !dojo.some(structure, isView)){
+ structure = [{ cells: structure }];
+ }else if(isView(structure)){
+ structure = [structure];
+ }
+ var cells = _getCellsFromStructure(structure);
+ dojo.forEach(dojo.isArray(structure) ? structure : [structure], function(viewDef, viewIdx){
+ var cellArray = viewDef;
+ if(dojo.isArray(viewDef)){
+ viewDef.splice(0, viewDef.length);
+ }else{
+ delete viewDef.rows;
+ cellArray = viewDef.cells = [];
+ }
+ dojo.forEach(colOrder[viewIdx], function(subrow){
+ dojo.forEach(subrow, function(cellInfo){
+ var i, cell;
+ for(i = 0; i < cells.length; ++i){
+ cell = cells[i];
+ if(dojo.toJson({'name':cell.name,'field':cell.field}) == dojo.toJson(cellInfo)){
+ break;
+ }
+ }
+ if(i < cells.length){
+ cellArray.push(cell);
+ }
+ });
+ });
+ });
+ }
+ oldFunc.call(grid, structure);
+ };
+ }
+ };
+
+ var _saveColumnOrder = function(grid){
+ var colOrder = dojo.map(dojo.filter(grid.views.views, function(view){
+ return !(view instanceof dojox.grid._RowSelector);
+ }), function(view){
+ return dojo.map(view.structure.cells, function(subrow){
+ return dojo.map(dojo.filter(subrow, function(cell){
+ return !(cell.isRowSelector || cell instanceof dojox.grid.cells.RowIndex);
+ }), function(cell){
+ return {
+ "name": cell.name,
+ "field": cell.field
+ };
+ });
+ });
+ });
+ return colOrder;
+ };
+
+ // Persist sorting order
+ var _loadSortOrder = function(sortOrder, grid){
+ try{
+ if(dojo.isObject(sortOrder)){
+ grid.setSortIndex(sortOrder.idx, sortOrder.asc);
+ }
+ }catch(e){
+ //setSortIndex will finally call _fetch, some exceptions will be throw
+ //'cause the grid hasn't be fully loaded now. Just ignore them.
+ }
+ };
+
+ var _saveSortOrder = function(grid){
+ return {
+ idx: grid.getSortIndex(),
+ asc: grid.getSortAsc()
+ };
+ };
+
+ if(!dojo.isIE){
+ // Now in non-IE, widgets are no longer destroyed on page unload,
+ // so we have to destroy it manually to trigger saving cookie.
+ dojo.addOnWindowUnload(function(){
+ dojo.forEach(dijit.findWidgets(dojo.body()), function(widget){
+ if(widget instanceof dojox.grid.EnhancedGrid && !widget._destroyed){
+ widget.destroyRecursive();
+ }
+ });
+ });
+ }
+
+ dojo.declare("dojox.grid.enhanced.plugins.Cookie", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // This plugin provides a way to persist some grid features in cookie.
+ // Default persistable features are:
+ // column width: "columnWidth" (handler name)
+ // column order: "columnOrder"
+ // sorting order: "sortOrder"
+ //
+ // Grid users can define new persistable features
+ // by calling the following before grid is initialized (that is, during "preInit");
+ // | grid.addCookieHandler({
+ // | name: "a name for the new persistable feature",
+ // | onLoad: function(savedObject, grid){
+ // | //load the cookie.
+ // | },
+ // | onSave: function(grid){
+ // | //save the cookie.
+ // | }
+ // | });
+
+ // name: String
+ // Plugin name
+ name: "cookie",
+
+ _cookieEnabled: true,
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ args = (args && dojo.isObject(args)) ? args : {};
+ this.cookieProps = args.cookieProps;
+ this._cookieHandlers = [];
+ this._mixinGrid();
+
+ //Column width & simple sorting & column reorder are base grid features, so they must be supported.
+ this.addCookieHandler({
+ name: "columnWidth",
+ onLoad: _loadColWidth,
+ onSave: _saveColWidth
+ });
+ this.addCookieHandler({
+ name: "columnOrder",
+ onLoad: _loadColumnOrder,
+ onSave: _saveColumnOrder
+ });
+ this.addCookieHandler({
+ name: "sortOrder",
+ onLoad: _loadSortOrder,
+ onSave: _saveSortOrder
+ });
+
+ dojo.forEach(this._cookieHandlers, function(handler){
+ if(args[handler.name] === false){
+ handler.enable = false;
+ }
+ }, this);
+ },
+ destroy:function(){
+ this._saveCookie();
+ this._cookieHandlers = null;
+ this.inherited(arguments);
+ },
+ _mixinGrid: function(){
+ var g = this.grid;
+ g.addCookieHandler = dojo.hitch(this, "addCookieHandler");
+ g.removeCookie = dojo.hitch(this, "removeCookie");
+ g.setCookieEnabled = dojo.hitch(this, "setCookieEnabled");
+ g.getCookieEnabled = dojo.hitch(this, "getCookieEnabled");
+ },
+ _saveCookie: function(){
+ if(this.getCookieEnabled()){
+ var cookie = {},
+ chs = this._cookieHandlers,
+ cookieProps = this.cookieProps,
+ cookieKey = _cookieKeyBuilder(this.grid);
+ for(var i = chs.length-1; i >= 0; --i){
+ if(chs[i].enabled){
+ //Do the real saving work here.
+ cookie[chs[i].name] = chs[i].onSave(this.grid);
+ }
+ }
+ cookieProps = dojo.isObject(this.cookieProps) ? this.cookieProps : {};
+ dojo.cookie(cookieKey, dojo.toJson(cookie), cookieProps);
+ }else{
+ this.removeCookie();
+ }
+ },
+ onPreInit: function(){
+ var grid = this.grid,
+ chs = this._cookieHandlers,
+ cookieKey = _cookieKeyBuilder(grid),
+ cookie = dojo.cookie(cookieKey);
+ if(cookie){
+ cookie = dojo.fromJson(cookie);
+ for(var i = 0; i < chs.length; ++i){
+ if(chs[i].name in cookie && chs[i].enabled){
+ //Do the real loading work here.
+ chs[i].onLoad(cookie[chs[i].name], grid);
+ }
+ }
+ }
+ this._cookie = cookie || {};
+ this._cookieStartedup = true;
+ },
+ addCookieHandler: function(args){
+ // summary:
+ // If a grid plugin wants cookie service, call this.
+ // This must be called during preInit.
+ // args: Object
+ // An object with the following structure:
+ // | {
+ // | name: "some-string",
+ // | onLoad: /* void */ function(/* object */partOfCookie, /* EDG */grid){...},
+ // | onSave: /* object */ function(/* EDG */grid){...}
+ // | }
+ if(args.name){
+ var dummy = function(){};
+ args.onLoad = args.onLoad || dummy;
+ args.onSave = args.onSave || dummy;
+ if(!("enabled" in args)){
+ args.enabled = true;
+ }
+ for(var i = this._cookieHandlers.length - 1; i >= 0; --i){
+ if(this._cookieHandlers[i].name == args.name){
+ this._cookieHandlers.splice(i, 1);
+ }
+ }
+ this._cookieHandlers.push(args);
+ if(this._cookieStartedup && args.name in this._cookie){
+ args.onLoad(this._cookie[args.name], this.grid);
+ }
+ }
+ },
+ removeCookie: function(){
+ // summary:
+ // Remove cookie for this grid.
+ var key = _cookieKeyBuilder(this.grid);
+ dojo.cookie(key, null, {expires: -1});
+ },
+ setCookieEnabled: function(cookieName, enabled){
+ // summary:
+ // A setter to enable|disable cookie support for a particular Grid feature.
+ // cookieName: String?
+ // Name of a cookie handler if provided, otherwise for all cookies.
+ // enabled: Boolean
+ if(arguments.length == 2){
+ var chs = this._cookieHandlers;
+ for(var i = chs.length - 1; i >= 0; --i){
+ if(chs[i].name === cookieName){
+ chs[i].enabled = !!enabled;
+ }
+ }
+ }else{
+ this._cookieEnabled = !!cookieName;
+ if(!this._cookieEnabled){ this.removeCookie(); }
+ }
+ },
+ getCookieEnabled: function(cookieName){
+ // summary:
+ // A getter to check cookie support of a particular Grid feature.
+ // cookieName: String?
+ // Name of a cookie handler if provided, otherwise for all cookies.
+ if(dojo.isString(cookieName)){
+ var chs = this._cookieHandlers;
+ for(var i = chs.length - 1; i >= 0; --i){
+ if(chs[i].name == cookieName){ return chs[i].enabled; }
+ }
+ return false;
+ }
+ return this._cookieEnabled;
+ }
+ });
+ dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Cookie/*name:'cookie'*/, {"preInit": true});
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Cookie.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Cookie.xd.js
new file mode 100644
index 0000000..d9bf5ed
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Cookie.xd.js
@@ -0,0 +1,364 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.Cookie"],
+["require", "dojox.grid.enhanced._Plugin"],
+["require", "dojo.cookie"],
+["require", "dojox.grid._RowSelector"],
+["require", "dojox.grid.cells._base"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.Cookie"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Cookie"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Cookie");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojo.cookie");
+dojo.require("dojox.grid._RowSelector");
+dojo.require("dojox.grid.cells._base");
+
+(function(){
+ // Generate a cookie key for the given grid.
+ var _cookieKeyBuilder = function(grid){
+ return window.location + "/" + grid.id;
+ };
+
+ //Utilities:
+ var _getCellsFromStructure = function(structure){
+ var cells = [];
+ if(!dojo.isArray(structure)){
+ structure = [structure];
+ }
+ dojo.forEach(structure,function(viewDef){
+ if(dojo.isArray(viewDef)){
+ viewDef = {"cells" : viewDef};
+ }
+ var rows = viewDef.rows || viewDef.cells;
+ if(dojo.isArray(rows)){
+ if(!dojo.isArray(rows[0])){
+ rows = [rows];
+ }
+ dojo.forEach(rows, function(row){
+ if(dojo.isArray(row)){
+ dojo.forEach(row, function(cell){
+ cells.push(cell);
+ });
+ }
+ });
+ }
+ });
+ return cells;
+ };
+
+ // Persist column width
+ var _loadColWidth = function(colWidths, grid){
+ if(dojo.isArray(colWidths)){
+ var oldFunc = grid._setStructureAttr;
+ grid._setStructureAttr = function(structure){
+ if(!grid._colWidthLoaded){
+ grid._colWidthLoaded = true;
+ var cells = _getCellsFromStructure(structure);
+ for(var i = cells.length - 1; i >= 0; --i){
+ if(typeof colWidths[i] == "number"){
+ cells[i].width = colWidths[i] + "px";
+ }
+ }
+ }
+ oldFunc.call(grid, structure);
+ grid._setStructureAttr = oldFunc;
+ };
+ }
+ };
+
+ var _saveColWidth = function(grid){
+ return dojo.map(dojo.filter(grid.layout.cells, function(cell){
+ return !(cell.isRowSelector || cell instanceof dojox.grid.cells.RowIndex);
+ }), function(cell){
+ return dojo[dojo.isWebKit ? "marginBox" : "contentBox"](cell.getHeaderNode()).w;
+ });
+ };
+
+ // Persist column order
+ var _loadColumnOrder = function(colOrder, grid){
+ if(colOrder && dojo.every(colOrder, function(viewInfo){
+ return dojo.isArray(viewInfo) && dojo.every(viewInfo, function(subrowInfo){
+ return dojo.isArray(subrowInfo) && subrowInfo.length > 0;
+ });
+ })){
+ var oldFunc = grid._setStructureAttr;
+ var isCell = function(def){
+ return ("name" in def || "field" in def || "get" in def);
+ };
+ var isView = function(def){
+ return (def !== null && dojo.isObject(def) &&
+ ("cells" in def || "rows" in def || ("type" in def && !isCell(def))));
+ };
+ grid._setStructureAttr = function(structure){
+ if(!grid._colOrderLoaded){
+ grid._colOrderLoaded = true;
+ grid._setStructureAttr = oldFunc;
+ structure = dojo.clone(structure);
+ if(dojo.isArray(structure) && !dojo.some(structure, isView)){
+ structure = [{ cells: structure }];
+ }else if(isView(structure)){
+ structure = [structure];
+ }
+ var cells = _getCellsFromStructure(structure);
+ dojo.forEach(dojo.isArray(structure) ? structure : [structure], function(viewDef, viewIdx){
+ var cellArray = viewDef;
+ if(dojo.isArray(viewDef)){
+ viewDef.splice(0, viewDef.length);
+ }else{
+ delete viewDef.rows;
+ cellArray = viewDef.cells = [];
+ }
+ dojo.forEach(colOrder[viewIdx], function(subrow){
+ dojo.forEach(subrow, function(cellInfo){
+ var i, cell;
+ for(i = 0; i < cells.length; ++i){
+ cell = cells[i];
+ if(dojo.toJson({'name':cell.name,'field':cell.field}) == dojo.toJson(cellInfo)){
+ break;
+ }
+ }
+ if(i < cells.length){
+ cellArray.push(cell);
+ }
+ });
+ });
+ });
+ }
+ oldFunc.call(grid, structure);
+ };
+ }
+ };
+
+ var _saveColumnOrder = function(grid){
+ var colOrder = dojo.map(dojo.filter(grid.views.views, function(view){
+ return !(view instanceof dojox.grid._RowSelector);
+ }), function(view){
+ return dojo.map(view.structure.cells, function(subrow){
+ return dojo.map(dojo.filter(subrow, function(cell){
+ return !(cell.isRowSelector || cell instanceof dojox.grid.cells.RowIndex);
+ }), function(cell){
+ return {
+ "name": cell.name,
+ "field": cell.field
+ };
+ });
+ });
+ });
+ return colOrder;
+ };
+
+ // Persist sorting order
+ var _loadSortOrder = function(sortOrder, grid){
+ try{
+ if(dojo.isObject(sortOrder)){
+ grid.setSortIndex(sortOrder.idx, sortOrder.asc);
+ }
+ }catch(e){
+ //setSortIndex will finally call _fetch, some exceptions will be throw
+ //'cause the grid hasn't be fully loaded now. Just ignore them.
+ }
+ };
+
+ var _saveSortOrder = function(grid){
+ return {
+ idx: grid.getSortIndex(),
+ asc: grid.getSortAsc()
+ };
+ };
+
+ if(!dojo.isIE){
+ // Now in non-IE, widgets are no longer destroyed on page unload,
+ // so we have to destroy it manually to trigger saving cookie.
+ dojo.addOnWindowUnload(function(){
+ dojo.forEach(dijit.findWidgets(dojo.body()), function(widget){
+ if(widget instanceof dojox.grid.EnhancedGrid && !widget._destroyed){
+ widget.destroyRecursive();
+ }
+ });
+ });
+ }
+
+ dojo.declare("dojox.grid.enhanced.plugins.Cookie", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // This plugin provides a way to persist some grid features in cookie.
+ // Default persistable features are:
+ // column width: "columnWidth" (handler name)
+ // column order: "columnOrder"
+ // sorting order: "sortOrder"
+ //
+ // Grid users can define new persistable features
+ // by calling the following before grid is initialized (that is, during "preInit");
+ // | grid.addCookieHandler({
+ // | name: "a name for the new persistable feature",
+ // | onLoad: function(savedObject, grid){
+ // | //load the cookie.
+ // | },
+ // | onSave: function(grid){
+ // | //save the cookie.
+ // | }
+ // | });
+
+ // name: String
+ // Plugin name
+ name: "cookie",
+
+ _cookieEnabled: true,
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ args = (args && dojo.isObject(args)) ? args : {};
+ this.cookieProps = args.cookieProps;
+ this._cookieHandlers = [];
+ this._mixinGrid();
+
+ //Column width & simple sorting & column reorder are base grid features, so they must be supported.
+ this.addCookieHandler({
+ name: "columnWidth",
+ onLoad: _loadColWidth,
+ onSave: _saveColWidth
+ });
+ this.addCookieHandler({
+ name: "columnOrder",
+ onLoad: _loadColumnOrder,
+ onSave: _saveColumnOrder
+ });
+ this.addCookieHandler({
+ name: "sortOrder",
+ onLoad: _loadSortOrder,
+ onSave: _saveSortOrder
+ });
+
+ dojo.forEach(this._cookieHandlers, function(handler){
+ if(args[handler.name] === false){
+ handler.enable = false;
+ }
+ }, this);
+ },
+ destroy:function(){
+ this._saveCookie();
+ this._cookieHandlers = null;
+ this.inherited(arguments);
+ },
+ _mixinGrid: function(){
+ var g = this.grid;
+ g.addCookieHandler = dojo.hitch(this, "addCookieHandler");
+ g.removeCookie = dojo.hitch(this, "removeCookie");
+ g.setCookieEnabled = dojo.hitch(this, "setCookieEnabled");
+ g.getCookieEnabled = dojo.hitch(this, "getCookieEnabled");
+ },
+ _saveCookie: function(){
+ if(this.getCookieEnabled()){
+ var cookie = {},
+ chs = this._cookieHandlers,
+ cookieProps = this.cookieProps,
+ cookieKey = _cookieKeyBuilder(this.grid);
+ for(var i = chs.length-1; i >= 0; --i){
+ if(chs[i].enabled){
+ //Do the real saving work here.
+ cookie[chs[i].name] = chs[i].onSave(this.grid);
+ }
+ }
+ cookieProps = dojo.isObject(this.cookieProps) ? this.cookieProps : {};
+ dojo.cookie(cookieKey, dojo.toJson(cookie), cookieProps);
+ }else{
+ this.removeCookie();
+ }
+ },
+ onPreInit: function(){
+ var grid = this.grid,
+ chs = this._cookieHandlers,
+ cookieKey = _cookieKeyBuilder(grid),
+ cookie = dojo.cookie(cookieKey);
+ if(cookie){
+ cookie = dojo.fromJson(cookie);
+ for(var i = 0; i < chs.length; ++i){
+ if(chs[i].name in cookie && chs[i].enabled){
+ //Do the real loading work here.
+ chs[i].onLoad(cookie[chs[i].name], grid);
+ }
+ }
+ }
+ this._cookie = cookie || {};
+ this._cookieStartedup = true;
+ },
+ addCookieHandler: function(args){
+ // summary:
+ // If a grid plugin wants cookie service, call this.
+ // This must be called during preInit.
+ // args: Object
+ // An object with the following structure:
+ // | {
+ // | name: "some-string",
+ // | onLoad: /* void */ function(/* object */partOfCookie, /* EDG */grid){...},
+ // | onSave: /* object */ function(/* EDG */grid){...}
+ // | }
+ if(args.name){
+ var dummy = function(){};
+ args.onLoad = args.onLoad || dummy;
+ args.onSave = args.onSave || dummy;
+ if(!("enabled" in args)){
+ args.enabled = true;
+ }
+ for(var i = this._cookieHandlers.length - 1; i >= 0; --i){
+ if(this._cookieHandlers[i].name == args.name){
+ this._cookieHandlers.splice(i, 1);
+ }
+ }
+ this._cookieHandlers.push(args);
+ if(this._cookieStartedup && args.name in this._cookie){
+ args.onLoad(this._cookie[args.name], this.grid);
+ }
+ }
+ },
+ removeCookie: function(){
+ // summary:
+ // Remove cookie for this grid.
+ var key = _cookieKeyBuilder(this.grid);
+ dojo.cookie(key, null, {expires: -1});
+ },
+ setCookieEnabled: function(cookieName, enabled){
+ // summary:
+ // A setter to enable|disable cookie support for a particular Grid feature.
+ // cookieName: String?
+ // Name of a cookie handler if provided, otherwise for all cookies.
+ // enabled: Boolean
+ if(arguments.length == 2){
+ var chs = this._cookieHandlers;
+ for(var i = chs.length - 1; i >= 0; --i){
+ if(chs[i].name === cookieName){
+ chs[i].enabled = !!enabled;
+ }
+ }
+ }else{
+ this._cookieEnabled = !!cookieName;
+ if(!this._cookieEnabled){ this.removeCookie(); }
+ }
+ },
+ getCookieEnabled: function(cookieName){
+ // summary:
+ // A getter to check cookie support of a particular Grid feature.
+ // cookieName: String?
+ // Name of a cookie handler if provided, otherwise for all cookies.
+ if(dojo.isString(cookieName)){
+ var chs = this._cookieHandlers;
+ for(var i = chs.length - 1; i >= 0; --i){
+ if(chs[i].name == cookieName){ return chs[i].enabled; }
+ }
+ return false;
+ }
+ return this._cookieEnabled;
+ }
+ });
+ dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Cookie/*name:'cookie'*/, {"preInit": true});
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Dialog.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Dialog.js
new file mode 100644
index 0000000..457a8c0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Dialog.js
@@ -0,0 +1,45 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.Dialog"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Dialog"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Dialog");
+
+dojo.require("dijit.Dialog");
+dojo.require("dojo.window");
+
+dojo.declare("dojox.grid.enhanced.plugins.Dialog", dijit.Dialog, {
+ refNode: null,
+ _position: function(){
+ if(this.refNode && !this._relativePosition){
+ var refPos = dojo.position(dojo.byId(this.refNode)),
+ thisPos = dojo.position(this.domNode),
+ viewPort = dojo.window.getBox();
+ if(refPos.x < 0){
+ refPos.x = 0;
+ }
+ if(refPos.x + refPos.w > viewPort.w){
+ refPos.w = viewPort.w - refPos.x;
+ }
+ if(refPos.y < 0){
+ refPos.y = 0;
+ }
+ if(refPos.y + refPos.h > viewPort.h){
+ refPos.h = viewPort.h - refPos.y;
+ }
+ refPos.x = refPos.x + refPos.w / 2 - thisPos.w / 2;
+ refPos.y = refPos.y + refPos.h / 2 - thisPos.h / 2;
+ if(refPos.x >= 0 && refPos.x + thisPos.w <= viewPort.w &&
+ refPos.y >= 0 && refPos.y + thisPos.h <= viewPort.h){
+ this._relativePosition = refPos;
+ }
+ }
+ this.inherited(arguments);
+ }
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Dialog.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Dialog.xd.js
new file mode 100644
index 0000000..9cd3b0e
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Dialog.xd.js
@@ -0,0 +1,51 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.Dialog"],
+["require", "dijit.Dialog"],
+["require", "dojo.window"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.Dialog"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Dialog"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Dialog");
+
+dojo.require("dijit.Dialog");
+dojo.require("dojo.window");
+
+dojo.declare("dojox.grid.enhanced.plugins.Dialog", dijit.Dialog, {
+ refNode: null,
+ _position: function(){
+ if(this.refNode && !this._relativePosition){
+ var refPos = dojo.position(dojo.byId(this.refNode)),
+ thisPos = dojo.position(this.domNode),
+ viewPort = dojo.window.getBox();
+ if(refPos.x < 0){
+ refPos.x = 0;
+ }
+ if(refPos.x + refPos.w > viewPort.w){
+ refPos.w = viewPort.w - refPos.x;
+ }
+ if(refPos.y < 0){
+ refPos.y = 0;
+ }
+ if(refPos.y + refPos.h > viewPort.h){
+ refPos.h = viewPort.h - refPos.y;
+ }
+ refPos.x = refPos.x + refPos.w / 2 - thisPos.w / 2;
+ refPos.y = refPos.y + refPos.h / 2 - thisPos.h / 2;
+ if(refPos.x >= 0 && refPos.x + thisPos.w <= viewPort.w &&
+ refPos.y >= 0 && refPos.y + thisPos.h <= viewPort.h){
+ this._relativePosition = refPos;
+ }
+ }
+ this.inherited(arguments);
+ }
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/DnD.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/DnD.js
new file mode 100644
index 0000000..8c5d8f1
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/DnD.js
@@ -0,0 +1,1085 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.DnD"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.DnD"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.DnD");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid.enhanced.plugins.Selector");
+dojo.require("dojox.grid.enhanced.plugins.Rearrange");
+dojo.require("dojo.dnd.move");
+dojo.require("dojo.dnd.Source");
+
+(function(){
+var _devideToArrays = function(a){
+ a.sort(function(v1, v2){
+ return v1 - v2;
+ });
+ var arr = [[a[0]]];
+ for(var i = 1, j = 0; i < a.length; ++i){
+ if(a[i] == a[i-1] + 1){
+ arr[j].push(a[i]);
+ }else{
+ arr[++j] = [a[i]];
+ }
+ }
+ return arr;
+ },
+ _joinToArray = function(arrays){
+ var a = arrays[0];
+ for(var i = 1; i < arrays.length; ++i){
+ a = a.concat(arrays[i]);
+ }
+ return a;
+ };
+dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provide drag and drop for grid columns/rows/cells within grid and out of grid.
+ // The store of grid must implement dojo.data.api.Write.
+ // DnD selected columns:
+ // Support moving within grid, moving/copying out of grid to a non-grid DnD target.
+ // DnD selected rows:
+ // Support moving within grid, moving/copying out of grid to any DnD target.
+ // DnD selected cells (in rectangle shape only):
+ // Support moving/copying within grid, moving/copying out of grid to any DnD target.
+ //
+
+ // name: String,
+ // plugin name;
+ name: "dnd",
+
+ _targetAnchorBorderWidth: 2,
+ _copyOnly: false,
+ _config: {
+ "row":{
+ "within":true,
+ "in":true,
+ "out":true
+ },
+ "col":{
+ "within":true,
+ "in":true,
+ "out":true
+ },
+ "cell":{
+ "within":true,
+ "in":true,
+ "out":true
+ }
+ },
+ constructor: function(grid, args){
+ this.grid = grid;
+ this._config = dojo.clone(this._config);
+ args = dojo.isObject(args) ? args : {};
+ this.setupConfig(args.dndConfig);
+ this._copyOnly = !!args.copyOnly;
+
+ //Get the plugins we are dependent on.
+ this._mixinGrid();
+ this.selector = grid.pluginMgr.getPlugin("selector");
+ this.rearranger = grid.pluginMgr.getPlugin("rearrange");
+ //TODO: waiting for a better plugin framework to pass args to dependent plugins.
+ this.rearranger.setArgs(args);
+
+ //Initialized the components we need.
+ this._clear();
+ this._elem = new dojox.grid.enhanced.plugins.GridDnDElement(this);
+ this._source = new dojox.grid.enhanced.plugins.GridDnDSource(this._elem.node, {
+ "grid": grid,
+ "dndElem": this._elem,
+ "dnd": this
+ });
+ this._container = dojo.query(".dojoxGridMasterView", this.grid.domNode)[0];
+ this._initEvents();
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ this._clear();
+ this._source.destroy();
+ this._elem.destroy();
+ this._container = null;
+ this.grid = null;
+ this.selector = null;
+ this.rearranger = null;
+ this._config = null;
+ },
+ _mixinGrid: function(){
+ // summary:
+ // Provide APIs for grid.
+ this.grid.setupDnDConfig = dojo.hitch(this, "setupConfig");
+ this.grid.dndCopyOnly = dojo.hitch(this, "copyOnly");
+ },
+ setupConfig: function(config){
+ // summary:
+ // Configure which DnD functionalities are needed.
+ // Combination of any item from type set ("row", "col", "cell")
+ // and any item from mode set("within", "in", "out") is configurable.
+ //
+ // "row", "col", "cell" are straitforward, while the other 3 are explained below:
+ // "within": DnD within grid, that is, column/row reordering and cell moving/copying.
+ // "in": Whether allowed to accept rows/cells (currently not support columns) from another grid.
+ // "out": Whether allowed to drag out of grid, to another grid or even to any other DnD target.
+ //
+ // If not provided in the config, will use the default.
+ // When declared together, Mode set has higher priority than type set.
+ // config: Object
+ // DnD configuration object.
+ // See the examples below.
+ // example:
+ // The following code disables row DnD within grid,
+ // but still can drag rows out of grid or drag rows from other gird.
+ // | setUpConfig({
+ // | "row": {
+ // | "within": false
+ // | }
+ // | });
+ //
+ // The opposite way is also okay:
+ // | setUpConfig({
+ // | "within": {
+ // | "row": false
+ // | }
+ // | });
+ //
+ // And if you'd like to disable/enable a whole set, here's a shortcut:
+ // | setUpConfig({
+ // | "cell", true,
+ // | "out": false
+ // | });
+ //
+ // Because mode has higher priority than type, the following will disable row dnd within grid:
+ // | setUpConfig({
+ // | "within", {
+ // | "row": false;
+ // | },
+ // | "row", {
+ // | "within": true
+ // | }
+ // | });
+ if(config && dojo.isObject(config)){
+ var firstLevel = ["row", "col", "cell"],
+ secondLevel = ["within", "in", "out"],
+ cfg = this._config;
+ dojo.forEach(firstLevel, function(type){
+ if(type in config){
+ var t = config[type];
+ if(t && dojo.isObject(t)){
+ dojo.forEach(secondLevel, function(mode){
+ if(mode in t){
+ cfg[type][mode] = !!t[mode];
+ }
+ });
+ }else{
+ dojo.forEach(secondLevel, function(mode){
+ cfg[type][mode] = !!t;
+ });
+ }
+ }
+ });
+ dojo.forEach(secondLevel, function(mode){
+ if(mode in config){
+ var m = config[mode];
+ if(m && dojo.isObject(m)){
+ dojo.forEach(firstLevel, function(type){
+ if(type in m){
+ cfg[type][mode] = !!m[type];
+ }
+ });
+ }else{
+ dojo.forEach(firstLevel, function(type){
+ cfg[type][mode] = !!m;
+ });
+ }
+ }
+ });
+ }
+ },
+ copyOnly: function(isCopyOnly){
+ // summary:
+ // Setter/getter of this._copyOnly.
+ if(typeof isCopyOnly != "undefined"){
+ this._copyOnly = !!isCopyOnly;
+ }
+ return this._copyOnly;
+ },
+ _isOutOfGrid: function(evt){
+ var gridPos = dojo.position(this.grid.domNode), x = evt.clientX, y = evt.clientY;
+ return y < gridPos.y || y > gridPos.y + gridPos.h ||
+ x < gridPos.x || x > gridPos.x + gridPos.w;
+ },
+ _onMouseMove: function(evt){
+ if(this._dndRegion && !this._dnding && !this._externalDnd){
+ this._dnding = true;
+ this._startDnd(evt);
+ }else{
+ if(this._isMouseDown && !this._dndRegion){
+ delete this._isMouseDown;
+ this._oldCursor = dojo.style(dojo.body(), "cursor");
+ dojo.style(dojo.body(), "cursor", "not-allowed");
+ }
+ //TODO: should implement as mouseenter/mouseleave
+ //But we have an avatar under mouse when dnd, and this will cause a lot of mouseenter in FF.
+ var isOut = this._isOutOfGrid(evt);
+ if(!this._alreadyOut && isOut){
+ this._alreadyOut = true;
+ if(this._dnding){
+ this._destroyDnDUI(true, false);
+ }
+ this._moveEvent = evt;
+ this._source.onOutEvent();
+ }else if(this._alreadyOut && !isOut){
+ this._alreadyOut = false;
+ if(this._dnding){
+ this._createDnDUI(evt, true);
+ }
+ this._moveEvent = evt;
+ this._source.onOverEvent();
+ }
+ }
+ },
+ _onMouseUp: function(){
+ if(!this._extDnding && !this._isSource){
+ var isInner = this._dnding && !this._alreadyOut;
+ if(isInner && this._config[this._dndRegion.type]["within"]){
+ this._rearrange();
+ }
+ this._endDnd(isInner);
+ }
+ dojo.style(dojo.body(), "cursor", this._oldCursor || "");
+ delete this._isMouseDown;
+ },
+ _initEvents: function(){
+ var g = this.grid, s = this.selector;
+ this.connect(dojo.doc, "onmousemove", "_onMouseMove");
+ this.connect(dojo.doc, "onmouseup", "_onMouseUp");
+
+ this.connect(g, "onCellMouseOver", function(evt){
+ if(!this._dnding && !s.isSelecting() && !evt.ctrlKey){
+ this._dndReady = s.isSelected("cell", evt.rowIndex, evt.cell.index);
+ s.selectEnabled(!this._dndReady);
+ }
+ });
+ this.connect(g, "onHeaderCellMouseOver", function(evt){
+ if(this._dndReady){
+ s.selectEnabled(true);
+ }
+ });
+ this.connect(g, "onRowMouseOver", function(evt){
+ if(this._dndReady && !evt.cell){
+ s.selectEnabled(true);
+ }
+ });
+ this.connect(g, "onCellMouseDown", function(evt){
+ if(!evt.ctrlKey && this._dndReady){
+ this._dndRegion = this._getDnDRegion(evt.rowIndex, evt.cell.index);
+ this._isMouseDown = true;
+ }
+ });
+ this.connect(g, "onCellMouseUp", function(evt){
+ if(!this._dndReady && !s.isSelecting() && evt.cell){
+ this._dndReady = s.isSelected("cell", evt.rowIndex, evt.cell.index);
+ s.selectEnabled(!this._dndReady);
+ }
+ });
+ this.connect(g, "onCellClick", function(evt){
+ if(this._dndReady && !evt.ctrlKey && !evt.shiftKey){
+ s.select("cell", evt.rowIndex, evt.cell.index);
+ }
+ });
+ this.connect(g, "onEndAutoScroll", function(isVertical, isForward, view, target, evt){
+ if(this._dnding){
+ this._markTargetAnchor(evt);
+ }
+ });
+ this.connect(dojo.doc, "onkeydown", function(evt){
+ if(evt.keyCode == dojo.keys.ESCAPE){
+ this._endDnd(false);
+ }else if(evt.keyCode == dojo.keys.CTRL){
+ s.selectEnabled(true);
+ this._isCopy = true;
+ }
+ });
+ this.connect(dojo.doc, "onkeyup", function(evt){
+ if(evt.keyCode == dojo.keys.CTRL){
+ s.selectEnabled(!this._dndReady);
+ this._isCopy = false;
+ }
+ });
+ },
+ _clear: function(){
+ this._dndRegion = null;
+ this._target = null;
+ this._moveEvent = null;
+ this._targetAnchor = {};
+ this._dnding = false;
+ this._externalDnd = false;
+ this._isSource = false;
+ this._alreadyOut = false;
+ this._extDnding = false;
+ },
+ _getDnDRegion: function(rowIndex, colIndex){
+ var s = this.selector,
+ selected = s._selected,
+ flag = (!!selected.cell.length) | (!!selected.row.length << 1) | (!!selected.col.length << 2),
+ type;
+ switch(flag){
+ case 1:
+ type = "cell";
+ if(!this._config[type]["within"] && !this._config[type]["out"]){
+ return null;
+ }
+ var cells = this.grid.layout.cells,
+ getCount = function(range){
+ var hiddenColCnt = 0;
+ for(var i = range.min.col; i <= range.max.col; ++i){
+ if(cells[i].hidden){
+ ++hiddenColCnt;
+ }
+ }
+ return (range.max.row - range.min.row + 1) * (range.max.col - range.min.col + 1 - hiddenColCnt);
+ },
+ inRange = function(item, range){
+ return item.row >= range.min.row && item.row <= range.max.row &&
+ item.col >= range.min.col && item.col <= range.max.col;
+ },
+ range = {
+ max: {
+ row: -1,
+ col: -1
+ },
+ min: {
+ row: Infinity,
+ col: Infinity
+ }
+ };
+
+ dojo.forEach(selected[type], function(item){
+ if(item.row < range.min.row){
+ range.min.row = item.row;
+ }
+ if(item.row > range.max.row){
+ range.max.row = item.row;
+ }
+ if(item.col < range.min.col){
+ range.min.col = item.col;
+ }
+ if(item.col > range.max.col){
+ range.max.col = item.col;
+ }
+ });
+ if(dojo.some(selected[type], function(item){
+ return item.row == rowIndex && item.col == colIndex;
+ })){
+ if(getCount(range) == selected[type].length && dojo.every(selected[type], function(item){
+ return inRange(item, range);
+ })){
+ return {
+ "type": type,
+ "selected": [range],
+ "handle": {
+ "row": rowIndex,
+ "col": colIndex
+ }
+ };
+ }
+ }
+ return null;
+ case 2: case 4:
+ type = flag == 2 ? "row" : "col";
+ if(!this._config[type]["within"] && !this._config[type]["out"]){
+ return null;
+ }
+ var res = s.getSelected(type);
+ if(res.length){
+ return {
+ "type": type,
+ "selected": _devideToArrays(res),
+ "handle": flag == 2 ? rowIndex : colIndex
+ };
+ }
+ return null;
+ }
+ return null;
+ },
+ _startDnd: function(evt){
+ this._createDnDUI(evt);
+ },
+ _endDnd: function(destroySource){
+ this._destroyDnDUI(false, destroySource);
+ this._clear();
+ },
+ _createDnDUI: function(evt, isMovingIn){
+ //By default the master view of grid do not have height, because the children in it are all positioned absolutely.
+ //But we need it to contain avatars.
+ var viewPos = dojo.position(this.grid.views.views[0].domNode);
+ dojo.style(this._container, "height", viewPos.h + "px");
+ try{
+ //If moving in from out side, dnd source is already created.
+ if(!isMovingIn){
+ this._createSource(evt);
+ }
+ this._createMoveable(evt);
+ this._oldCursor = dojo.style(dojo.body(), "cursor");
+ dojo.style(dojo.body(), "cursor", "default");
+ }catch(e){
+ console.warn("DnD._createDnDUI() error:", e);
+ }
+ },
+ _destroyDnDUI: function(isMovingOut, destroySource){
+ try{
+ if(destroySource){
+ this._destroySource();
+ }
+ this._unmarkTargetAnchor();
+ if(!isMovingOut){
+ this._destroyMoveable();
+ }
+ dojo.style(dojo.body(), "cursor", this._oldCursor);
+ }catch(e){
+ console.warn("DnD._destroyDnDUI() error:", this.grid.id, e);
+ }
+ },
+ _createSource: function(evt){
+ this._elem.createDnDNodes(this._dndRegion);
+ var m = dojo.dnd.manager();
+ var oldMakeAvatar = m.makeAvatar;
+ m._dndPlugin = this;
+ m.makeAvatar = function(){
+ var avatar = new dojox.grid.enhanced.plugins.GridDnDAvatar(m);
+ delete m._dndPlugin;
+ return avatar;
+ };
+ m.startDrag(this._source, this._elem.getDnDNodes(), evt.ctrlKey);
+ m.makeAvatar = oldMakeAvatar;
+ m.onMouseMove(evt);
+ },
+ _destroySource: function(){
+ dojo.publish("/dnd/cancel");
+ this._elem.destroyDnDNodes();
+ },
+ _createMoveable: function(evt){
+ if(!this._markTagetAnchorHandler){
+ this._markTagetAnchorHandler = this.connect(dojo.doc, "onmousemove", "_markTargetAnchor");
+ }
+ },
+ _destroyMoveable: function(){
+ this.disconnect(this._markTagetAnchorHandler);
+ delete this._markTagetAnchorHandler;
+ },
+ _calcColTargetAnchorPos: function(evt, containerPos){
+ // summary:
+ // Calculate the position of the column DnD avatar
+ var i, headPos, left, target, ex = evt.clientX,
+ cells = this.grid.layout.cells,
+ ltr = dojo._isBodyLtr(),
+ headers = this._getVisibleHeaders();
+ for(i = 0; i < headers.length; ++i){
+ headPos = dojo.position(headers[i].node);
+ if(ltr ? ((i === 0 || ex >= headPos.x) && ex < headPos.x + headPos.w) :
+ ((i === 0 || ex < headPos.x + headPos.w) && ex >= headPos.x)){
+ left = headPos.x + (ltr ? 0 : headPos.w);
+ break;
+ }else if(ltr ? (i === headers.length - 1 && ex >= headPos.x + headPos.w) :
+ (i === headers.length - 1 && ex < headPos.x)){
+ ++i;
+ left = headPos.x + (ltr ? headPos.w : 0);
+ break;
+ }
+ }
+ if(i < headers.length){
+ target = headers[i].cell.index;
+ if(this.selector.isSelected("col", target) && this.selector.isSelected("col", target - 1)){
+ var ranges = this._dndRegion.selected;
+ for(i = 0; i < ranges.length; ++i){
+ if(dojo.indexOf(ranges[i], target) >= 0){
+ target = ranges[i][0];
+ headPos = dojo.position(cells[target].getHeaderNode());
+ left = headPos.x + (ltr ? 0 : headPos.w);
+ break;
+ }
+ }
+ }
+ }else{
+ target = cells.length;
+ }
+ this._target = target;
+ return left - containerPos.x;
+ },
+ _calcRowTargetAnchorPos: function(evt, containerPos){
+ // summary:
+ // Calculate the position of the row DnD avatar
+ var g = this.grid, top, i = 0,
+ cells = g.layout.cells;
+ while(cells[i].hidden){ ++i; }
+ var cell = g.layout.cells[i],
+ rowIndex = g.scroller.firstVisibleRow,
+ nodePos = dojo.position(cell.getNode(rowIndex));
+ while(nodePos.y + nodePos.h < evt.clientY){
+ if(++rowIndex >= g.rowCount){
+ break;
+ }
+ nodePos = dojo.position(cell.getNode(rowIndex));
+ }
+ if(rowIndex < g.rowCount){
+ if(this.selector.isSelected("row", rowIndex) && this.selector.isSelected("row", rowIndex - 1)){
+ var ranges = this._dndRegion.selected;
+ for(i = 0; i < ranges.length; ++i){
+ if(dojo.indexOf(ranges[i], rowIndex) >= 0){
+ rowIndex = ranges[i][0];
+ nodePos = dojo.position(cell.getNode(rowIndex));
+ break;
+ }
+ }
+ }
+ top = nodePos.y;
+ }else{
+ top = nodePos.y + nodePos.h;
+ }
+ this._target = rowIndex;
+ return top - containerPos.y;
+ },
+ _calcCellTargetAnchorPos: function(evt, containerPos, targetAnchor){
+ // summary:
+ // Calculate the position of the cell DnD avatar
+ var s = this._dndRegion.selected[0],
+ origin = this._dndRegion.handle,
+ g = this.grid, ltr = dojo._isBodyLtr(),
+ cells = g.layout.cells, headPos,
+ minPos, maxPos, headers,
+ height, width, left, top,
+ minCol, maxCol, i,
+ preSpan = origin.col - s.min.col,
+ postSpan = s.max.col - origin.col,
+ leftTopDiv, rightBottomDiv;
+ if(!targetAnchor.childNodes.length){
+ leftTopDiv = dojo.create("div", {
+ "class": "dojoxGridCellBorderLeftTopDIV"
+ }, targetAnchor);
+ rightBottomDiv = dojo.create("div", {
+ "class": "dojoxGridCellBorderRightBottomDIV"
+ }, targetAnchor);
+ }else{
+ leftTopDiv = dojo.query(".dojoxGridCellBorderLeftTopDIV", targetAnchor)[0];
+ rightBottomDiv = dojo.query(".dojoxGridCellBorderRightBottomDIV", targetAnchor)[0];
+ }
+ for(i = s.min.col + 1; i < origin.col; ++i){
+ if(cells[i].hidden){
+ --preSpan;
+ }
+ }
+ for(i = origin.col + 1; i < s.max.col; ++i){
+ if(cells[i].hidden){
+ --postSpan;
+ }
+ }
+ headers = this._getVisibleHeaders();
+ //calc width
+ for(i = preSpan; i < headers.length - postSpan; ++i){
+ headPos = dojo.position(headers[i].node);
+ if((evt.clientX >= headPos.x && evt.clientX < headPos.x + headPos.w) || //within in this column
+ //prior to this column, but within range
+ (i == preSpan && (ltr ? evt.clientX < headPos.x : evt.clientX >= headPos.x + headPos.w)) ||
+ //post to this column, but within range
+ (i == headers.length - postSpan - 1 && (ltr ? evt.clientX >= headPos.x + headPos.w : evt < headPos.x))){
+ minCol = headers[i - preSpan];
+ maxCol = headers[i + postSpan];
+ minPos = dojo.position(minCol.node);
+ maxPos = dojo.position(maxCol.node);
+ minCol = minCol.cell.index;
+ maxCol = maxCol.cell.index;
+ left = ltr ? minPos.x : maxPos.x;
+ width = ltr ? (maxPos.x + maxPos.w - minPos.x) : (minPos.x + minPos.w - maxPos.x);
+ break;
+ }
+ }
+ //calc height
+ i = 0;
+ while(cells[i].hidden){ ++i; }
+ var cell = cells[i],
+ rowIndex = g.scroller.firstVisibleRow,
+ nodePos = dojo.position(cell.getNode(rowIndex));
+ while(nodePos.y + nodePos.h < evt.clientY){
+ if(++rowIndex < g.rowCount){
+ nodePos = dojo.position(cell.getNode(rowIndex));
+ }else{
+ break;
+ }
+ }
+ var minRow = rowIndex >= origin.row - s.min.row ? rowIndex - origin.row + s.min.row : 0;
+ var maxRow = minRow + s.max.row - s.min.row;
+ if(maxRow >= g.rowCount){
+ maxRow = g.rowCount - 1;
+ minRow = maxRow - s.max.row + s.min.row;
+ }
+ minPos = dojo.position(cell.getNode(minRow));
+ maxPos = dojo.position(cell.getNode(maxRow));
+ top = minPos.y;
+ height = maxPos.y + maxPos.h - minPos.y;
+ this._target = {
+ "min":{
+ "row": minRow,
+ "col": minCol
+ },
+ "max":{
+ "row": maxRow,
+ "col": maxCol
+ }
+ };
+ var anchorBorderSize = (dojo.marginBox(leftTopDiv).w - dojo.contentBox(leftTopDiv).w) / 2;
+ var leftTopCellPos = dojo.position(cells[minCol].getNode(minRow));
+ dojo.style(leftTopDiv, {
+ "width": (leftTopCellPos.w - anchorBorderSize) + "px",
+ "height": (leftTopCellPos.h - anchorBorderSize) + "px"
+ });
+ var rightBottomCellPos = dojo.position(cells[maxCol].getNode(maxRow));
+ dojo.style(rightBottomDiv, {
+ "width": (rightBottomCellPos.w - anchorBorderSize) + "px",
+ "height": (rightBottomCellPos.h - anchorBorderSize) + "px"
+ });
+ return {
+ h: height,
+ w: width,
+ l: left - containerPos.x,
+ t: top - containerPos.y
+ };
+ },
+ _markTargetAnchor: function(evt){
+ try{
+ var t = this._dndRegion.type;
+ if(this._alreadyOut || (this._dnding && !this._config[t]["within"]) || (this._extDnding && !this._config[t]["in"])){
+ return;
+ }
+ var height, width, left, top,
+ targetAnchor = this._targetAnchor[t],
+ pos = dojo.position(this._container);
+ if(!targetAnchor){
+ targetAnchor = this._targetAnchor[t] = dojo.create("div", {
+ "class": (t == "cell") ? "dojoxGridCellBorderDIV" : "dojoxGridBorderDIV"
+ });
+ dojo.style(targetAnchor, "display", "none");
+ this._container.appendChild(targetAnchor);
+ }
+ switch(t){
+ case "col":
+ height = pos.h;
+ width = this._targetAnchorBorderWidth;
+ left = this._calcColTargetAnchorPos(evt, pos);
+ top = 0;
+ break;
+ case "row":
+ height = this._targetAnchorBorderWidth;
+ width = pos.w;
+ left = 0;
+ top = this._calcRowTargetAnchorPos(evt, pos);
+ break;
+ case "cell":
+ var cellPos = this._calcCellTargetAnchorPos(evt, pos, targetAnchor);
+ height = cellPos.h;
+ width = cellPos.w;
+ left = cellPos.l;
+ top = cellPos.t;
+ }
+ if(typeof height == "number" && typeof width == "number" && typeof left == "number" && typeof top == "number"){
+ dojo.style(targetAnchor, {
+ "height": height + "px",
+ "width": width + "px",
+ "left": left + "px",
+ "top": top + "px"
+ });
+ dojo.style(targetAnchor, "display", "");
+ }else{
+ this._target = null;
+ }
+ }catch(e){
+ console.warn("DnD._markTargetAnchor() error:",e);
+ }
+ },
+ _unmarkTargetAnchor: function(){
+ if(this._dndRegion){
+ var targetAnchor = this._targetAnchor[this._dndRegion.type];
+ if(targetAnchor){
+ dojo.style(this._targetAnchor[this._dndRegion.type], "display", "none");
+ }
+ }
+ },
+ _getVisibleHeaders: function(){
+ return dojo.map(dojo.filter(this.grid.layout.cells, function(cell){
+ return !cell.hidden;
+ }), function(cell){
+ return {
+ "node": cell.getHeaderNode(),
+ "cell": cell
+ };
+ });
+ },
+ _rearrange: function(){
+ if(this._target === null){
+ return;
+ }
+ var t = this._dndRegion.type;
+ var ranges = this._dndRegion.selected;
+ if(t === "cell"){
+ this.rearranger[(this._isCopy || this._copyOnly) ? "copyCells" : "moveCells"](ranges[0], this._target);
+ }else{
+ this.rearranger[t == "col" ? "moveColumns" : "moveRows"](_joinToArray(ranges), this._target);
+ }
+ this._target = null;
+ },
+ onDraggingOver: function(sourcePlugin){
+ if(!this._dnding && sourcePlugin){
+ sourcePlugin._isSource = true;
+ this._extDnding = true;
+ if(!this._externalDnd){
+ this._externalDnd = true;
+ this._dndRegion = this._mapRegion(sourcePlugin.grid, sourcePlugin._dndRegion);
+ }
+ this._createDnDUI(this._moveEvent,true);
+ this.grid.pluginMgr.getPlugin("autoScroll").readyForAutoScroll = true;
+ }
+ },
+ _mapRegion: function(srcGrid, dndRegion){
+ if(dndRegion.type === "cell"){
+ var srcRange = dndRegion.selected[0];
+ var cells = this.grid.layout.cells;
+ var srcCells = srcGrid.layout.cells;
+ var c, cnt = 0;
+ for(c = srcRange.min.col; c <= srcRange.max.col; ++c){
+ if(!srcCells[c].hidden){
+ ++cnt;
+ }
+ }
+ for(c = 0; cnt > 0; ++c){
+ if(!cells[c].hidden){
+ --cnt;
+ }
+ }
+ var region = dojo.clone(dndRegion);
+ region.selected[0].min.col = 0;
+ region.selected[0].max.col = c - 1;
+ for(c = srcRange.min.col; c <= dndRegion.handle.col; ++c){
+ if(!srcCells[c].hidden){
+ ++cnt;
+ }
+ }
+ for(c = 0; cnt > 0; ++c){
+ if(!cells[c].hidden){
+ --cnt;
+ }
+ }
+ region.handle.col = c;
+ }
+ return dndRegion;
+ },
+ onDraggingOut: function(sourcePlugin){
+ if(this._externalDnd){
+ this._extDnding = false;
+ this._destroyDnDUI(true, false);
+ if(sourcePlugin){
+ sourcePlugin._isSource = false;
+ }
+ }
+ },
+ onDragIn: function(sourcePlugin, isCopy){
+ var success = false;
+ if(this._target !== null){
+ var type = sourcePlugin._dndRegion.type;
+ var ranges = sourcePlugin._dndRegion.selected;
+ switch(type){
+ case "cell":
+ this.rearranger.changeCells(sourcePlugin.grid, ranges[0], this._target);
+ break;
+ case "row":
+ var range = _joinToArray(ranges);
+ this.rearranger.insertRows(sourcePlugin.grid, range, this._target);
+ break;
+ }
+ success = true;
+ }
+ this._endDnd(true);
+ if(sourcePlugin.onDragOut){
+ sourcePlugin.onDragOut(success && !isCopy);
+ }
+ },
+ onDragOut: function(isMove){
+ if(isMove && !this._copyOnly){
+ var type = this._dndRegion.type;
+ var ranges = this._dndRegion.selected;
+ switch(type){
+ case "cell":
+ this.rearranger.clearCells(ranges[0]);
+ break;
+ case "row":
+ this.rearranger.removeRows(_joinToArray(ranges));
+ break;
+ }
+ }
+ this._endDnd(true);
+ },
+ _canAccept: function(sourcePlugin){
+ if(!sourcePlugin){
+ return false;
+ }
+ var srcRegion = sourcePlugin._dndRegion;
+ var type = srcRegion.type;
+ if(!this._config[type]["in"] || !sourcePlugin._config[type]["out"]){
+ return false;
+ }
+ var g = this.grid;
+ var ranges = srcRegion.selected;
+ var colCnt = dojo.filter(g.layout.cells, function(cell){
+ return !cell.hidden;
+ }).length;
+ var rowCnt = g.rowCount;
+ var res = true;
+ switch(type){
+ case "cell":
+ ranges = ranges[0];
+ res = g.store.getFeatures()["dojo.data.api.Write"] &&
+ (ranges.max.row - ranges.min.row) <= rowCnt &&
+ dojo.filter(sourcePlugin.grid.layout.cells, function(cell){
+ return cell.index >= ranges.min.col && cell.index <= ranges.max.col && !cell.hidden;
+ }).length <= colCnt;
+ //intentional drop through - don't break
+ case "row":
+ if(sourcePlugin._allDnDItemsLoaded()){
+ return res;
+ }
+ }
+ return false;
+ },
+ _allDnDItemsLoaded: function(){
+ if(this._dndRegion){
+ var type = this._dndRegion.type,
+ ranges = this._dndRegion.selected,
+ rows = [];
+ switch(type){
+ case "cell":
+ for(var i = ranges[0].min.row, max = ranges[0].max.row; i <= max; ++i){
+ rows.push(i);
+ }
+ break;
+ case "row":
+ rows = _joinToArray(ranges);
+ break;
+ default:
+ return false;
+ }
+ var cache = this.grid._by_idx;
+ return dojo.every(rows, function(rowIndex){
+ return !!cache[rowIndex];
+ });
+ }
+ return false;
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.GridDnDElement", null, {
+ constructor: function(dndPlugin){
+ this.plugin = dndPlugin;
+ this.node = dojo.create("div");
+ this._items = {};
+ },
+ destroy: function(){
+ this.plugin = null;
+ dojo.destroy(this.node);
+ this.node = null;
+ this._items = null;
+ },
+ createDnDNodes: function(dndRegion){
+ this.destroyDnDNodes();
+ var acceptType = ["grid/" + dndRegion.type + "s"];
+ var itemNodeIdBase = this.plugin.grid.id + "_dndItem";
+ dojo.forEach(dndRegion.selected, function(range, i){
+ var id = itemNodeIdBase + i;
+ this._items[id] = {
+ "type": acceptType,
+ "data": range,
+ "dndPlugin": this.plugin
+ };
+ this.node.appendChild(dojo.create("div", {
+ "id": id
+ }));
+ }, this);
+ },
+ getDnDNodes: function(){
+ return dojo.map(this.node.childNodes, function(node){
+ return node;
+ });
+ },
+ destroyDnDNodes: function(){
+ dojo.empty(this.node);
+ this._items = {};
+ },
+ getItem: function(nodeId){
+ return this._items[nodeId];
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.GridDnDSource",dojo.dnd.Source,{
+ accept: ["grid/cells", "grid/rows", "grid/cols"],
+ constructor: function(node, param){
+ this.grid = param.grid;
+ this.dndElem = param.dndElem;
+ this.dndPlugin = param.dnd;
+ this.sourcePlugin = null;
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ this.grid = null;
+ this.dndElem = null;
+ this.dndPlugin = null;
+ this.sourcePlugin = null;
+ },
+ getItem: function(nodeId){
+ return this.dndElem.getItem(nodeId);
+ },
+ checkAcceptance: function(source, nodes){
+ if(this != source && nodes[0]){
+ var item = source.getItem(nodes[0].id);
+ if(item.dndPlugin){
+ var type = item.type;
+ for(var j = 0; j < type.length; ++j){
+ if(type[j] in this.accept){
+ if(this.dndPlugin._canAccept(item.dndPlugin)){
+ this.sourcePlugin = item.dndPlugin;
+ }else{
+ return false;
+ }
+ break;
+ }
+ }
+ }else if("grid/rows" in this.accept){
+ var rows = [];
+ dojo.forEach(nodes, function(node){
+ var item = source.getItem(node.id);
+ if(item.data && dojo.indexOf(item.type, "grid/rows") >= 0){
+ var rowData = item.data;
+ if(typeof item.data == "string"){
+ rowData = dojo.fromJson(item.data);
+ }
+ if(rowData){
+ rows.push(rowData);
+ }
+ }
+ });
+ if(rows.length){
+ this.sourcePlugin = {
+ _dndRegion: {
+ type: "row",
+ selected: [rows]
+ }
+ };
+ }else{
+ return false;
+ }
+ }
+ }
+ return this.inherited(arguments);
+ },
+ onDraggingOver: function(){
+ this.dndPlugin.onDraggingOver(this.sourcePlugin);
+ },
+ onDraggingOut: function(){
+ this.dndPlugin.onDraggingOut(this.sourcePlugin);
+ },
+ onDndDrop: function(source, nodes, copy, target){
+ //this.inherited(arguments);
+ this.onDndCancel();
+ if(this != source && this == target){
+ this.dndPlugin.onDragIn(this.sourcePlugin, copy);
+ }
+ }
+});
+
+dojo.declare("dojox.grid.enhanced.plugins.GridDnDAvatar", dojo.dnd.Avatar, {
+ construct: function(){
+ // summary:
+ // constructor function;
+ // it is separate so it can be (dynamically) overwritten in case of need
+ this._itemType = this.manager._dndPlugin._dndRegion.type;
+ this._itemCount = this._getItemCount();
+
+ this.isA11y = dojo.hasClass(dojo.body(), "dijit_a11y");
+ var a = dojo.create("table", {
+ "border": "0",
+ "cellspacing": "0",
+ "class": "dojoxGridDndAvatar",
+ "style": {
+ position: "absolute",
+ zIndex: "1999",
+ margin: "0px"
+ }
+ }),
+ source = this.manager.source,
+ b = dojo.create("tbody", null, a),
+ tr = dojo.create("tr", null, b),
+ td = dojo.create("td", {
+ "class": "dojoxGridDnDIcon"
+ }, tr);
+ if(this.isA11y){
+ dojo.create("span", {
+ "id" : "a11yIcon",
+ "innerHTML" : this.manager.copy ? '+' : "<"
+ }, td);
+ }
+ td = dojo.create("td", {
+ "class" : "dojoxGridDnDItemIcon " + this._getGridDnDIconClass()
+ }, tr);
+ td = dojo.create("td", null, tr);
+ dojo.create("span", {
+ "class": "dojoxGridDnDItemCount",
+ "innerHTML": source.generateText ? this._generateText() : ""
+ }, td);
+ // we have to set the opacity on IE only after the node is live
+ dojo.style(tr, {
+ "opacity": 0.9
+ });
+ this.node = a;
+ },
+ _getItemCount: function(){
+ var selected = this.manager._dndPlugin._dndRegion.selected,
+ count = 0;
+ switch(this._itemType){
+ case "cell":
+ selected = selected[0];
+ var cells = this.manager._dndPlugin.grid.layout.cells,
+ colCount = selected.max.col - selected.min.col + 1,
+ rowCount = selected.max.row - selected.min.row + 1;
+ if(colCount > 1){
+ for(var i = selected.min.col; i <= selected.max.col; ++i){
+ if(cells[i].hidden){
+ --colCount;
+ }
+ }
+ }
+ count = colCount * rowCount;
+ break;
+ case "row":
+ case "col":
+ count = _joinToArray(selected).length;
+ }
+ return count;
+ },
+ _getGridDnDIconClass: function(){
+ return {
+ "row": ["dojoxGridDnDIconRowSingle", "dojoxGridDnDIconRowMulti"],
+ "col": ["dojoxGridDnDIconColSingle", "dojoxGridDnDIconColMulti"],
+ "cell": ["dojoxGridDnDIconCellSingle", "dojoxGridDnDIconCellMulti"]
+ }[this._itemType][this._itemCount == 1 ? 0 : 1];
+ },
+ _generateText: function(){
+ // summary:
+ // generates a proper text to reflect copying or moving of items
+ return "(" + this._itemCount + ")";
+ }
+});
+
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.DnD/*name:'dnd'*/, {
+ "dependency": ["selector", "rearrange"]
+});
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/DnD.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/DnD.xd.js
new file mode 100644
index 0000000..0bbb5a7
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/DnD.xd.js
@@ -0,0 +1,1094 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.DnD"],
+["require", "dojox.grid.enhanced._Plugin"],
+["require", "dojox.grid.enhanced.plugins.Selector"],
+["require", "dojox.grid.enhanced.plugins.Rearrange"],
+["require", "dojo.dnd.move"],
+["require", "dojo.dnd.Source"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.DnD"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.DnD"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.DnD");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid.enhanced.plugins.Selector");
+dojo.require("dojox.grid.enhanced.plugins.Rearrange");
+dojo.require("dojo.dnd.move");
+dojo.require("dojo.dnd.Source");
+
+(function(){
+var _devideToArrays = function(a){
+ a.sort(function(v1, v2){
+ return v1 - v2;
+ });
+ var arr = [[a[0]]];
+ for(var i = 1, j = 0; i < a.length; ++i){
+ if(a[i] == a[i-1] + 1){
+ arr[j].push(a[i]);
+ }else{
+ arr[++j] = [a[i]];
+ }
+ }
+ return arr;
+ },
+ _joinToArray = function(arrays){
+ var a = arrays[0];
+ for(var i = 1; i < arrays.length; ++i){
+ a = a.concat(arrays[i]);
+ }
+ return a;
+ };
+dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provide drag and drop for grid columns/rows/cells within grid and out of grid.
+ // The store of grid must implement dojo.data.api.Write.
+ // DnD selected columns:
+ // Support moving within grid, moving/copying out of grid to a non-grid DnD target.
+ // DnD selected rows:
+ // Support moving within grid, moving/copying out of grid to any DnD target.
+ // DnD selected cells (in rectangle shape only):
+ // Support moving/copying within grid, moving/copying out of grid to any DnD target.
+ //
+
+ // name: String,
+ // plugin name;
+ name: "dnd",
+
+ _targetAnchorBorderWidth: 2,
+ _copyOnly: false,
+ _config: {
+ "row":{
+ "within":true,
+ "in":true,
+ "out":true
+ },
+ "col":{
+ "within":true,
+ "in":true,
+ "out":true
+ },
+ "cell":{
+ "within":true,
+ "in":true,
+ "out":true
+ }
+ },
+ constructor: function(grid, args){
+ this.grid = grid;
+ this._config = dojo.clone(this._config);
+ args = dojo.isObject(args) ? args : {};
+ this.setupConfig(args.dndConfig);
+ this._copyOnly = !!args.copyOnly;
+
+ //Get the plugins we are dependent on.
+ this._mixinGrid();
+ this.selector = grid.pluginMgr.getPlugin("selector");
+ this.rearranger = grid.pluginMgr.getPlugin("rearrange");
+ //TODO: waiting for a better plugin framework to pass args to dependent plugins.
+ this.rearranger.setArgs(args);
+
+ //Initialized the components we need.
+ this._clear();
+ this._elem = new dojox.grid.enhanced.plugins.GridDnDElement(this);
+ this._source = new dojox.grid.enhanced.plugins.GridDnDSource(this._elem.node, {
+ "grid": grid,
+ "dndElem": this._elem,
+ "dnd": this
+ });
+ this._container = dojo.query(".dojoxGridMasterView", this.grid.domNode)[0];
+ this._initEvents();
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ this._clear();
+ this._source.destroy();
+ this._elem.destroy();
+ this._container = null;
+ this.grid = null;
+ this.selector = null;
+ this.rearranger = null;
+ this._config = null;
+ },
+ _mixinGrid: function(){
+ // summary:
+ // Provide APIs for grid.
+ this.grid.setupDnDConfig = dojo.hitch(this, "setupConfig");
+ this.grid.dndCopyOnly = dojo.hitch(this, "copyOnly");
+ },
+ setupConfig: function(config){
+ // summary:
+ // Configure which DnD functionalities are needed.
+ // Combination of any item from type set ("row", "col", "cell")
+ // and any item from mode set("within", "in", "out") is configurable.
+ //
+ // "row", "col", "cell" are straitforward, while the other 3 are explained below:
+ // "within": DnD within grid, that is, column/row reordering and cell moving/copying.
+ // "in": Whether allowed to accept rows/cells (currently not support columns) from another grid.
+ // "out": Whether allowed to drag out of grid, to another grid or even to any other DnD target.
+ //
+ // If not provided in the config, will use the default.
+ // When declared together, Mode set has higher priority than type set.
+ // config: Object
+ // DnD configuration object.
+ // See the examples below.
+ // example:
+ // The following code disables row DnD within grid,
+ // but still can drag rows out of grid or drag rows from other gird.
+ // | setUpConfig({
+ // | "row": {
+ // | "within": false
+ // | }
+ // | });
+ //
+ // The opposite way is also okay:
+ // | setUpConfig({
+ // | "within": {
+ // | "row": false
+ // | }
+ // | });
+ //
+ // And if you'd like to disable/enable a whole set, here's a shortcut:
+ // | setUpConfig({
+ // | "cell", true,
+ // | "out": false
+ // | });
+ //
+ // Because mode has higher priority than type, the following will disable row dnd within grid:
+ // | setUpConfig({
+ // | "within", {
+ // | "row": false;
+ // | },
+ // | "row", {
+ // | "within": true
+ // | }
+ // | });
+ if(config && dojo.isObject(config)){
+ var firstLevel = ["row", "col", "cell"],
+ secondLevel = ["within", "in", "out"],
+ cfg = this._config;
+ dojo.forEach(firstLevel, function(type){
+ if(type in config){
+ var t = config[type];
+ if(t && dojo.isObject(t)){
+ dojo.forEach(secondLevel, function(mode){
+ if(mode in t){
+ cfg[type][mode] = !!t[mode];
+ }
+ });
+ }else{
+ dojo.forEach(secondLevel, function(mode){
+ cfg[type][mode] = !!t;
+ });
+ }
+ }
+ });
+ dojo.forEach(secondLevel, function(mode){
+ if(mode in config){
+ var m = config[mode];
+ if(m && dojo.isObject(m)){
+ dojo.forEach(firstLevel, function(type){
+ if(type in m){
+ cfg[type][mode] = !!m[type];
+ }
+ });
+ }else{
+ dojo.forEach(firstLevel, function(type){
+ cfg[type][mode] = !!m;
+ });
+ }
+ }
+ });
+ }
+ },
+ copyOnly: function(isCopyOnly){
+ // summary:
+ // Setter/getter of this._copyOnly.
+ if(typeof isCopyOnly != "undefined"){
+ this._copyOnly = !!isCopyOnly;
+ }
+ return this._copyOnly;
+ },
+ _isOutOfGrid: function(evt){
+ var gridPos = dojo.position(this.grid.domNode), x = evt.clientX, y = evt.clientY;
+ return y < gridPos.y || y > gridPos.y + gridPos.h ||
+ x < gridPos.x || x > gridPos.x + gridPos.w;
+ },
+ _onMouseMove: function(evt){
+ if(this._dndRegion && !this._dnding && !this._externalDnd){
+ this._dnding = true;
+ this._startDnd(evt);
+ }else{
+ if(this._isMouseDown && !this._dndRegion){
+ delete this._isMouseDown;
+ this._oldCursor = dojo.style(dojo.body(), "cursor");
+ dojo.style(dojo.body(), "cursor", "not-allowed");
+ }
+ //TODO: should implement as mouseenter/mouseleave
+ //But we have an avatar under mouse when dnd, and this will cause a lot of mouseenter in FF.
+ var isOut = this._isOutOfGrid(evt);
+ if(!this._alreadyOut && isOut){
+ this._alreadyOut = true;
+ if(this._dnding){
+ this._destroyDnDUI(true, false);
+ }
+ this._moveEvent = evt;
+ this._source.onOutEvent();
+ }else if(this._alreadyOut && !isOut){
+ this._alreadyOut = false;
+ if(this._dnding){
+ this._createDnDUI(evt, true);
+ }
+ this._moveEvent = evt;
+ this._source.onOverEvent();
+ }
+ }
+ },
+ _onMouseUp: function(){
+ if(!this._extDnding && !this._isSource){
+ var isInner = this._dnding && !this._alreadyOut;
+ if(isInner && this._config[this._dndRegion.type]["within"]){
+ this._rearrange();
+ }
+ this._endDnd(isInner);
+ }
+ dojo.style(dojo.body(), "cursor", this._oldCursor || "");
+ delete this._isMouseDown;
+ },
+ _initEvents: function(){
+ var g = this.grid, s = this.selector;
+ this.connect(dojo.doc, "onmousemove", "_onMouseMove");
+ this.connect(dojo.doc, "onmouseup", "_onMouseUp");
+
+ this.connect(g, "onCellMouseOver", function(evt){
+ if(!this._dnding && !s.isSelecting() && !evt.ctrlKey){
+ this._dndReady = s.isSelected("cell", evt.rowIndex, evt.cell.index);
+ s.selectEnabled(!this._dndReady);
+ }
+ });
+ this.connect(g, "onHeaderCellMouseOver", function(evt){
+ if(this._dndReady){
+ s.selectEnabled(true);
+ }
+ });
+ this.connect(g, "onRowMouseOver", function(evt){
+ if(this._dndReady && !evt.cell){
+ s.selectEnabled(true);
+ }
+ });
+ this.connect(g, "onCellMouseDown", function(evt){
+ if(!evt.ctrlKey && this._dndReady){
+ this._dndRegion = this._getDnDRegion(evt.rowIndex, evt.cell.index);
+ this._isMouseDown = true;
+ }
+ });
+ this.connect(g, "onCellMouseUp", function(evt){
+ if(!this._dndReady && !s.isSelecting() && evt.cell){
+ this._dndReady = s.isSelected("cell", evt.rowIndex, evt.cell.index);
+ s.selectEnabled(!this._dndReady);
+ }
+ });
+ this.connect(g, "onCellClick", function(evt){
+ if(this._dndReady && !evt.ctrlKey && !evt.shiftKey){
+ s.select("cell", evt.rowIndex, evt.cell.index);
+ }
+ });
+ this.connect(g, "onEndAutoScroll", function(isVertical, isForward, view, target, evt){
+ if(this._dnding){
+ this._markTargetAnchor(evt);
+ }
+ });
+ this.connect(dojo.doc, "onkeydown", function(evt){
+ if(evt.keyCode == dojo.keys.ESCAPE){
+ this._endDnd(false);
+ }else if(evt.keyCode == dojo.keys.CTRL){
+ s.selectEnabled(true);
+ this._isCopy = true;
+ }
+ });
+ this.connect(dojo.doc, "onkeyup", function(evt){
+ if(evt.keyCode == dojo.keys.CTRL){
+ s.selectEnabled(!this._dndReady);
+ this._isCopy = false;
+ }
+ });
+ },
+ _clear: function(){
+ this._dndRegion = null;
+ this._target = null;
+ this._moveEvent = null;
+ this._targetAnchor = {};
+ this._dnding = false;
+ this._externalDnd = false;
+ this._isSource = false;
+ this._alreadyOut = false;
+ this._extDnding = false;
+ },
+ _getDnDRegion: function(rowIndex, colIndex){
+ var s = this.selector,
+ selected = s._selected,
+ flag = (!!selected.cell.length) | (!!selected.row.length << 1) | (!!selected.col.length << 2),
+ type;
+ switch(flag){
+ case 1:
+ type = "cell";
+ if(!this._config[type]["within"] && !this._config[type]["out"]){
+ return null;
+ }
+ var cells = this.grid.layout.cells,
+ getCount = function(range){
+ var hiddenColCnt = 0;
+ for(var i = range.min.col; i <= range.max.col; ++i){
+ if(cells[i].hidden){
+ ++hiddenColCnt;
+ }
+ }
+ return (range.max.row - range.min.row + 1) * (range.max.col - range.min.col + 1 - hiddenColCnt);
+ },
+ inRange = function(item, range){
+ return item.row >= range.min.row && item.row <= range.max.row &&
+ item.col >= range.min.col && item.col <= range.max.col;
+ },
+ range = {
+ max: {
+ row: -1,
+ col: -1
+ },
+ min: {
+ row: Infinity,
+ col: Infinity
+ }
+ };
+
+ dojo.forEach(selected[type], function(item){
+ if(item.row < range.min.row){
+ range.min.row = item.row;
+ }
+ if(item.row > range.max.row){
+ range.max.row = item.row;
+ }
+ if(item.col < range.min.col){
+ range.min.col = item.col;
+ }
+ if(item.col > range.max.col){
+ range.max.col = item.col;
+ }
+ });
+ if(dojo.some(selected[type], function(item){
+ return item.row == rowIndex && item.col == colIndex;
+ })){
+ if(getCount(range) == selected[type].length && dojo.every(selected[type], function(item){
+ return inRange(item, range);
+ })){
+ return {
+ "type": type,
+ "selected": [range],
+ "handle": {
+ "row": rowIndex,
+ "col": colIndex
+ }
+ };
+ }
+ }
+ return null;
+ case 2: case 4:
+ type = flag == 2 ? "row" : "col";
+ if(!this._config[type]["within"] && !this._config[type]["out"]){
+ return null;
+ }
+ var res = s.getSelected(type);
+ if(res.length){
+ return {
+ "type": type,
+ "selected": _devideToArrays(res),
+ "handle": flag == 2 ? rowIndex : colIndex
+ };
+ }
+ return null;
+ }
+ return null;
+ },
+ _startDnd: function(evt){
+ this._createDnDUI(evt);
+ },
+ _endDnd: function(destroySource){
+ this._destroyDnDUI(false, destroySource);
+ this._clear();
+ },
+ _createDnDUI: function(evt, isMovingIn){
+ //By default the master view of grid do not have height, because the children in it are all positioned absolutely.
+ //But we need it to contain avatars.
+ var viewPos = dojo.position(this.grid.views.views[0].domNode);
+ dojo.style(this._container, "height", viewPos.h + "px");
+ try{
+ //If moving in from out side, dnd source is already created.
+ if(!isMovingIn){
+ this._createSource(evt);
+ }
+ this._createMoveable(evt);
+ this._oldCursor = dojo.style(dojo.body(), "cursor");
+ dojo.style(dojo.body(), "cursor", "default");
+ }catch(e){
+ console.warn("DnD._createDnDUI() error:", e);
+ }
+ },
+ _destroyDnDUI: function(isMovingOut, destroySource){
+ try{
+ if(destroySource){
+ this._destroySource();
+ }
+ this._unmarkTargetAnchor();
+ if(!isMovingOut){
+ this._destroyMoveable();
+ }
+ dojo.style(dojo.body(), "cursor", this._oldCursor);
+ }catch(e){
+ console.warn("DnD._destroyDnDUI() error:", this.grid.id, e);
+ }
+ },
+ _createSource: function(evt){
+ this._elem.createDnDNodes(this._dndRegion);
+ var m = dojo.dnd.manager();
+ var oldMakeAvatar = m.makeAvatar;
+ m._dndPlugin = this;
+ m.makeAvatar = function(){
+ var avatar = new dojox.grid.enhanced.plugins.GridDnDAvatar(m);
+ delete m._dndPlugin;
+ return avatar;
+ };
+ m.startDrag(this._source, this._elem.getDnDNodes(), evt.ctrlKey);
+ m.makeAvatar = oldMakeAvatar;
+ m.onMouseMove(evt);
+ },
+ _destroySource: function(){
+ dojo.publish("/dnd/cancel");
+ this._elem.destroyDnDNodes();
+ },
+ _createMoveable: function(evt){
+ if(!this._markTagetAnchorHandler){
+ this._markTagetAnchorHandler = this.connect(dojo.doc, "onmousemove", "_markTargetAnchor");
+ }
+ },
+ _destroyMoveable: function(){
+ this.disconnect(this._markTagetAnchorHandler);
+ delete this._markTagetAnchorHandler;
+ },
+ _calcColTargetAnchorPos: function(evt, containerPos){
+ // summary:
+ // Calculate the position of the column DnD avatar
+ var i, headPos, left, target, ex = evt.clientX,
+ cells = this.grid.layout.cells,
+ ltr = dojo._isBodyLtr(),
+ headers = this._getVisibleHeaders();
+ for(i = 0; i < headers.length; ++i){
+ headPos = dojo.position(headers[i].node);
+ if(ltr ? ((i === 0 || ex >= headPos.x) && ex < headPos.x + headPos.w) :
+ ((i === 0 || ex < headPos.x + headPos.w) && ex >= headPos.x)){
+ left = headPos.x + (ltr ? 0 : headPos.w);
+ break;
+ }else if(ltr ? (i === headers.length - 1 && ex >= headPos.x + headPos.w) :
+ (i === headers.length - 1 && ex < headPos.x)){
+ ++i;
+ left = headPos.x + (ltr ? headPos.w : 0);
+ break;
+ }
+ }
+ if(i < headers.length){
+ target = headers[i].cell.index;
+ if(this.selector.isSelected("col", target) && this.selector.isSelected("col", target - 1)){
+ var ranges = this._dndRegion.selected;
+ for(i = 0; i < ranges.length; ++i){
+ if(dojo.indexOf(ranges[i], target) >= 0){
+ target = ranges[i][0];
+ headPos = dojo.position(cells[target].getHeaderNode());
+ left = headPos.x + (ltr ? 0 : headPos.w);
+ break;
+ }
+ }
+ }
+ }else{
+ target = cells.length;
+ }
+ this._target = target;
+ return left - containerPos.x;
+ },
+ _calcRowTargetAnchorPos: function(evt, containerPos){
+ // summary:
+ // Calculate the position of the row DnD avatar
+ var g = this.grid, top, i = 0,
+ cells = g.layout.cells;
+ while(cells[i].hidden){ ++i; }
+ var cell = g.layout.cells[i],
+ rowIndex = g.scroller.firstVisibleRow,
+ nodePos = dojo.position(cell.getNode(rowIndex));
+ while(nodePos.y + nodePos.h < evt.clientY){
+ if(++rowIndex >= g.rowCount){
+ break;
+ }
+ nodePos = dojo.position(cell.getNode(rowIndex));
+ }
+ if(rowIndex < g.rowCount){
+ if(this.selector.isSelected("row", rowIndex) && this.selector.isSelected("row", rowIndex - 1)){
+ var ranges = this._dndRegion.selected;
+ for(i = 0; i < ranges.length; ++i){
+ if(dojo.indexOf(ranges[i], rowIndex) >= 0){
+ rowIndex = ranges[i][0];
+ nodePos = dojo.position(cell.getNode(rowIndex));
+ break;
+ }
+ }
+ }
+ top = nodePos.y;
+ }else{
+ top = nodePos.y + nodePos.h;
+ }
+ this._target = rowIndex;
+ return top - containerPos.y;
+ },
+ _calcCellTargetAnchorPos: function(evt, containerPos, targetAnchor){
+ // summary:
+ // Calculate the position of the cell DnD avatar
+ var s = this._dndRegion.selected[0],
+ origin = this._dndRegion.handle,
+ g = this.grid, ltr = dojo._isBodyLtr(),
+ cells = g.layout.cells, headPos,
+ minPos, maxPos, headers,
+ height, width, left, top,
+ minCol, maxCol, i,
+ preSpan = origin.col - s.min.col,
+ postSpan = s.max.col - origin.col,
+ leftTopDiv, rightBottomDiv;
+ if(!targetAnchor.childNodes.length){
+ leftTopDiv = dojo.create("div", {
+ "class": "dojoxGridCellBorderLeftTopDIV"
+ }, targetAnchor);
+ rightBottomDiv = dojo.create("div", {
+ "class": "dojoxGridCellBorderRightBottomDIV"
+ }, targetAnchor);
+ }else{
+ leftTopDiv = dojo.query(".dojoxGridCellBorderLeftTopDIV", targetAnchor)[0];
+ rightBottomDiv = dojo.query(".dojoxGridCellBorderRightBottomDIV", targetAnchor)[0];
+ }
+ for(i = s.min.col + 1; i < origin.col; ++i){
+ if(cells[i].hidden){
+ --preSpan;
+ }
+ }
+ for(i = origin.col + 1; i < s.max.col; ++i){
+ if(cells[i].hidden){
+ --postSpan;
+ }
+ }
+ headers = this._getVisibleHeaders();
+ //calc width
+ for(i = preSpan; i < headers.length - postSpan; ++i){
+ headPos = dojo.position(headers[i].node);
+ if((evt.clientX >= headPos.x && evt.clientX < headPos.x + headPos.w) || //within in this column
+ //prior to this column, but within range
+ (i == preSpan && (ltr ? evt.clientX < headPos.x : evt.clientX >= headPos.x + headPos.w)) ||
+ //post to this column, but within range
+ (i == headers.length - postSpan - 1 && (ltr ? evt.clientX >= headPos.x + headPos.w : evt < headPos.x))){
+ minCol = headers[i - preSpan];
+ maxCol = headers[i + postSpan];
+ minPos = dojo.position(minCol.node);
+ maxPos = dojo.position(maxCol.node);
+ minCol = minCol.cell.index;
+ maxCol = maxCol.cell.index;
+ left = ltr ? minPos.x : maxPos.x;
+ width = ltr ? (maxPos.x + maxPos.w - minPos.x) : (minPos.x + minPos.w - maxPos.x);
+ break;
+ }
+ }
+ //calc height
+ i = 0;
+ while(cells[i].hidden){ ++i; }
+ var cell = cells[i],
+ rowIndex = g.scroller.firstVisibleRow,
+ nodePos = dojo.position(cell.getNode(rowIndex));
+ while(nodePos.y + nodePos.h < evt.clientY){
+ if(++rowIndex < g.rowCount){
+ nodePos = dojo.position(cell.getNode(rowIndex));
+ }else{
+ break;
+ }
+ }
+ var minRow = rowIndex >= origin.row - s.min.row ? rowIndex - origin.row + s.min.row : 0;
+ var maxRow = minRow + s.max.row - s.min.row;
+ if(maxRow >= g.rowCount){
+ maxRow = g.rowCount - 1;
+ minRow = maxRow - s.max.row + s.min.row;
+ }
+ minPos = dojo.position(cell.getNode(minRow));
+ maxPos = dojo.position(cell.getNode(maxRow));
+ top = minPos.y;
+ height = maxPos.y + maxPos.h - minPos.y;
+ this._target = {
+ "min":{
+ "row": minRow,
+ "col": minCol
+ },
+ "max":{
+ "row": maxRow,
+ "col": maxCol
+ }
+ };
+ var anchorBorderSize = (dojo.marginBox(leftTopDiv).w - dojo.contentBox(leftTopDiv).w) / 2;
+ var leftTopCellPos = dojo.position(cells[minCol].getNode(minRow));
+ dojo.style(leftTopDiv, {
+ "width": (leftTopCellPos.w - anchorBorderSize) + "px",
+ "height": (leftTopCellPos.h - anchorBorderSize) + "px"
+ });
+ var rightBottomCellPos = dojo.position(cells[maxCol].getNode(maxRow));
+ dojo.style(rightBottomDiv, {
+ "width": (rightBottomCellPos.w - anchorBorderSize) + "px",
+ "height": (rightBottomCellPos.h - anchorBorderSize) + "px"
+ });
+ return {
+ h: height,
+ w: width,
+ l: left - containerPos.x,
+ t: top - containerPos.y
+ };
+ },
+ _markTargetAnchor: function(evt){
+ try{
+ var t = this._dndRegion.type;
+ if(this._alreadyOut || (this._dnding && !this._config[t]["within"]) || (this._extDnding && !this._config[t]["in"])){
+ return;
+ }
+ var height, width, left, top,
+ targetAnchor = this._targetAnchor[t],
+ pos = dojo.position(this._container);
+ if(!targetAnchor){
+ targetAnchor = this._targetAnchor[t] = dojo.create("div", {
+ "class": (t == "cell") ? "dojoxGridCellBorderDIV" : "dojoxGridBorderDIV"
+ });
+ dojo.style(targetAnchor, "display", "none");
+ this._container.appendChild(targetAnchor);
+ }
+ switch(t){
+ case "col":
+ height = pos.h;
+ width = this._targetAnchorBorderWidth;
+ left = this._calcColTargetAnchorPos(evt, pos);
+ top = 0;
+ break;
+ case "row":
+ height = this._targetAnchorBorderWidth;
+ width = pos.w;
+ left = 0;
+ top = this._calcRowTargetAnchorPos(evt, pos);
+ break;
+ case "cell":
+ var cellPos = this._calcCellTargetAnchorPos(evt, pos, targetAnchor);
+ height = cellPos.h;
+ width = cellPos.w;
+ left = cellPos.l;
+ top = cellPos.t;
+ }
+ if(typeof height == "number" && typeof width == "number" && typeof left == "number" && typeof top == "number"){
+ dojo.style(targetAnchor, {
+ "height": height + "px",
+ "width": width + "px",
+ "left": left + "px",
+ "top": top + "px"
+ });
+ dojo.style(targetAnchor, "display", "");
+ }else{
+ this._target = null;
+ }
+ }catch(e){
+ console.warn("DnD._markTargetAnchor() error:",e);
+ }
+ },
+ _unmarkTargetAnchor: function(){
+ if(this._dndRegion){
+ var targetAnchor = this._targetAnchor[this._dndRegion.type];
+ if(targetAnchor){
+ dojo.style(this._targetAnchor[this._dndRegion.type], "display", "none");
+ }
+ }
+ },
+ _getVisibleHeaders: function(){
+ return dojo.map(dojo.filter(this.grid.layout.cells, function(cell){
+ return !cell.hidden;
+ }), function(cell){
+ return {
+ "node": cell.getHeaderNode(),
+ "cell": cell
+ };
+ });
+ },
+ _rearrange: function(){
+ if(this._target === null){
+ return;
+ }
+ var t = this._dndRegion.type;
+ var ranges = this._dndRegion.selected;
+ if(t === "cell"){
+ this.rearranger[(this._isCopy || this._copyOnly) ? "copyCells" : "moveCells"](ranges[0], this._target);
+ }else{
+ this.rearranger[t == "col" ? "moveColumns" : "moveRows"](_joinToArray(ranges), this._target);
+ }
+ this._target = null;
+ },
+ onDraggingOver: function(sourcePlugin){
+ if(!this._dnding && sourcePlugin){
+ sourcePlugin._isSource = true;
+ this._extDnding = true;
+ if(!this._externalDnd){
+ this._externalDnd = true;
+ this._dndRegion = this._mapRegion(sourcePlugin.grid, sourcePlugin._dndRegion);
+ }
+ this._createDnDUI(this._moveEvent,true);
+ this.grid.pluginMgr.getPlugin("autoScroll").readyForAutoScroll = true;
+ }
+ },
+ _mapRegion: function(srcGrid, dndRegion){
+ if(dndRegion.type === "cell"){
+ var srcRange = dndRegion.selected[0];
+ var cells = this.grid.layout.cells;
+ var srcCells = srcGrid.layout.cells;
+ var c, cnt = 0;
+ for(c = srcRange.min.col; c <= srcRange.max.col; ++c){
+ if(!srcCells[c].hidden){
+ ++cnt;
+ }
+ }
+ for(c = 0; cnt > 0; ++c){
+ if(!cells[c].hidden){
+ --cnt;
+ }
+ }
+ var region = dojo.clone(dndRegion);
+ region.selected[0].min.col = 0;
+ region.selected[0].max.col = c - 1;
+ for(c = srcRange.min.col; c <= dndRegion.handle.col; ++c){
+ if(!srcCells[c].hidden){
+ ++cnt;
+ }
+ }
+ for(c = 0; cnt > 0; ++c){
+ if(!cells[c].hidden){
+ --cnt;
+ }
+ }
+ region.handle.col = c;
+ }
+ return dndRegion;
+ },
+ onDraggingOut: function(sourcePlugin){
+ if(this._externalDnd){
+ this._extDnding = false;
+ this._destroyDnDUI(true, false);
+ if(sourcePlugin){
+ sourcePlugin._isSource = false;
+ }
+ }
+ },
+ onDragIn: function(sourcePlugin, isCopy){
+ var success = false;
+ if(this._target !== null){
+ var type = sourcePlugin._dndRegion.type;
+ var ranges = sourcePlugin._dndRegion.selected;
+ switch(type){
+ case "cell":
+ this.rearranger.changeCells(sourcePlugin.grid, ranges[0], this._target);
+ break;
+ case "row":
+ var range = _joinToArray(ranges);
+ this.rearranger.insertRows(sourcePlugin.grid, range, this._target);
+ break;
+ }
+ success = true;
+ }
+ this._endDnd(true);
+ if(sourcePlugin.onDragOut){
+ sourcePlugin.onDragOut(success && !isCopy);
+ }
+ },
+ onDragOut: function(isMove){
+ if(isMove && !this._copyOnly){
+ var type = this._dndRegion.type;
+ var ranges = this._dndRegion.selected;
+ switch(type){
+ case "cell":
+ this.rearranger.clearCells(ranges[0]);
+ break;
+ case "row":
+ this.rearranger.removeRows(_joinToArray(ranges));
+ break;
+ }
+ }
+ this._endDnd(true);
+ },
+ _canAccept: function(sourcePlugin){
+ if(!sourcePlugin){
+ return false;
+ }
+ var srcRegion = sourcePlugin._dndRegion;
+ var type = srcRegion.type;
+ if(!this._config[type]["in"] || !sourcePlugin._config[type]["out"]){
+ return false;
+ }
+ var g = this.grid;
+ var ranges = srcRegion.selected;
+ var colCnt = dojo.filter(g.layout.cells, function(cell){
+ return !cell.hidden;
+ }).length;
+ var rowCnt = g.rowCount;
+ var res = true;
+ switch(type){
+ case "cell":
+ ranges = ranges[0];
+ res = g.store.getFeatures()["dojo.data.api.Write"] &&
+ (ranges.max.row - ranges.min.row) <= rowCnt &&
+ dojo.filter(sourcePlugin.grid.layout.cells, function(cell){
+ return cell.index >= ranges.min.col && cell.index <= ranges.max.col && !cell.hidden;
+ }).length <= colCnt;
+ //intentional drop through - don't break
+ case "row":
+ if(sourcePlugin._allDnDItemsLoaded()){
+ return res;
+ }
+ }
+ return false;
+ },
+ _allDnDItemsLoaded: function(){
+ if(this._dndRegion){
+ var type = this._dndRegion.type,
+ ranges = this._dndRegion.selected,
+ rows = [];
+ switch(type){
+ case "cell":
+ for(var i = ranges[0].min.row, max = ranges[0].max.row; i <= max; ++i){
+ rows.push(i);
+ }
+ break;
+ case "row":
+ rows = _joinToArray(ranges);
+ break;
+ default:
+ return false;
+ }
+ var cache = this.grid._by_idx;
+ return dojo.every(rows, function(rowIndex){
+ return !!cache[rowIndex];
+ });
+ }
+ return false;
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.GridDnDElement", null, {
+ constructor: function(dndPlugin){
+ this.plugin = dndPlugin;
+ this.node = dojo.create("div");
+ this._items = {};
+ },
+ destroy: function(){
+ this.plugin = null;
+ dojo.destroy(this.node);
+ this.node = null;
+ this._items = null;
+ },
+ createDnDNodes: function(dndRegion){
+ this.destroyDnDNodes();
+ var acceptType = ["grid/" + dndRegion.type + "s"];
+ var itemNodeIdBase = this.plugin.grid.id + "_dndItem";
+ dojo.forEach(dndRegion.selected, function(range, i){
+ var id = itemNodeIdBase + i;
+ this._items[id] = {
+ "type": acceptType,
+ "data": range,
+ "dndPlugin": this.plugin
+ };
+ this.node.appendChild(dojo.create("div", {
+ "id": id
+ }));
+ }, this);
+ },
+ getDnDNodes: function(){
+ return dojo.map(this.node.childNodes, function(node){
+ return node;
+ });
+ },
+ destroyDnDNodes: function(){
+ dojo.empty(this.node);
+ this._items = {};
+ },
+ getItem: function(nodeId){
+ return this._items[nodeId];
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.GridDnDSource",dojo.dnd.Source,{
+ accept: ["grid/cells", "grid/rows", "grid/cols"],
+ constructor: function(node, param){
+ this.grid = param.grid;
+ this.dndElem = param.dndElem;
+ this.dndPlugin = param.dnd;
+ this.sourcePlugin = null;
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ this.grid = null;
+ this.dndElem = null;
+ this.dndPlugin = null;
+ this.sourcePlugin = null;
+ },
+ getItem: function(nodeId){
+ return this.dndElem.getItem(nodeId);
+ },
+ checkAcceptance: function(source, nodes){
+ if(this != source && nodes[0]){
+ var item = source.getItem(nodes[0].id);
+ if(item.dndPlugin){
+ var type = item.type;
+ for(var j = 0; j < type.length; ++j){
+ if(type[j] in this.accept){
+ if(this.dndPlugin._canAccept(item.dndPlugin)){
+ this.sourcePlugin = item.dndPlugin;
+ }else{
+ return false;
+ }
+ break;
+ }
+ }
+ }else if("grid/rows" in this.accept){
+ var rows = [];
+ dojo.forEach(nodes, function(node){
+ var item = source.getItem(node.id);
+ if(item.data && dojo.indexOf(item.type, "grid/rows") >= 0){
+ var rowData = item.data;
+ if(typeof item.data == "string"){
+ rowData = dojo.fromJson(item.data);
+ }
+ if(rowData){
+ rows.push(rowData);
+ }
+ }
+ });
+ if(rows.length){
+ this.sourcePlugin = {
+ _dndRegion: {
+ type: "row",
+ selected: [rows]
+ }
+ };
+ }else{
+ return false;
+ }
+ }
+ }
+ return this.inherited(arguments);
+ },
+ onDraggingOver: function(){
+ this.dndPlugin.onDraggingOver(this.sourcePlugin);
+ },
+ onDraggingOut: function(){
+ this.dndPlugin.onDraggingOut(this.sourcePlugin);
+ },
+ onDndDrop: function(source, nodes, copy, target){
+ //this.inherited(arguments);
+ this.onDndCancel();
+ if(this != source && this == target){
+ this.dndPlugin.onDragIn(this.sourcePlugin, copy);
+ }
+ }
+});
+
+dojo.declare("dojox.grid.enhanced.plugins.GridDnDAvatar", dojo.dnd.Avatar, {
+ construct: function(){
+ // summary:
+ // constructor function;
+ // it is separate so it can be (dynamically) overwritten in case of need
+ this._itemType = this.manager._dndPlugin._dndRegion.type;
+ this._itemCount = this._getItemCount();
+
+ this.isA11y = dojo.hasClass(dojo.body(), "dijit_a11y");
+ var a = dojo.create("table", {
+ "border": "0",
+ "cellspacing": "0",
+ "class": "dojoxGridDndAvatar",
+ "style": {
+ position: "absolute",
+ zIndex: "1999",
+ margin: "0px"
+ }
+ }),
+ source = this.manager.source,
+ b = dojo.create("tbody", null, a),
+ tr = dojo.create("tr", null, b),
+ td = dojo.create("td", {
+ "class": "dojoxGridDnDIcon"
+ }, tr);
+ if(this.isA11y){
+ dojo.create("span", {
+ "id" : "a11yIcon",
+ "innerHTML" : this.manager.copy ? '+' : "<"
+ }, td);
+ }
+ td = dojo.create("td", {
+ "class" : "dojoxGridDnDItemIcon " + this._getGridDnDIconClass()
+ }, tr);
+ td = dojo.create("td", null, tr);
+ dojo.create("span", {
+ "class": "dojoxGridDnDItemCount",
+ "innerHTML": source.generateText ? this._generateText() : ""
+ }, td);
+ // we have to set the opacity on IE only after the node is live
+ dojo.style(tr, {
+ "opacity": 0.9
+ });
+ this.node = a;
+ },
+ _getItemCount: function(){
+ var selected = this.manager._dndPlugin._dndRegion.selected,
+ count = 0;
+ switch(this._itemType){
+ case "cell":
+ selected = selected[0];
+ var cells = this.manager._dndPlugin.grid.layout.cells,
+ colCount = selected.max.col - selected.min.col + 1,
+ rowCount = selected.max.row - selected.min.row + 1;
+ if(colCount > 1){
+ for(var i = selected.min.col; i <= selected.max.col; ++i){
+ if(cells[i].hidden){
+ --colCount;
+ }
+ }
+ }
+ count = colCount * rowCount;
+ break;
+ case "row":
+ case "col":
+ count = _joinToArray(selected).length;
+ }
+ return count;
+ },
+ _getGridDnDIconClass: function(){
+ return {
+ "row": ["dojoxGridDnDIconRowSingle", "dojoxGridDnDIconRowMulti"],
+ "col": ["dojoxGridDnDIconColSingle", "dojoxGridDnDIconColMulti"],
+ "cell": ["dojoxGridDnDIconCellSingle", "dojoxGridDnDIconCellMulti"]
+ }[this._itemType][this._itemCount == 1 ? 0 : 1];
+ },
+ _generateText: function(){
+ // summary:
+ // generates a proper text to reflect copying or moving of items
+ return "(" + this._itemCount + ")";
+ }
+});
+
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.DnD/*name:'dnd'*/, {
+ "dependency": ["selector", "rearrange"]
+});
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Exporter.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Exporter.js
new file mode 100644
index 0000000..5b2c164
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Exporter.js
@@ -0,0 +1,242 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.Exporter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Exporter"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Exporter");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid._RowSelector");
+
+dojo.declare("dojox.grid.enhanced.plugins.Exporter", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provide functions to export the grid data into a given format.
+ //
+ // Acceptable plugin parameters:
+ // 1. exportFormatter: function(data, cell, rowIndex, item)
+ // Provide a way to customize how data should look in exported string.
+ // Note that usually the formatter of grid cell should not be used here (it can return HTML or even widget).
+ // example:
+ // | function onExported(exported_text){
+ // | //custom code here...
+ // | }
+ // | dijit.byId("my_grid_id").exportTo("csv", //registered export format, mandatory
+ // | { //the whole object is optional.
+ // | fetchArgs: {start:0,count:1000}, //keywordArgs for fetch, optional
+ // | writerArgs: {separator:';'}, //export writer specific arguments, optional
+ // | },
+ // | function(str){
+ // | //call back function, mandatory
+ // | });
+ // | var result = dijit.byId("my_grid_id").exportSelectedTo("table", //registered export format, mandatory
+ // | {separator:'|'} //export writer specific arguments, optional
+ // | );
+ //
+
+ // name: String
+ // Plugin name.
+ name: "exporter",
+
+ constructor: function(grid, args){
+ // summary:
+ // only newed by _Plugin
+ // grid: EnhancedGrid
+ // The grid to plug in to.
+ this.grid = grid;
+ this.formatter = (args && dojo.isObject(args)) && args.exportFormatter;
+ this._mixinGrid();
+ },
+ _mixinGrid: function(){
+ var g = this.grid;
+ g.exportTo = dojo.hitch(this, this.exportTo);
+ g.exportGrid = dojo.hitch(this, this.exportGrid);
+ g.exportSelected = dojo.hitch(this, this.exportSelected);
+ g.setExportFormatter = dojo.hitch(this, this.setExportFormatter);
+ },
+ setExportFormatter: function(formatter){
+ this.formatter = formatter;
+ },
+ exportGrid: function(type, args, onExported){
+ // summary:
+ // Export required rows(fetchArgs) to a kind of format(type)
+ // using the corresponding writer with given arguments(writerArgs),
+ // then pass the exported text to a given function(onExported).
+ // tags:
+ // public
+ // type: string
+ // A registered export format name
+ // args: object?
+ // includes:
+ // {
+ // fetchArgs: object?
+ // Any arguments for store.fetch
+ // writerArgs: object?
+ // Arguments for the given format writer
+ // }
+ // onExported: function(string)
+ // Call back function when export result is ready
+ if(dojo.isFunction(args)){
+ onExported = args;
+ args = {};
+ }
+ if(!dojo.isString(type) || !dojo.isFunction(onExported)){
+ return;
+ }
+ args = args || {};
+ var g = this.grid, _this = this,
+ writer = this._getExportWriter(type, args.writerArgs),
+ fetchArgs = (args.fetchArgs && dojo.isObject(args.fetchArgs)) ? args.fetchArgs : {},
+ oldFunc = fetchArgs.onComplete;
+ if(g.store){
+ fetchArgs.onComplete = function(items, request){
+ if(oldFunc){
+ oldFunc(items, request);
+ }
+ onExported(_this._goThroughGridData(items, writer));
+ };
+ fetchArgs.sort = fetchArgs.sort || g.getSortProps();
+ g._storeLayerFetch(fetchArgs);
+ }else{
+ //Data is defined directly in the structure;
+ var start = fetchArgs.start || 0,
+ count = fetchArgs.count || -1,
+ items = [];
+ for(var i = start; i != start + count && i < g.rowCount; ++i){
+ items.push(g.getItem(i));
+ }
+ onExported(this._goThroughGridData(items, writer));
+ }
+ },
+ exportSelected: function(type, writerArgs){
+ // summary:
+ // Only export selected rows.
+ // tags:
+ // public
+ // type: string
+ // A registered export format name
+ // writerArgs: object?
+ // Arguments for the given format writer
+ // returns: string
+ // The exported string
+ if(!dojo.isString(type)){
+ return "";
+ }
+ var writer = this._getExportWriter(type, writerArgs);
+ return this._goThroughGridData(this.grid.selection.getSelected(), writer); //String
+ },
+ _buildRow: function(/* object */arg_obj,/* ExportWriter */writer){
+ // summary:
+ // Use the given export writer(writer) to go through a single row
+ // which is given in the context object(arg_obj).
+ // tags:
+ // private
+ // returns:
+ // undefined
+ var _this = this;
+ dojo.forEach(arg_obj._views, function(view, vIdx){
+ arg_obj.view = view;
+ arg_obj.viewIdx = vIdx;
+ if(writer.beforeView(arg_obj)){
+ dojo.forEach(view.structure.cells, function(subrow, srIdx){
+ arg_obj.subrow = subrow;
+ arg_obj.subrowIdx = srIdx;
+ if(writer.beforeSubrow(arg_obj)){
+ dojo.forEach(subrow, function(cell, cIdx){
+ if(arg_obj.isHeader && _this._isSpecialCol(cell)){
+ arg_obj.spCols.push(cell.index);
+ }
+ arg_obj.cell = cell;
+ arg_obj.cellIdx = cIdx;
+ writer.handleCell(arg_obj);
+ });
+ writer.afterSubrow(arg_obj);
+ }
+ });
+ writer.afterView(arg_obj);
+ }
+ });
+ },
+ _goThroughGridData: function(/* Array */items,/* ExportWriter */writer){
+ // summary:
+ // Use the given export writer(writer) to go through the grid structure
+ // and the given rows(items), then return the writer output.
+ // tags:
+ // private
+ var grid = this.grid,
+ views = dojo.filter(grid.views.views, function(view){
+ return !(view instanceof dojox.grid._RowSelector);
+ }),
+ arg_obj = {
+ 'grid': grid,
+ 'isHeader': true,
+ 'spCols': [],
+ '_views': views,
+ 'colOffset': (views.length < grid.views.views.length ? -1 : 0)
+ };
+ //go through header
+ if(writer.beforeHeader(grid)){
+ this._buildRow(arg_obj,writer);
+ writer.afterHeader();
+ }
+ //go through content
+ arg_obj.isHeader = false;
+ if(writer.beforeContent(items)){
+ dojo.forEach(items, function(item, rIdx){
+ arg_obj.row = item;
+ arg_obj.rowIdx = rIdx;
+ if(writer.beforeContentRow(arg_obj)){
+ this._buildRow(arg_obj, writer);
+ writer.afterContentRow(arg_obj);
+ }
+ }, this);
+ writer.afterContent();
+ }
+ return writer.toString();
+ },
+ _isSpecialCol: function(/* dojox.grid.__CellDef */header_cell){
+ // summary:
+ // Row selectors and row indexes should be recognized and handled separately.
+ // tags:
+ // private
+ return header_cell.isRowSelector || header_cell instanceof dojox.grid.cells.RowIndex; //Boolean
+ },
+ _getExportWriter: function(/* string */ fileType, /* object? */ writerArgs){
+ // summary:
+ // Use the given export format type(fileType)
+ // and writer arguments(writerArgs) to create
+ // a ExportWriter and return it.
+ // tags:
+ // private
+ var writerName, cls,
+ expCls = dojox.grid.enhanced.plugins.Exporter;
+ if(expCls.writerNames){
+ writerName = expCls.writerNames[fileType.toLowerCase()];
+ cls = dojo.getObject(writerName);
+ if(cls){
+ var writer = new cls(writerArgs);
+ writer.formatter = this.formatter;
+ return writer; //ExportWriter
+ }else{
+ throw new Error('Please make sure class "' + writerName + '" is required.');
+ }
+ }
+ throw new Error('The writer for "' + fileType + '" has not been registered.');
+ }
+});
+dojox.grid.enhanced.plugins.Exporter.registerWriter = function(/* string */fileType,/* string */writerClsName){
+ // summary:
+ // Register a writer(writerClsName) to a export format type(fileType).
+ // This function separates the Exporter from all kinds of writers.
+ // tags:
+ // public
+ var expCls = dojox.grid.enhanced.plugins.Exporter;
+ expCls.writerNames = expCls.writerNames || {};
+ expCls.writerNames[fileType] = writerClsName;
+};
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Exporter/*name:'exporter'*/);
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Exporter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Exporter.xd.js
new file mode 100644
index 0000000..dd254e0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Exporter.xd.js
@@ -0,0 +1,248 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.Exporter"],
+["require", "dojox.grid.enhanced._Plugin"],
+["require", "dojox.grid._RowSelector"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.Exporter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Exporter"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Exporter");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid._RowSelector");
+
+dojo.declare("dojox.grid.enhanced.plugins.Exporter", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provide functions to export the grid data into a given format.
+ //
+ // Acceptable plugin parameters:
+ // 1. exportFormatter: function(data, cell, rowIndex, item)
+ // Provide a way to customize how data should look in exported string.
+ // Note that usually the formatter of grid cell should not be used here (it can return HTML or even widget).
+ // example:
+ // | function onExported(exported_text){
+ // | //custom code here...
+ // | }
+ // | dijit.byId("my_grid_id").exportTo("csv", //registered export format, mandatory
+ // | { //the whole object is optional.
+ // | fetchArgs: {start:0,count:1000}, //keywordArgs for fetch, optional
+ // | writerArgs: {separator:';'}, //export writer specific arguments, optional
+ // | },
+ // | function(str){
+ // | //call back function, mandatory
+ // | });
+ // | var result = dijit.byId("my_grid_id").exportSelectedTo("table", //registered export format, mandatory
+ // | {separator:'|'} //export writer specific arguments, optional
+ // | );
+ //
+
+ // name: String
+ // Plugin name.
+ name: "exporter",
+
+ constructor: function(grid, args){
+ // summary:
+ // only newed by _Plugin
+ // grid: EnhancedGrid
+ // The grid to plug in to.
+ this.grid = grid;
+ this.formatter = (args && dojo.isObject(args)) && args.exportFormatter;
+ this._mixinGrid();
+ },
+ _mixinGrid: function(){
+ var g = this.grid;
+ g.exportTo = dojo.hitch(this, this.exportTo);
+ g.exportGrid = dojo.hitch(this, this.exportGrid);
+ g.exportSelected = dojo.hitch(this, this.exportSelected);
+ g.setExportFormatter = dojo.hitch(this, this.setExportFormatter);
+ },
+ setExportFormatter: function(formatter){
+ this.formatter = formatter;
+ },
+ exportGrid: function(type, args, onExported){
+ // summary:
+ // Export required rows(fetchArgs) to a kind of format(type)
+ // using the corresponding writer with given arguments(writerArgs),
+ // then pass the exported text to a given function(onExported).
+ // tags:
+ // public
+ // type: string
+ // A registered export format name
+ // args: object?
+ // includes:
+ // {
+ // fetchArgs: object?
+ // Any arguments for store.fetch
+ // writerArgs: object?
+ // Arguments for the given format writer
+ // }
+ // onExported: function(string)
+ // Call back function when export result is ready
+ if(dojo.isFunction(args)){
+ onExported = args;
+ args = {};
+ }
+ if(!dojo.isString(type) || !dojo.isFunction(onExported)){
+ return;
+ }
+ args = args || {};
+ var g = this.grid, _this = this,
+ writer = this._getExportWriter(type, args.writerArgs),
+ fetchArgs = (args.fetchArgs && dojo.isObject(args.fetchArgs)) ? args.fetchArgs : {},
+ oldFunc = fetchArgs.onComplete;
+ if(g.store){
+ fetchArgs.onComplete = function(items, request){
+ if(oldFunc){
+ oldFunc(items, request);
+ }
+ onExported(_this._goThroughGridData(items, writer));
+ };
+ fetchArgs.sort = fetchArgs.sort || g.getSortProps();
+ g._storeLayerFetch(fetchArgs);
+ }else{
+ //Data is defined directly in the structure;
+ var start = fetchArgs.start || 0,
+ count = fetchArgs.count || -1,
+ items = [];
+ for(var i = start; i != start + count && i < g.rowCount; ++i){
+ items.push(g.getItem(i));
+ }
+ onExported(this._goThroughGridData(items, writer));
+ }
+ },
+ exportSelected: function(type, writerArgs){
+ // summary:
+ // Only export selected rows.
+ // tags:
+ // public
+ // type: string
+ // A registered export format name
+ // writerArgs: object?
+ // Arguments for the given format writer
+ // returns: string
+ // The exported string
+ if(!dojo.isString(type)){
+ return "";
+ }
+ var writer = this._getExportWriter(type, writerArgs);
+ return this._goThroughGridData(this.grid.selection.getSelected(), writer); //String
+ },
+ _buildRow: function(/* object */arg_obj,/* ExportWriter */writer){
+ // summary:
+ // Use the given export writer(writer) to go through a single row
+ // which is given in the context object(arg_obj).
+ // tags:
+ // private
+ // returns:
+ // undefined
+ var _this = this;
+ dojo.forEach(arg_obj._views, function(view, vIdx){
+ arg_obj.view = view;
+ arg_obj.viewIdx = vIdx;
+ if(writer.beforeView(arg_obj)){
+ dojo.forEach(view.structure.cells, function(subrow, srIdx){
+ arg_obj.subrow = subrow;
+ arg_obj.subrowIdx = srIdx;
+ if(writer.beforeSubrow(arg_obj)){
+ dojo.forEach(subrow, function(cell, cIdx){
+ if(arg_obj.isHeader && _this._isSpecialCol(cell)){
+ arg_obj.spCols.push(cell.index);
+ }
+ arg_obj.cell = cell;
+ arg_obj.cellIdx = cIdx;
+ writer.handleCell(arg_obj);
+ });
+ writer.afterSubrow(arg_obj);
+ }
+ });
+ writer.afterView(arg_obj);
+ }
+ });
+ },
+ _goThroughGridData: function(/* Array */items,/* ExportWriter */writer){
+ // summary:
+ // Use the given export writer(writer) to go through the grid structure
+ // and the given rows(items), then return the writer output.
+ // tags:
+ // private
+ var grid = this.grid,
+ views = dojo.filter(grid.views.views, function(view){
+ return !(view instanceof dojox.grid._RowSelector);
+ }),
+ arg_obj = {
+ 'grid': grid,
+ 'isHeader': true,
+ 'spCols': [],
+ '_views': views,
+ 'colOffset': (views.length < grid.views.views.length ? -1 : 0)
+ };
+ //go through header
+ if(writer.beforeHeader(grid)){
+ this._buildRow(arg_obj,writer);
+ writer.afterHeader();
+ }
+ //go through content
+ arg_obj.isHeader = false;
+ if(writer.beforeContent(items)){
+ dojo.forEach(items, function(item, rIdx){
+ arg_obj.row = item;
+ arg_obj.rowIdx = rIdx;
+ if(writer.beforeContentRow(arg_obj)){
+ this._buildRow(arg_obj, writer);
+ writer.afterContentRow(arg_obj);
+ }
+ }, this);
+ writer.afterContent();
+ }
+ return writer.toString();
+ },
+ _isSpecialCol: function(/* dojox.grid.__CellDef */header_cell){
+ // summary:
+ // Row selectors and row indexes should be recognized and handled separately.
+ // tags:
+ // private
+ return header_cell.isRowSelector || header_cell instanceof dojox.grid.cells.RowIndex; //Boolean
+ },
+ _getExportWriter: function(/* string */ fileType, /* object? */ writerArgs){
+ // summary:
+ // Use the given export format type(fileType)
+ // and writer arguments(writerArgs) to create
+ // a ExportWriter and return it.
+ // tags:
+ // private
+ var writerName, cls,
+ expCls = dojox.grid.enhanced.plugins.Exporter;
+ if(expCls.writerNames){
+ writerName = expCls.writerNames[fileType.toLowerCase()];
+ cls = dojo.getObject(writerName);
+ if(cls){
+ var writer = new cls(writerArgs);
+ writer.formatter = this.formatter;
+ return writer; //ExportWriter
+ }else{
+ throw new Error('Please make sure class "' + writerName + '" is required.');
+ }
+ }
+ throw new Error('The writer for "' + fileType + '" has not been registered.');
+ }
+});
+dojox.grid.enhanced.plugins.Exporter.registerWriter = function(/* string */fileType,/* string */writerClsName){
+ // summary:
+ // Register a writer(writerClsName) to a export format type(fileType).
+ // This function separates the Exporter from all kinds of writers.
+ // tags:
+ // public
+ var expCls = dojox.grid.enhanced.plugins.Exporter;
+ expCls.writerNames = expCls.writerNames || {};
+ expCls.writerNames[fileType] = writerClsName;
+};
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Exporter/*name:'exporter'*/);
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Filter.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Filter.js
new file mode 100644
index 0000000..ea87100
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Filter.js
@@ -0,0 +1,171 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.Filter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Filter"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Filter");
+
+dojo.requireLocalization("dojox.grid.enhanced", "Filter", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ru,sl,sv,th,tr,zh,zh-tw");
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid.enhanced.plugins.Dialog");
+dojo.require("dojox.grid.enhanced.plugins.filter.FilterLayer");
+dojo.require("dojox.grid.enhanced.plugins.filter.FilterBar");
+dojo.require("dojox.grid.enhanced.plugins.filter.FilterDefDialog");
+dojo.require("dojox.grid.enhanced.plugins.filter.FilterStatusTip");
+dojo.require("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm");
+
+(function(){
+ var ns = dojox.grid.enhanced.plugins,
+ fns = ns.filter;
+
+ dojo.declare("dojox.grid.enhanced.plugins.Filter", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provide filter functionality for grid.
+ //
+ // Acceptable plugin parameters:
+ // 1. itemsName: string
+ // the name shown on the filter bar.
+ // 2. statusTipTimeout: number
+ // when does the status tip show.
+ // 3. ruleCount: number
+ // default to 3, should not change to more. The Claro theme limits it.
+ // 4. disabledConditions: object
+ // If you don't need all of the conditions provided for a data type,
+ // you can explicitly declare them here:
+ // e.g.: disabledConditions: {string: ["contains", "is"], number: ["equalto"], ...}
+ // 5. isServerSide: boolean
+ // Whether to use server side filtering. Default to false.
+ // 6. isStateful: boolean
+ // If isServerSide is true, set the server side filter to be stateful or not. default to false.
+ // 7. url: string
+ // If using stateful, this is the url to send commands. default to store.url.
+ //
+ // Acceptable cell parameters defined in layout:
+ // 1. filterable: boolean
+ // The column is not filterable only when this is set to false explicitly.
+ // 2. datatype: string
+ // The data type of this column. Can be "string", "number", "date", "time", "boolean".
+ // Default to "string".
+ // 3. autoComplete: boolean
+ // If need auto-complete in the ComboBox for String type, set this to true.
+ // 4. dataTypeArgs: object
+ // Some arguments helping convert store data to something the filter UI understands.
+ // Different data type arguments can be provided to different data types.
+ // For date/time, this is a dojo.date.locale.__FormatOptions, so the DataTimeBox can understand the store data.
+ // For boolean, this object contains:
+ // trueLabel: string
+ // A label to display in the filter definition dialog for true value. Default to "True".
+ // falseLable: string
+ // A label to display in the filter definition dialog for false value. Default to "False".
+ // 5. disabledConditions: object
+ // If you don't need all of the conditions provided by the filter UI on this column, you can explicitly say it out here.
+ // e.g.: disabledConditions: ["contains", "is"]
+ // This will disable the "contains" condition for this column, if this column is of string type.
+ // For full set of conditions, please refer to dojox.grid.enhanced.plugins.filter.FilterDefDialog._setupData.
+ // example:
+ // | <div dojoType="dojox.grid.EnhancedGrid" plugins="{GridFilter: true}" ...></div>
+ // | or provide some parameters:
+ // | <div dojoType="dojox.grid.EnhancedGrid" plugins="{GridFilter: {itemsName: 'songs'}}" ...></div>
+ // | Customize columns for filter:
+ // | var layout = [
+ // | ...
+ // | //define a column to be un-filterable in layout/structure
+ // | {field: "Genre", filterable: false, ...}
+ // | //define a column of type string and supports autoComplete when you type in filter conditions.
+ // | {field: "Writer", datatype: "string", autoCommplete: true, ...}
+ // | //define a column of type date and the data in store has format: "yyyy/M/d"
+ // | {field: "Publish Date", datatype: "date", dataTypeArgs: {datePattern: "yyyy/M/d"}, ...}
+ // | //disable some conditions for a column
+ // | {field: "Track", disabledConditions: ["equalto","notequalto"], ...}
+ // | ...
+ // | ];
+
+ // name: String
+ // plugin name
+ name: "filter",
+
+ constructor: function(grid, args){
+ // summary:
+ // See constructor of dojox.grid.enhanced._Plugin.
+ this.grid = grid;
+ this.nls = dojo.i18n.getLocalization("dojox.grid.enhanced", "Filter");
+
+ args = this.args = dojo.isObject(args) ? args : {};
+ if(typeof args.ruleCount != 'number' || args.ruleCount < 0){
+ args.ruleCount = 3;
+ }
+
+ //Install filter layer
+ this._wrapStore();
+
+ //Install UI components
+ var obj = { "plugin": this };
+ this.clearFilterDialog = new dojox.grid.enhanced.plugins.Dialog({
+ refNode: this.grid.domNode,
+ title: this.nls["clearFilterDialogTitle"],
+ content: new fns.ClearFilterConfirm(obj)
+ });
+ this.filterDefDialog = new fns.FilterDefDialog(obj);
+ this.filterBar = new fns.FilterBar(obj);
+ this.filterStatusTip = new fns.FilterStatusTip(obj);
+
+ //Expose the layer event to grid.
+ grid.onFilterDefined = function(){};
+ this.connect(grid.layer("filter"), "onFilterDefined", function(filter){
+ grid.onFilterDefined(grid.getFilter(), grid.getFilterRelation());
+ });
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ try{
+ this.grid.unwrap("filter");
+ this.filterBar.destroyRecursive();
+ this.filterBar = null;
+ this.clearFilterDialog.destroyRecursive();
+ this.clearFilterDialog = null;
+ this.filterStatusTip.destroy();
+ this.filterStatusTip = null;
+ this.filterDefDialog.destroy();
+ this.filterDefDialog = null;
+ this.grid = null;
+ this.nls = null;
+ this.args = null;
+ }catch(e){
+ console.warn("Filter.destroy() error:",e);
+ }
+ },
+ _wrapStore: function(){
+ var g = this.grid;
+ var args = this.args;
+ var filterLayer = args.isServerSide ? new fns.ServerSideFilterLayer(args) :
+ new fns.ClientSideFilterLayer({
+ cacheSize: args.filterCacheSize,
+ fetchAll: args.fetchAllOnFirstFilter,
+ getter: this._clientFilterGetter
+ });
+ ns.wrap(g, "_storeLayerFetch", filterLayer);
+
+ this.connect(g, "_onDelete", dojo.hitch(filterLayer, "invalidate"));
+ },
+ onSetStore: function(store){
+ this.filterDefDialog.clearFilter(true);
+ },
+ _clientFilterGetter: function(/* data item */ datarow,/* cell */cell, /* int */rowIndex){
+ // summary:
+ // Define the grid-specific way to get data from a row.
+ // Argument "cell" is provided by FilterDefDialog when defining filter expressions.
+ // Argument "rowIndex" is provided by FilterLayer when checking a row.
+ // FilterLayer also provides a forth argument: "store", which is grid.store,
+ // but we don't need it here.
+ return cell.get(rowIndex, datarow);
+ }
+ });
+})();
+
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Filter/*name:'filter'*/);
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Filter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Filter.xd.js
new file mode 100644
index 0000000..59c80a5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Filter.xd.js
@@ -0,0 +1,183 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.Filter"],
+["requireLocalization", "dojox.grid.enhanced", "Filter", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ru,sl,sv,th,tr,zh,zh-tw", "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ru,sl,sv,th,tr,zh,zh-tw"],
+["require", "dojox.grid.enhanced._Plugin"],
+["require", "dojox.grid.enhanced.plugins.Dialog"],
+["require", "dojox.grid.enhanced.plugins.filter.FilterLayer"],
+["require", "dojox.grid.enhanced.plugins.filter.FilterBar"],
+["require", "dojox.grid.enhanced.plugins.filter.FilterDefDialog"],
+["require", "dojox.grid.enhanced.plugins.filter.FilterStatusTip"],
+["require", "dojox.grid.enhanced.plugins.filter.ClearFilterConfirm"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.Filter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Filter"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Filter");
+
+;
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid.enhanced.plugins.Dialog");
+dojo.require("dojox.grid.enhanced.plugins.filter.FilterLayer");
+dojo.require("dojox.grid.enhanced.plugins.filter.FilterBar");
+dojo.require("dojox.grid.enhanced.plugins.filter.FilterDefDialog");
+dojo.require("dojox.grid.enhanced.plugins.filter.FilterStatusTip");
+dojo.require("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm");
+
+(function(){
+ var ns = dojox.grid.enhanced.plugins,
+ fns = ns.filter;
+
+ dojo.declare("dojox.grid.enhanced.plugins.Filter", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provide filter functionality for grid.
+ //
+ // Acceptable plugin parameters:
+ // 1. itemsName: string
+ // the name shown on the filter bar.
+ // 2. statusTipTimeout: number
+ // when does the status tip show.
+ // 3. ruleCount: number
+ // default to 3, should not change to more. The Claro theme limits it.
+ // 4. disabledConditions: object
+ // If you don't need all of the conditions provided for a data type,
+ // you can explicitly declare them here:
+ // e.g.: disabledConditions: {string: ["contains", "is"], number: ["equalto"], ...}
+ // 5. isServerSide: boolean
+ // Whether to use server side filtering. Default to false.
+ // 6. isStateful: boolean
+ // If isServerSide is true, set the server side filter to be stateful or not. default to false.
+ // 7. url: string
+ // If using stateful, this is the url to send commands. default to store.url.
+ //
+ // Acceptable cell parameters defined in layout:
+ // 1. filterable: boolean
+ // The column is not filterable only when this is set to false explicitly.
+ // 2. datatype: string
+ // The data type of this column. Can be "string", "number", "date", "time", "boolean".
+ // Default to "string".
+ // 3. autoComplete: boolean
+ // If need auto-complete in the ComboBox for String type, set this to true.
+ // 4. dataTypeArgs: object
+ // Some arguments helping convert store data to something the filter UI understands.
+ // Different data type arguments can be provided to different data types.
+ // For date/time, this is a dojo.date.locale.__FormatOptions, so the DataTimeBox can understand the store data.
+ // For boolean, this object contains:
+ // trueLabel: string
+ // A label to display in the filter definition dialog for true value. Default to "True".
+ // falseLable: string
+ // A label to display in the filter definition dialog for false value. Default to "False".
+ // 5. disabledConditions: object
+ // If you don't need all of the conditions provided by the filter UI on this column, you can explicitly say it out here.
+ // e.g.: disabledConditions: ["contains", "is"]
+ // This will disable the "contains" condition for this column, if this column is of string type.
+ // For full set of conditions, please refer to dojox.grid.enhanced.plugins.filter.FilterDefDialog._setupData.
+ // example:
+ // | <div dojoType="dojox.grid.EnhancedGrid" plugins="{GridFilter: true}" ...></div>
+ // | or provide some parameters:
+ // | <div dojoType="dojox.grid.EnhancedGrid" plugins="{GridFilter: {itemsName: 'songs'}}" ...></div>
+ // | Customize columns for filter:
+ // | var layout = [
+ // | ...
+ // | //define a column to be un-filterable in layout/structure
+ // | {field: "Genre", filterable: false, ...}
+ // | //define a column of type string and supports autoComplete when you type in filter conditions.
+ // | {field: "Writer", datatype: "string", autoCommplete: true, ...}
+ // | //define a column of type date and the data in store has format: "yyyy/M/d"
+ // | {field: "Publish Date", datatype: "date", dataTypeArgs: {datePattern: "yyyy/M/d"}, ...}
+ // | //disable some conditions for a column
+ // | {field: "Track", disabledConditions: ["equalto","notequalto"], ...}
+ // | ...
+ // | ];
+
+ // name: String
+ // plugin name
+ name: "filter",
+
+ constructor: function(grid, args){
+ // summary:
+ // See constructor of dojox.grid.enhanced._Plugin.
+ this.grid = grid;
+ this.nls = dojo.i18n.getLocalization("dojox.grid.enhanced", "Filter");
+
+ args = this.args = dojo.isObject(args) ? args : {};
+ if(typeof args.ruleCount != 'number' || args.ruleCount < 0){
+ args.ruleCount = 3;
+ }
+
+ //Install filter layer
+ this._wrapStore();
+
+ //Install UI components
+ var obj = { "plugin": this };
+ this.clearFilterDialog = new dojox.grid.enhanced.plugins.Dialog({
+ refNode: this.grid.domNode,
+ title: this.nls["clearFilterDialogTitle"],
+ content: new fns.ClearFilterConfirm(obj)
+ });
+ this.filterDefDialog = new fns.FilterDefDialog(obj);
+ this.filterBar = new fns.FilterBar(obj);
+ this.filterStatusTip = new fns.FilterStatusTip(obj);
+
+ //Expose the layer event to grid.
+ grid.onFilterDefined = function(){};
+ this.connect(grid.layer("filter"), "onFilterDefined", function(filter){
+ grid.onFilterDefined(grid.getFilter(), grid.getFilterRelation());
+ });
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ try{
+ this.grid.unwrap("filter");
+ this.filterBar.destroyRecursive();
+ this.filterBar = null;
+ this.clearFilterDialog.destroyRecursive();
+ this.clearFilterDialog = null;
+ this.filterStatusTip.destroy();
+ this.filterStatusTip = null;
+ this.filterDefDialog.destroy();
+ this.filterDefDialog = null;
+ this.grid = null;
+ this.nls = null;
+ this.args = null;
+ }catch(e){
+ console.warn("Filter.destroy() error:",e);
+ }
+ },
+ _wrapStore: function(){
+ var g = this.grid;
+ var args = this.args;
+ var filterLayer = args.isServerSide ? new fns.ServerSideFilterLayer(args) :
+ new fns.ClientSideFilterLayer({
+ cacheSize: args.filterCacheSize,
+ fetchAll: args.fetchAllOnFirstFilter,
+ getter: this._clientFilterGetter
+ });
+ ns.wrap(g, "_storeLayerFetch", filterLayer);
+
+ this.connect(g, "_onDelete", dojo.hitch(filterLayer, "invalidate"));
+ },
+ onSetStore: function(store){
+ this.filterDefDialog.clearFilter(true);
+ },
+ _clientFilterGetter: function(/* data item */ datarow,/* cell */cell, /* int */rowIndex){
+ // summary:
+ // Define the grid-specific way to get data from a row.
+ // Argument "cell" is provided by FilterDefDialog when defining filter expressions.
+ // Argument "rowIndex" is provided by FilterLayer when checking a row.
+ // FilterLayer also provides a forth argument: "store", which is grid.store,
+ // but we don't need it here.
+ return cell.get(rowIndex, datarow);
+ }
+ });
+})();
+
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Filter/*name:'filter'*/);
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/GridSource.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/GridSource.js
new file mode 100644
index 0000000..0a02402
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/GridSource.js
@@ -0,0 +1,159 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.GridSource"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.GridSource"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.GridSource");
+
+dojo.require("dojo.dnd.Source");
+dojo.require("dojox.grid.enhanced.plugins.DnD");
+
+(function(){
+var _joinToArray = function(arrays){
+ var a = arrays[0];
+ for(var i = 1; i < arrays.length; ++i){
+ a = a.concat(arrays[i]);
+ }
+ return a;
+};
+dojo.declare("dojox.grid.enhanced.plugins.GridSource", dojo.dnd.Source, {
+ // summary:
+ // A special source that can accept grid contents.
+ // Only for non-grid widgets or domNodes.
+ accept: ["grid/cells", "grid/rows", "grid/cols", "text"],
+
+ // insertNodesForGrid:
+ // If you'd like to insert some sort of nodes into your dnd source, turn this on,
+ // and override getCellContent/getRowContent/getColumnContent
+ // to populate the dnd data in your desired format.
+ insertNodesForGrid: false,
+
+ markupFactory: function(params, node){
+ return new dojox.grid.enhanced.plugins.GridSource(node, params);
+ },
+ checkAcceptance: function(source, nodes){
+ if(source instanceof dojox.grid.enhanced.plugins.GridDnDSource){
+ if(nodes[0]){
+ var item = source.getItem(nodes[0].id);
+ if(item && (dojo.indexOf(item.type, "grid/rows") >= 0 || dojo.indexOf(item.type, "grid/cells") >= 0) &&
+ !source.dndPlugin._allDnDItemsLoaded()){
+ return false;
+ }
+ }
+ this.sourcePlugin = source.dndPlugin;
+ }
+ return this.inherited(arguments);
+ },
+ onDraggingOver: function(){
+ if(this.sourcePlugin){
+ this.sourcePlugin._isSource = true;
+ }
+ },
+ onDraggingOut: function(){
+ if(this.sourcePlugin){
+ this.sourcePlugin._isSource = false;
+ }
+ },
+ onDropExternal: function(source, nodes, copy){
+ if(source instanceof dojox.grid.enhanced.plugins.GridDnDSource){
+ var ranges = dojo.map(nodes, function(node){
+ return source.getItem(node.id).data;
+ });
+ var item = source.getItem(nodes[0].id);
+ var grid = item.dndPlugin.grid;
+ var type = item.type[0];
+ var range;
+ try{
+ switch(type){
+ case "grid/cells":
+ nodes[0].innerHTML = this.getCellContent(grid, ranges[0].min, ranges[0].max) || "";
+ this.onDropGridCells(grid, ranges[0].min, ranges[0].max);
+ break;
+ case "grid/rows":
+ range = _joinToArray(ranges);
+ nodes[0].innerHTML = this.getRowContent(grid, range) || "";
+ this.onDropGridRows(grid, range);
+ break;
+ case "grid/cols":
+ range = _joinToArray(ranges);
+ nodes[0].innerHTML = this.getColumnContent(grid, range) || "";
+ this.onDropGridColumns(grid, range);
+ break;
+ }
+ if(this.insertNodesForGrid){
+ this.selectNone();
+ this.insertNodes(true, [nodes[0]], this.before, this.current);
+ }
+ item.dndPlugin.onDragOut(!copy);
+ }catch(e){
+ console.warn("GridSource.onDropExternal() error:",e);
+ }
+ }else{
+ this.inherited(arguments);
+ }
+ },
+ getCellContent: function(grid, leftTopCell, rightBottomCell){
+ // summary:
+ // Fill node innerHTML for dnd grid cells.
+ // sample code:
+ // var cells = grid.layout.cells;
+ // var store = grid.store;
+ // var cache = grid._by_idx;
+ // var res = "Grid Cells from " + grid.id + ":<br/>";
+ // for(var r = leftTopCell.row; r <= rightBottomCell.row; ++r){
+ // for(var c = leftTopCell.col; c <= rightBottomCell.col; ++c){
+ // res += store.getValue(cache[r].item, cells[c].field) + ", ";
+ // }
+ // res = res.substring(0, res.length - 2) + ";<br/>";
+ // }
+ // return res;
+ },
+ getRowContent: function(grid, rowIndexes){
+ // summary:
+ // Fill node innerHTML for dnd grid rows.
+ // sample code:
+ // var cells = grid.layout.cells;
+ // var store = grid.store;
+ // var cache = grid._by_idx;
+ // var res = "Grid Rows from " + grid.id + ":<br/>";
+ // for(var i = 0; i < rowIndexes.length; ++i){
+ // var r = rowIndexes[i];
+ // res += "Row " + r + ": ";
+ // for(var j = 0; j < cells.length; ++j){
+ // if(!cells[j].hidden){
+ // res += store.getValue(cache[r].item, cells[j].field) + ", ";
+ // }
+ // }
+ // res = res.substring(0, res.length - 2) + ";<br/>";
+ // }
+ // return res;
+ },
+ getColumnContent: function(grid, colIndexes){
+ // summary:
+ // Fill node innerHTML for dnd grid columns.
+ // sample code:
+ // var cells = grid.layout.cells;
+ // var res = "Grid Columns from " + grid.id + ":";
+ // for(var i = 0; i < colIndexes.length; ++i){
+ // var c = colIndexes[i];
+ // res += (cells[c].name || cells[c].field) + ", ";
+ // }
+ // return res.substring(0, res.length - 2);
+ },
+ onDropGridCells: function(grid, leftTopCell, rightBottomCell){
+
+ },
+ onDropGridRows: function(grid, rowIndexes){
+
+ },
+ onDropGridColumns: function(grid, colIndexes){
+
+ }
+});
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/GridSource.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/GridSource.xd.js
new file mode 100644
index 0000000..4398814
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/GridSource.xd.js
@@ -0,0 +1,165 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.GridSource"],
+["require", "dojo.dnd.Source"],
+["require", "dojox.grid.enhanced.plugins.DnD"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.GridSource"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.GridSource"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.GridSource");
+
+dojo.require("dojo.dnd.Source");
+dojo.require("dojox.grid.enhanced.plugins.DnD");
+
+(function(){
+var _joinToArray = function(arrays){
+ var a = arrays[0];
+ for(var i = 1; i < arrays.length; ++i){
+ a = a.concat(arrays[i]);
+ }
+ return a;
+};
+dojo.declare("dojox.grid.enhanced.plugins.GridSource", dojo.dnd.Source, {
+ // summary:
+ // A special source that can accept grid contents.
+ // Only for non-grid widgets or domNodes.
+ accept: ["grid/cells", "grid/rows", "grid/cols", "text"],
+
+ // insertNodesForGrid:
+ // If you'd like to insert some sort of nodes into your dnd source, turn this on,
+ // and override getCellContent/getRowContent/getColumnContent
+ // to populate the dnd data in your desired format.
+ insertNodesForGrid: false,
+
+ markupFactory: function(params, node){
+ return new dojox.grid.enhanced.plugins.GridSource(node, params);
+ },
+ checkAcceptance: function(source, nodes){
+ if(source instanceof dojox.grid.enhanced.plugins.GridDnDSource){
+ if(nodes[0]){
+ var item = source.getItem(nodes[0].id);
+ if(item && (dojo.indexOf(item.type, "grid/rows") >= 0 || dojo.indexOf(item.type, "grid/cells") >= 0) &&
+ !source.dndPlugin._allDnDItemsLoaded()){
+ return false;
+ }
+ }
+ this.sourcePlugin = source.dndPlugin;
+ }
+ return this.inherited(arguments);
+ },
+ onDraggingOver: function(){
+ if(this.sourcePlugin){
+ this.sourcePlugin._isSource = true;
+ }
+ },
+ onDraggingOut: function(){
+ if(this.sourcePlugin){
+ this.sourcePlugin._isSource = false;
+ }
+ },
+ onDropExternal: function(source, nodes, copy){
+ if(source instanceof dojox.grid.enhanced.plugins.GridDnDSource){
+ var ranges = dojo.map(nodes, function(node){
+ return source.getItem(node.id).data;
+ });
+ var item = source.getItem(nodes[0].id);
+ var grid = item.dndPlugin.grid;
+ var type = item.type[0];
+ var range;
+ try{
+ switch(type){
+ case "grid/cells":
+ nodes[0].innerHTML = this.getCellContent(grid, ranges[0].min, ranges[0].max) || "";
+ this.onDropGridCells(grid, ranges[0].min, ranges[0].max);
+ break;
+ case "grid/rows":
+ range = _joinToArray(ranges);
+ nodes[0].innerHTML = this.getRowContent(grid, range) || "";
+ this.onDropGridRows(grid, range);
+ break;
+ case "grid/cols":
+ range = _joinToArray(ranges);
+ nodes[0].innerHTML = this.getColumnContent(grid, range) || "";
+ this.onDropGridColumns(grid, range);
+ break;
+ }
+ if(this.insertNodesForGrid){
+ this.selectNone();
+ this.insertNodes(true, [nodes[0]], this.before, this.current);
+ }
+ item.dndPlugin.onDragOut(!copy);
+ }catch(e){
+ console.warn("GridSource.onDropExternal() error:",e);
+ }
+ }else{
+ this.inherited(arguments);
+ }
+ },
+ getCellContent: function(grid, leftTopCell, rightBottomCell){
+ // summary:
+ // Fill node innerHTML for dnd grid cells.
+ // sample code:
+ // var cells = grid.layout.cells;
+ // var store = grid.store;
+ // var cache = grid._by_idx;
+ // var res = "Grid Cells from " + grid.id + ":<br/>";
+ // for(var r = leftTopCell.row; r <= rightBottomCell.row; ++r){
+ // for(var c = leftTopCell.col; c <= rightBottomCell.col; ++c){
+ // res += store.getValue(cache[r].item, cells[c].field) + ", ";
+ // }
+ // res = res.substring(0, res.length - 2) + ";<br/>";
+ // }
+ // return res;
+ },
+ getRowContent: function(grid, rowIndexes){
+ // summary:
+ // Fill node innerHTML for dnd grid rows.
+ // sample code:
+ // var cells = grid.layout.cells;
+ // var store = grid.store;
+ // var cache = grid._by_idx;
+ // var res = "Grid Rows from " + grid.id + ":<br/>";
+ // for(var i = 0; i < rowIndexes.length; ++i){
+ // var r = rowIndexes[i];
+ // res += "Row " + r + ": ";
+ // for(var j = 0; j < cells.length; ++j){
+ // if(!cells[j].hidden){
+ // res += store.getValue(cache[r].item, cells[j].field) + ", ";
+ // }
+ // }
+ // res = res.substring(0, res.length - 2) + ";<br/>";
+ // }
+ // return res;
+ },
+ getColumnContent: function(grid, colIndexes){
+ // summary:
+ // Fill node innerHTML for dnd grid columns.
+ // sample code:
+ // var cells = grid.layout.cells;
+ // var res = "Grid Columns from " + grid.id + ":";
+ // for(var i = 0; i < colIndexes.length; ++i){
+ // var c = colIndexes[i];
+ // res += (cells[c].name || cells[c].field) + ", ";
+ // }
+ // return res.substring(0, res.length - 2);
+ },
+ onDropGridCells: function(grid, leftTopCell, rightBottomCell){
+
+ },
+ onDropGridRows: function(grid, rowIndexes){
+
+ },
+ onDropGridColumns: function(grid, colIndexes){
+
+ }
+});
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/IndirectSelection.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/IndirectSelection.js
new file mode 100644
index 0000000..f27ec28
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/IndirectSelection.js
@@ -0,0 +1,616 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.IndirectSelection"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.IndirectSelection"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.IndirectSelection");
+
+dojo.require('dojo.string');
+dojo.require("dojox.grid.cells.dijit");
+dojo.require("dojox.grid.enhanced._Plugin");
+
+dojo.declare("dojox.grid.enhanced.plugins.IndirectSelection", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // A handy way for adding check boxe/radio button for rows, and selecting rows by swiping(or keyboard)
+
+ // description:
+ // For better rendering performance, div(images) are used to simulate radio button|check boxes
+ //
+ // example:
+ // <div dojoType="dojox.grid.EnhancedGrid" plugins="{indirectSelection: true}" ...></div>
+ // or <div dojoType="dojox.grid.EnhancedGrid" plugins="{indirectSelection: {name: 'xxx', width:'30px', styles:'text-align: center;'}}" ...></div>
+
+ //name: String
+ // Plugin name
+ name: "indirectSelection",
+
+ constructor: function(){
+ //Hook layout.setStructure(), so that indirectSelection is always included
+ var layout = this.grid.layout;
+ this.connect(layout, 'setStructure', dojo.hitch(layout, this.addRowSelectCell, this.option));
+ },
+ addRowSelectCell: function(option){
+ // summary:
+ // Add indirectSelection cell(mapped to a column of radio button|check boxes)
+ if(!this.grid.indirectSelection || this.grid.selectionMode == 'none'){
+ return;
+ }
+ var rowSelectCellAdded = false, inValidFields = ['get', 'formatter', 'field', 'fields'],
+ defaultCellDef = {type: dojox.grid.cells.MultipleRowSelector, name: '', width:'30px', styles:'text-align: center;'};
+ if(option.headerSelector){ option.name = ''; }//mutual conflicting attrs
+
+ if(this.grid.rowSelectCell){//remove the existed one
+ this.grid.rowSelectCell.destroy();
+ }
+
+ dojo.forEach(this.structure, function(view){
+ var cells = view.cells;
+ if(cells && cells.length > 0 && !rowSelectCellAdded){
+ var firstRow = cells[0];
+ if(firstRow[0] && firstRow[0].isRowSelector){
+ console.debug('addRowSelectCell() - row selector cells already added, return.');
+ rowSelectCellAdded = true;
+ return;
+ }
+ var selectDef, cellType = this.grid.selectionMode == 'single' ? dojox.grid.cells.SingleRowSelector : dojox.grid.cells.MultipleRowSelector;
+ selectDef = dojo.mixin(defaultCellDef, option, {type: cellType, editable: false, notselectable: true, filterable: false, navigatable: true, nosort: true});
+ dojo.forEach(inValidFields, function(field){//remove invalid fields
+ if(field in selectDef){ delete selectDef[field]; }
+ });
+ if(cells.length > 1){ selectDef.rowSpan = cells.length; }//for complicate layout
+ dojo.forEach(this.cells, function(cell, i){
+ if(cell.index >= 0){
+ cell.index += 1;
+ //console.debug('cell '+ (cell.index - 1) + ' is updated to index ' + cell.index);
+ }else{
+ console.warn('Error:IndirectSelection.addRowSelectCell()- cell ' + i + ' has no index!');
+ }
+ });
+ var rowSelectCell = this.addCellDef(0, 0, selectDef);
+ rowSelectCell.index = 0;
+ firstRow.unshift(rowSelectCell);
+ this.cells.unshift(rowSelectCell);
+ this.grid.rowSelectCell = rowSelectCell;
+ rowSelectCellAdded = true;
+ }
+ }, this);
+ this.cellCount = this.cells.length;
+ },
+ destroy: function(){
+ this.grid.rowSelectCell.destroy();
+ delete this.grid.rowSelectCell;
+ this.inherited(arguments);
+ }
+});
+
+dojo.declare("dojox.grid.cells.RowSelector", dojox.grid.cells._Widget, {
+ // summary:
+ // Common attributes & functions for row selectors(Radio|CheckBox)
+
+ //inputType: String
+ // Input type - Radio|CheckBox
+ inputType: "",
+
+ //map: Object
+ // Cache div refs of radio|checkbox to avoid querying each time
+ map: null,
+
+ //disabledMap: Object
+ // Cache index of disabled rows
+ disabledMap: null,
+
+ //isRowSelector: Boolean
+ // Marker of indirectSelection cell(column)
+ isRowSelector: true,
+
+ //_connects: Array
+ // List of all connections.
+ _connects: null,
+
+ //_subscribes: Array
+ // List of all subscribes.
+ _subscribes: null,
+
+ //checkedText: String
+ // Checked character for high contrast mode
+ checkedText: '&#8730;',
+
+ //unCheckedText: String
+ // Unchecked character for high contrast mode
+ unCheckedText: 'O',
+
+ constructor: function(){
+ this.map = {}; this.disabledMap = {}, this.disabledCount= 0;
+ this._connects = []; this._subscribes = [];
+ this.inA11YMode = dojo.hasClass(dojo.body(), "dijit_a11y");
+
+ this.baseClass = "dojoxGridRowSelector dijitReset dijitInline dijit" + this.inputType;
+ this.checkedClass = " dijit" + this.inputType + "Checked";
+ this.disabledClass = " dijit" + this.inputType + "Disabled";
+ this.checkedDisabledClass = " dijit" + this.inputType + "CheckedDisabled";
+ this.statusTextClass = " dojoxGridRowSelectorStatusText";//a11y use
+
+ this._connects.push(dojo.connect(this.grid, 'dokeyup', this, '_dokeyup'));
+ this._connects.push(dojo.connect(this.grid.selection, 'onSelected', this, '_onSelected'));
+ this._connects.push(dojo.connect(this.grid.selection, 'onDeselected', this, '_onDeselected'));
+ this._connects.push(dojo.connect(this.grid.scroller, 'invalidatePageNode', this, '_pageDestroyed'));
+ this._connects.push(dojo.connect(this.grid, 'onCellClick', this, '_onClick'));
+ this._connects.push(dojo.connect(this.grid, 'updateRow', this, '_onUpdateRow'));
+ },
+ formatter: function(data, rowIndex){
+ // summary:
+ // Overwritten, see dojox.grid.cells._Widget
+ var clazz = this.baseClass;
+ var checked = this.getValue(rowIndex);
+ var disabled = !!this.disabledMap[rowIndex];//normalize 'undefined'
+
+ if(checked){
+ clazz += this.checkedClass;
+ if(disabled){ clazz += this.checkedDisabledClass; }
+ }else if(disabled){
+ clazz += this.disabledClass;
+ }
+ return ["<div tabindex = -1 ",
+ "id = '" + this.grid.id + "_rowSelector_" + rowIndex + "' ",
+ "name = '" + this.grid.id + "_rowSelector' class = '" + clazz + "' ",
+ "role = 'presentation' aria-pressed = '" + checked + "' aria-disabled = '" + disabled +
+ "' aria-label = '" + dojo.string.substitute(this.grid._nls["indirectSelection" + this.inputType], [rowIndex + 1]) + "'>",
+ "<span class = '" + this.statusTextClass + "'>" + (checked ? this.checkedText : this.unCheckedText) + "</span>",
+ "</div>"].join("");
+ },
+ setValue: function(rowIndex, inValue){
+ // summary:
+ // Overwritten, see dojox.grid.cells._Widget
+ // Simply return, no action
+ },
+ getValue: function(rowIndex){
+ // summary:
+ // Overwritten, see dojox.grid.cells._Widget
+ return this.grid.selection.isSelected(rowIndex);
+ },
+ toggleRow: function(index, value){
+ // summary:
+ // toggle checked | unchecked state for given row
+ // index: Integer
+ // Row index
+ // value: Boolean
+ // True - checked | False - unchecked
+ this._nativeSelect(index, value);
+ },
+ setDisabled: function(index, disabled){
+ // summary:
+ // toggle disabled | enabled state for given row
+ // idx: Integer
+ // Row index
+ // disabled: Boolean
+ // True - disabled | False - enabled
+ if(index < 0){ return; }
+ this._toggleDisabledStyle(index, disabled);
+ },
+ disabled: function(index){
+ // summary:
+ // Check if one row is disabled
+ return !!this.disabledMap[index];
+ },
+ _onClick: function(e){
+ // summary:
+ // When mouse click on the selector cell, select/deselect the row.
+ if(e.cell === this){
+ this._selectRow(e);
+ }
+ },
+ _dokeyup: function(e){
+ // summary:
+ // Event handler for key up event
+ // - from dojox.grid.enhanced._Events.dokeyup()
+ // e: Event
+ // Key up event
+ if(e.cellIndex == this.index && e.rowIndex >= 0 && e.keyCode == dojo.keys.SPACE){
+ this._selectRow(e);
+ }
+ },
+ focus: function(rowIndex){
+ // summary:
+ // Set focus to given row
+ // rowIndex: Integer
+ // Target row
+ var selector = this.map[rowIndex];
+ if(selector){ selector.focus(); }
+ },
+ _focusEndingCell: function(rowIndex, cellIndex){
+ // summary:
+ // Set focus to the ending grid cell(rowIndex,cellIndex) when swipe selection finished
+ // rowIndex: Integer
+ // Row index
+ // cellIndex: Integer
+ // Column index
+ var cell = this.grid.getCell(cellIndex);
+ this.grid.focus.setFocusCell(cell, rowIndex);
+ },
+ _nativeSelect: function(index, value){
+ // summary:
+ // Use grid's native selection
+ this.grid.selection[value ? 'select' : 'deselect'](index);
+ },
+ _onSelected: function(index){
+ // summary:
+ // Triggered when a row is selected
+ this._toggleCheckedStyle(index, true);
+ },
+ _onDeselected: function(index){
+ // summary:
+ // Triggered when a row is deselected
+ this._toggleCheckedStyle(index, false);
+ },
+ _onUpdateRow: function(index){
+ // summary:
+ // Clear cache when row is re-built.
+ delete this.map[index];
+ },
+ _toggleCheckedStyle: function(index, value){
+ // summary:
+ // Change css styles for checked | unchecked
+ var selector = this._getSelector(index);
+ if(selector){
+ dojo.toggleClass(selector, this.checkedClass, value);
+ if(this.disabledMap[index]){
+ dojo.toggleClass(selector, this.checkedDisabledClass, value);
+ }
+ dijit.setWaiState(selector, 'pressed', value);
+ if(this.inA11YMode){
+ dojo.attr(selector.firstChild, 'innerHTML', value ? this.checkedText : this.unCheckedText);
+ }
+ }
+ },
+ _toggleDisabledStyle: function(index, disabled){
+ // summary:
+ // Change css styles for disabled | enabled
+ var selector = this._getSelector(index);
+ if(selector){
+ dojo.toggleClass(selector, this.disabledClass, disabled);
+ if(this.getValue(index)){
+ dojo.toggleClass(selector, this.checkedDisabledClass, disabled);
+ }
+ dijit.setWaiState(selector, 'disabled', disabled);
+ }
+ this.disabledMap[index] = disabled;
+ if(index >= 0){
+ this.disabledCount += disabled ? 1 : -1;
+ }
+ },
+ _getSelector: function(index){
+ // summary:
+ // Find selector for given row caching it if 1st time found
+ var selector = this.map[index];
+ if(!selector){//use accurate query for better performance
+ var rowNode = this.view.rowNodes[index];
+ if(rowNode){
+ selector = dojo.query('.dojoxGridRowSelector', rowNode)[0];
+ if(selector){ this.map[index] = selector; }
+ }
+ }
+ return selector;
+ },
+ _pageDestroyed: function(pageIndex){
+ // summary:
+ // Explicitly empty map cache when a page destroyed
+ // See dojox.grid._Scroller.invalidatePageNode()
+ // pageIndex: Integer
+ // Index of destroyed page
+ var rowsPerPage = this.grid.scroller.rowsPerPage;
+ var start = pageIndex * rowsPerPage, end = start + rowsPerPage - 1;
+ for(var i = start; i <= end; i++){
+ if(!this.map[i]){continue;}
+ dojo.destroy(this.map[i]);
+ delete this.map[i];
+ }
+ //console.log("Page ",pageIndex, " destroyed, Map=",this.map);
+ },
+ destroy: function(){
+ for(var i in this.map){
+ dojo.destroy(this.map[i]);
+ delete this.map[i];
+ }
+ for(i in this.disabledMap){ delete this.disabledMap[i]; }
+ dojo.forEach(this._connects, dojo.disconnect);
+ dojo.forEach(this._subscribes, dojo.unsubscribe);
+ delete this._connects;
+ delete this._subscribes;
+ //console.log('Single(Multiple)RowSelector.destroy() executed!');
+ }
+});
+
+dojo.declare("dojox.grid.cells.SingleRowSelector", dojox.grid.cells.RowSelector, {
+ // summary:
+ // IndirectSelection cell(column) for single selection mode, using styles of dijit.form.RadioButton
+ inputType: "Radio",
+
+ _selectRow: function(e){
+ // summary:
+ // Select the target row
+ // e: Event
+ // Event fired on the target row
+ var index = e.rowIndex;
+ if(this.disabledMap[index]){ return; }
+ this._focusEndingCell(index, 0);
+ this._nativeSelect(index, !this.grid.selection.selected[index]);
+ }
+});
+
+dojo.declare("dojox.grid.cells.MultipleRowSelector", dojox.grid.cells.RowSelector, {
+ // summary:
+ // Indirect selection cell for multiple or extended mode, using dijit.form.CheckBox
+ inputType: "CheckBox",
+
+ //swipeStartRowIndex: Integer
+ // Start row index for swipe selection
+ swipeStartRowIndex: -1,
+
+ //swipeMinRowIndex: Integer
+ // Min row index for swipe selection
+ swipeMinRowIndex: -1,
+
+ //swipeMinRowIndex: Integer
+ // Max row index for swipe selection
+ swipeMaxRowIndex: -1,
+
+ //toSelect: Boolean
+ // new state for selection
+ toSelect: false,
+
+ //lastClickRowIdx: Integer
+ // Row index for last click, used for range selection via Shift + click
+ lastClickRowIdx: -1,
+
+ //toggleAllTrigerred: Boolean
+ // Whether toggle all has been triggered or not
+ toggleAllTrigerred: false,
+
+ unCheckedText: '&#9633;',
+
+ constructor: function(){
+ this._connects.push(dojo.connect(dojo.doc, 'onmouseup', this, '_domouseup'));
+ this._connects.push(dojo.connect(this.grid, 'onRowMouseOver', this, '_onRowMouseOver'));
+ this._connects.push(dojo.connect(this.grid.focus, 'move', this, '_swipeByKey'));
+ this._connects.push(dojo.connect(this.grid, 'onCellMouseDown', this, '_onMouseDown'));
+ if(this.headerSelector){//option set by user to add a select-all checkbox in column header
+ this._connects.push(dojo.connect(this.grid.views, 'render', this, '_addHeaderSelector'));
+ this._connects.push(dojo.connect(this.grid, 'onSelectionChanged', this, '_onSelectionChanged'));
+ this._connects.push(dojo.connect(this.grid, 'onKeyDown', this, function(e){
+ if(e.rowIndex == -1 && e.cellIndex == this.index && e.keyCode == dojo.keys.SPACE){
+ this._toggletHeader();//TBD - a better way
+ }
+ }));
+ }
+ },
+ toggleAllSelection:function(checked){
+ // summary:
+ // Toggle select all|deselect all
+ // checked: Boolean
+ // True - select all, False - deselect all
+ var grid = this.grid, selection = grid.selection;
+ if(checked){
+ selection.selectRange(0, grid.rowCount-1);
+ }else{
+ selection.deselectAll();
+ }
+ this.toggleAllTrigerred = true;
+ },
+ _onMouseDown: function(e){
+ if(e.cell == this){
+ this._startSelection(e.rowIndex);
+ dojo.stopEvent(e);
+ }
+ },
+ _onRowMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over a data row(outside of this column).
+ // - from dojox.grid.enhanced._Events.onRowMouseOver()
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this._updateSelection(e, 0);
+ },
+ _domouseup: function(e){
+ // summary:
+ // Event handler for mouse up event - from dojo.doc.domouseup()
+ // e: Event
+ // Mouse up event
+ if(dojo.isIE){
+ this.view.content.decorateEvent(e);//TODO - why only e in IE hasn't been decorated?
+ }
+ var inSwipeSelection = e.cellIndex >= 0 && this.inSwipeSelection() && !this.grid.edit.isEditRow(e.rowIndex);
+ if(inSwipeSelection){
+ this._focusEndingCell(e.rowIndex, e.cellIndex);
+ }
+ this._finishSelect();
+ },
+ _dokeyup: function(e){
+ // summary:
+ // Event handler for key up event
+ // - from dojox.grid.enhanced._Events.dokeyup()
+ // e: Event
+ // Key up event
+ this.inherited(arguments);
+ if(!e.shiftKey){
+ this._finishSelect();
+ }
+ },
+ _startSelection: function(rowIndex){
+ // summary:
+ // Initialize parameters to start a new swipe selection
+ // rowIndex: Integer
+ // Index of the start row
+ this.swipeStartRowIndex = this.swipeMinRowIndex = this.swipeMaxRowIndex = rowIndex;
+ this.toSelect = !this.getValue(rowIndex);
+ },
+ _updateSelection: function(e, delta){
+ // summary:
+ // Update row selections, fired during a swipe selection
+ // e: Event
+ // Event of the current row,
+ // delta: Integer
+ // Row index delta, used for swipe selection via Shift + Arrow key
+ // 0: not via key, -1 : Shift + Up, 1 : Shift + Down
+ if(!this.inSwipeSelection()){ return; }
+
+ var byKey = delta !== 0;//whether via Shift + Arrow Key
+ var currRow = e.rowIndex, deltaRow = currRow - this.swipeStartRowIndex + delta;
+ if(deltaRow > 0 && this.swipeMaxRowIndex < currRow + delta){
+ this.swipeMaxRowIndex = currRow + delta;
+ }
+ if(deltaRow < 0 && this.swipeMinRowIndex > currRow + delta){
+ this.swipeMinRowIndex = currRow + delta;
+ }
+
+ var min = deltaRow > 0 ? this.swipeStartRowIndex : currRow + delta;
+ var max = deltaRow > 0 ? currRow + delta : this.swipeStartRowIndex;
+ for(var i = this.swipeMinRowIndex; i <= this.swipeMaxRowIndex; i++){
+ if(this.disabledMap[i] || i < 0){ continue; }
+ if(i >= min && i <= max){//deltaRow != 0 || this.toSelect
+ this._nativeSelect(i, this.toSelect);
+ }else if(!byKey){
+ this._nativeSelect(i, !this.toSelect);
+ }
+ }
+ },
+ _swipeByKey: function(rowOffset, colOffset, e){
+ // summary:
+ // Update row selections, fired when Shift + Cursor is used for swipe selection
+ // See dojox.grid.enhanced._Events.onKeyDown
+ // e: Event
+ // Event of the current row,
+ // rowOffset: Integer
+ // Row offset, used for swipe selection via Shift + Cursor
+ // -1 : Shift + Up, 1 : Shift + Down
+ if(!e || rowOffset === 0 || !e.shiftKey || e.cellIndex != this.index ||
+ this.grid.focus.rowIndex < 0){ //TBD - e.rowIndex == 0 && delta == -1
+ return;
+ }
+ var rowIndex = e.rowIndex;
+ if(this.swipeStartRowIndex < 0){
+ //A new swipe selection starts via Shift + Arrow key
+ this.swipeStartRowIndex = rowIndex;
+ if(rowOffset > 0){//Shift + Down
+ this.swipeMaxRowIndex = rowIndex + rowOffset;
+ this.swipeMinRowIndex = rowIndex;
+ }else{//Shift + UP
+ this.swipeMinRowIndex = rowIndex + rowOffset;
+ this.swipeMaxRowIndex = rowIndex;
+ }
+ this.toSelect = this.getValue(rowIndex);
+ }
+ this._updateSelection(e, rowOffset);
+ },
+ _finishSelect: function(){
+ // summary:
+ // Reset parameters to end a swipe selection
+ this.swipeStartRowIndex = -1;
+ this.swipeMinRowIndex = -1;
+ this.swipeMaxRowIndex = -1;
+ this.toSelect = false;
+ },
+ inSwipeSelection: function(){
+ // summary:
+ // Check if during a swipe selection
+ // return: Boolean
+ // Whether in swipe selection
+ return this.swipeStartRowIndex >= 0;
+ },
+ _nativeSelect: function(index, value){
+ // summary:
+ // Overwritten
+ this.grid.selection[value ? 'addToSelection' : 'deselect'](index);
+ },
+ _selectRow: function(e){
+ // summary:
+ // Select the target row or range or rows
+ // e: Event
+ // Event fired on the target row
+ var rowIndex = e.rowIndex;
+ if(this.disabledMap[rowIndex]){ return; }
+ dojo.stopEvent(e);
+ this._focusEndingCell(rowIndex, 0);
+
+ var delta = rowIndex - this.lastClickRowIdx;
+ var newValue = !this.grid.selection.selected[rowIndex];
+ if(this.lastClickRowIdx >= 0 && !e.ctrlKey && !e.altKey && e.shiftKey){
+ var min = delta > 0 ? this.lastClickRowIdx : rowIndex;
+ var max = delta > 0 ? rowIndex : this.lastClickRowIdx;
+ for(var i = min; i >= 0 && i <= max; i++){
+ this._nativeSelect(i, newValue);
+ }
+ }else{
+ this._nativeSelect(rowIndex, newValue);
+ }
+ this.lastClickRowIdx = rowIndex;
+ },
+ getValue: function(rowIndex){
+ // summary:
+ // Overwritten
+ if(rowIndex == -1){//header selector
+ var g = this.grid;
+ return g.rowCount > 0 && g.rowCount <= g.selection.getSelectedCount();
+ }
+ return this.inherited(arguments);
+ },
+ _addHeaderSelector: function(){
+ // summary:
+ // Add selector in column header for selecting|deselecting all
+ var headerCellNode = this.view.getHeaderCellNode(this.index);
+ if(!headerCellNode){ return; }
+ dojo.empty(headerCellNode);
+ var g = this.grid;
+ var selector = headerCellNode.appendChild(dojo.create("div", {
+ "tabindex": -1, "id": g.id + "_rowSelector_-1", "class": this.baseClass, "role": "presentation",
+ "innerHTML": "<span class = '" + this.statusTextClass +
+ "'></span><span style='height: 0; width: 0; overflow: hidden; display: block;'>" +
+ g._nls["selectAll"] + "</span>"
+ }));
+ this.map[-1] = selector;
+ var idx = this._headerSelectorConnectIdx;
+ if(idx !== undefined){
+ dojo.disconnect(this._connects[idx]);
+ this._connects.splice(idx, 1);
+ }
+ this._headerSelectorConnectIdx = this._connects.length;
+ this._connects.push(dojo.connect(selector, 'onclick', this, '_toggletHeader'));
+ this._onSelectionChanged();
+ },
+ _toggletHeader: function(){
+ // summary:
+ // Toggle state for head selector
+ if(!!this.disabledMap[-1]){ return; }
+ this.grid._selectingRange = true;
+ this.toggleAllSelection(!this.getValue(-1));
+ this._onSelectionChanged();
+ this.grid._selectingRange = false;
+ },
+ _onSelectionChanged: function(){
+ // summary:
+ // Update header selector anytime selection changed
+ var g = this.grid;
+ if(!this.map[-1] || g._selectingRange){ return; }
+ this._toggleCheckedStyle(-1, this.getValue(-1));
+ },
+ _toggleDisabledStyle: function(index, disabled){
+ // summary:
+ // Overwritten
+ this.inherited(arguments);
+ if(this.headerSelector){
+ var allDisabled = (this.grid.rowCount == this.disabledCount);
+ if(allDisabled != !!this.disabledMap[-1]){//only if needed
+ arguments[0] = -1;
+ arguments[1] = allDisabled;
+ this.inherited(arguments);
+ }
+ }
+ }
+});
+
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.IndirectSelection/*name:'indirectSelection'*/, {"preInit": true});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/IndirectSelection.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/IndirectSelection.xd.js
new file mode 100644
index 0000000..8686d02
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/IndirectSelection.xd.js
@@ -0,0 +1,623 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.IndirectSelection"],
+["require", 'dojo.string'],
+["require", "dojox.grid.cells.dijit"],
+["require", "dojox.grid.enhanced._Plugin"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.IndirectSelection"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.IndirectSelection"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.IndirectSelection");
+
+dojo.require('dojo.string');
+dojo.require("dojox.grid.cells.dijit");
+dojo.require("dojox.grid.enhanced._Plugin");
+
+dojo.declare("dojox.grid.enhanced.plugins.IndirectSelection", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // A handy way for adding check boxe/radio button for rows, and selecting rows by swiping(or keyboard)
+
+ // description:
+ // For better rendering performance, div(images) are used to simulate radio button|check boxes
+ //
+ // example:
+ // <div dojoType="dojox.grid.EnhancedGrid" plugins="{indirectSelection: true}" ...></div>
+ // or <div dojoType="dojox.grid.EnhancedGrid" plugins="{indirectSelection: {name: 'xxx', width:'30px', styles:'text-align: center;'}}" ...></div>
+
+ //name: String
+ // Plugin name
+ name: "indirectSelection",
+
+ constructor: function(){
+ //Hook layout.setStructure(), so that indirectSelection is always included
+ var layout = this.grid.layout;
+ this.connect(layout, 'setStructure', dojo.hitch(layout, this.addRowSelectCell, this.option));
+ },
+ addRowSelectCell: function(option){
+ // summary:
+ // Add indirectSelection cell(mapped to a column of radio button|check boxes)
+ if(!this.grid.indirectSelection || this.grid.selectionMode == 'none'){
+ return;
+ }
+ var rowSelectCellAdded = false, inValidFields = ['get', 'formatter', 'field', 'fields'],
+ defaultCellDef = {type: dojox.grid.cells.MultipleRowSelector, name: '', width:'30px', styles:'text-align: center;'};
+ if(option.headerSelector){ option.name = ''; }//mutual conflicting attrs
+
+ if(this.grid.rowSelectCell){//remove the existed one
+ this.grid.rowSelectCell.destroy();
+ }
+
+ dojo.forEach(this.structure, function(view){
+ var cells = view.cells;
+ if(cells && cells.length > 0 && !rowSelectCellAdded){
+ var firstRow = cells[0];
+ if(firstRow[0] && firstRow[0].isRowSelector){
+ console.debug('addRowSelectCell() - row selector cells already added, return.');
+ rowSelectCellAdded = true;
+ return;
+ }
+ var selectDef, cellType = this.grid.selectionMode == 'single' ? dojox.grid.cells.SingleRowSelector : dojox.grid.cells.MultipleRowSelector;
+ selectDef = dojo.mixin(defaultCellDef, option, {type: cellType, editable: false, notselectable: true, filterable: false, navigatable: true, nosort: true});
+ dojo.forEach(inValidFields, function(field){//remove invalid fields
+ if(field in selectDef){ delete selectDef[field]; }
+ });
+ if(cells.length > 1){ selectDef.rowSpan = cells.length; }//for complicate layout
+ dojo.forEach(this.cells, function(cell, i){
+ if(cell.index >= 0){
+ cell.index += 1;
+ //console.debug('cell '+ (cell.index - 1) + ' is updated to index ' + cell.index);
+ }else{
+ console.warn('Error:IndirectSelection.addRowSelectCell()- cell ' + i + ' has no index!');
+ }
+ });
+ var rowSelectCell = this.addCellDef(0, 0, selectDef);
+ rowSelectCell.index = 0;
+ firstRow.unshift(rowSelectCell);
+ this.cells.unshift(rowSelectCell);
+ this.grid.rowSelectCell = rowSelectCell;
+ rowSelectCellAdded = true;
+ }
+ }, this);
+ this.cellCount = this.cells.length;
+ },
+ destroy: function(){
+ this.grid.rowSelectCell.destroy();
+ delete this.grid.rowSelectCell;
+ this.inherited(arguments);
+ }
+});
+
+dojo.declare("dojox.grid.cells.RowSelector", dojox.grid.cells._Widget, {
+ // summary:
+ // Common attributes & functions for row selectors(Radio|CheckBox)
+
+ //inputType: String
+ // Input type - Radio|CheckBox
+ inputType: "",
+
+ //map: Object
+ // Cache div refs of radio|checkbox to avoid querying each time
+ map: null,
+
+ //disabledMap: Object
+ // Cache index of disabled rows
+ disabledMap: null,
+
+ //isRowSelector: Boolean
+ // Marker of indirectSelection cell(column)
+ isRowSelector: true,
+
+ //_connects: Array
+ // List of all connections.
+ _connects: null,
+
+ //_subscribes: Array
+ // List of all subscribes.
+ _subscribes: null,
+
+ //checkedText: String
+ // Checked character for high contrast mode
+ checkedText: '&#8730;',
+
+ //unCheckedText: String
+ // Unchecked character for high contrast mode
+ unCheckedText: 'O',
+
+ constructor: function(){
+ this.map = {}; this.disabledMap = {}, this.disabledCount= 0;
+ this._connects = []; this._subscribes = [];
+ this.inA11YMode = dojo.hasClass(dojo.body(), "dijit_a11y");
+
+ this.baseClass = "dojoxGridRowSelector dijitReset dijitInline dijit" + this.inputType;
+ this.checkedClass = " dijit" + this.inputType + "Checked";
+ this.disabledClass = " dijit" + this.inputType + "Disabled";
+ this.checkedDisabledClass = " dijit" + this.inputType + "CheckedDisabled";
+ this.statusTextClass = " dojoxGridRowSelectorStatusText";//a11y use
+
+ this._connects.push(dojo.connect(this.grid, 'dokeyup', this, '_dokeyup'));
+ this._connects.push(dojo.connect(this.grid.selection, 'onSelected', this, '_onSelected'));
+ this._connects.push(dojo.connect(this.grid.selection, 'onDeselected', this, '_onDeselected'));
+ this._connects.push(dojo.connect(this.grid.scroller, 'invalidatePageNode', this, '_pageDestroyed'));
+ this._connects.push(dojo.connect(this.grid, 'onCellClick', this, '_onClick'));
+ this._connects.push(dojo.connect(this.grid, 'updateRow', this, '_onUpdateRow'));
+ },
+ formatter: function(data, rowIndex){
+ // summary:
+ // Overwritten, see dojox.grid.cells._Widget
+ var clazz = this.baseClass;
+ var checked = this.getValue(rowIndex);
+ var disabled = !!this.disabledMap[rowIndex];//normalize 'undefined'
+
+ if(checked){
+ clazz += this.checkedClass;
+ if(disabled){ clazz += this.checkedDisabledClass; }
+ }else if(disabled){
+ clazz += this.disabledClass;
+ }
+ return ["<div tabindex = -1 ",
+ "id = '" + this.grid.id + "_rowSelector_" + rowIndex + "' ",
+ "name = '" + this.grid.id + "_rowSelector' class = '" + clazz + "' ",
+ "role = 'presentation' aria-pressed = '" + checked + "' aria-disabled = '" + disabled +
+ "' aria-label = '" + dojo.string.substitute(this.grid._nls["indirectSelection" + this.inputType], [rowIndex + 1]) + "'>",
+ "<span class = '" + this.statusTextClass + "'>" + (checked ? this.checkedText : this.unCheckedText) + "</span>",
+ "</div>"].join("");
+ },
+ setValue: function(rowIndex, inValue){
+ // summary:
+ // Overwritten, see dojox.grid.cells._Widget
+ // Simply return, no action
+ },
+ getValue: function(rowIndex){
+ // summary:
+ // Overwritten, see dojox.grid.cells._Widget
+ return this.grid.selection.isSelected(rowIndex);
+ },
+ toggleRow: function(index, value){
+ // summary:
+ // toggle checked | unchecked state for given row
+ // index: Integer
+ // Row index
+ // value: Boolean
+ // True - checked | False - unchecked
+ this._nativeSelect(index, value);
+ },
+ setDisabled: function(index, disabled){
+ // summary:
+ // toggle disabled | enabled state for given row
+ // idx: Integer
+ // Row index
+ // disabled: Boolean
+ // True - disabled | False - enabled
+ if(index < 0){ return; }
+ this._toggleDisabledStyle(index, disabled);
+ },
+ disabled: function(index){
+ // summary:
+ // Check if one row is disabled
+ return !!this.disabledMap[index];
+ },
+ _onClick: function(e){
+ // summary:
+ // When mouse click on the selector cell, select/deselect the row.
+ if(e.cell === this){
+ this._selectRow(e);
+ }
+ },
+ _dokeyup: function(e){
+ // summary:
+ // Event handler for key up event
+ // - from dojox.grid.enhanced._Events.dokeyup()
+ // e: Event
+ // Key up event
+ if(e.cellIndex == this.index && e.rowIndex >= 0 && e.keyCode == dojo.keys.SPACE){
+ this._selectRow(e);
+ }
+ },
+ focus: function(rowIndex){
+ // summary:
+ // Set focus to given row
+ // rowIndex: Integer
+ // Target row
+ var selector = this.map[rowIndex];
+ if(selector){ selector.focus(); }
+ },
+ _focusEndingCell: function(rowIndex, cellIndex){
+ // summary:
+ // Set focus to the ending grid cell(rowIndex,cellIndex) when swipe selection finished
+ // rowIndex: Integer
+ // Row index
+ // cellIndex: Integer
+ // Column index
+ var cell = this.grid.getCell(cellIndex);
+ this.grid.focus.setFocusCell(cell, rowIndex);
+ },
+ _nativeSelect: function(index, value){
+ // summary:
+ // Use grid's native selection
+ this.grid.selection[value ? 'select' : 'deselect'](index);
+ },
+ _onSelected: function(index){
+ // summary:
+ // Triggered when a row is selected
+ this._toggleCheckedStyle(index, true);
+ },
+ _onDeselected: function(index){
+ // summary:
+ // Triggered when a row is deselected
+ this._toggleCheckedStyle(index, false);
+ },
+ _onUpdateRow: function(index){
+ // summary:
+ // Clear cache when row is re-built.
+ delete this.map[index];
+ },
+ _toggleCheckedStyle: function(index, value){
+ // summary:
+ // Change css styles for checked | unchecked
+ var selector = this._getSelector(index);
+ if(selector){
+ dojo.toggleClass(selector, this.checkedClass, value);
+ if(this.disabledMap[index]){
+ dojo.toggleClass(selector, this.checkedDisabledClass, value);
+ }
+ dijit.setWaiState(selector, 'pressed', value);
+ if(this.inA11YMode){
+ dojo.attr(selector.firstChild, 'innerHTML', value ? this.checkedText : this.unCheckedText);
+ }
+ }
+ },
+ _toggleDisabledStyle: function(index, disabled){
+ // summary:
+ // Change css styles for disabled | enabled
+ var selector = this._getSelector(index);
+ if(selector){
+ dojo.toggleClass(selector, this.disabledClass, disabled);
+ if(this.getValue(index)){
+ dojo.toggleClass(selector, this.checkedDisabledClass, disabled);
+ }
+ dijit.setWaiState(selector, 'disabled', disabled);
+ }
+ this.disabledMap[index] = disabled;
+ if(index >= 0){
+ this.disabledCount += disabled ? 1 : -1;
+ }
+ },
+ _getSelector: function(index){
+ // summary:
+ // Find selector for given row caching it if 1st time found
+ var selector = this.map[index];
+ if(!selector){//use accurate query for better performance
+ var rowNode = this.view.rowNodes[index];
+ if(rowNode){
+ selector = dojo.query('.dojoxGridRowSelector', rowNode)[0];
+ if(selector){ this.map[index] = selector; }
+ }
+ }
+ return selector;
+ },
+ _pageDestroyed: function(pageIndex){
+ // summary:
+ // Explicitly empty map cache when a page destroyed
+ // See dojox.grid._Scroller.invalidatePageNode()
+ // pageIndex: Integer
+ // Index of destroyed page
+ var rowsPerPage = this.grid.scroller.rowsPerPage;
+ var start = pageIndex * rowsPerPage, end = start + rowsPerPage - 1;
+ for(var i = start; i <= end; i++){
+ if(!this.map[i]){continue;}
+ dojo.destroy(this.map[i]);
+ delete this.map[i];
+ }
+ //console.log("Page ",pageIndex, " destroyed, Map=",this.map);
+ },
+ destroy: function(){
+ for(var i in this.map){
+ dojo.destroy(this.map[i]);
+ delete this.map[i];
+ }
+ for(i in this.disabledMap){ delete this.disabledMap[i]; }
+ dojo.forEach(this._connects, dojo.disconnect);
+ dojo.forEach(this._subscribes, dojo.unsubscribe);
+ delete this._connects;
+ delete this._subscribes;
+ //console.log('Single(Multiple)RowSelector.destroy() executed!');
+ }
+});
+
+dojo.declare("dojox.grid.cells.SingleRowSelector", dojox.grid.cells.RowSelector, {
+ // summary:
+ // IndirectSelection cell(column) for single selection mode, using styles of dijit.form.RadioButton
+ inputType: "Radio",
+
+ _selectRow: function(e){
+ // summary:
+ // Select the target row
+ // e: Event
+ // Event fired on the target row
+ var index = e.rowIndex;
+ if(this.disabledMap[index]){ return; }
+ this._focusEndingCell(index, 0);
+ this._nativeSelect(index, !this.grid.selection.selected[index]);
+ }
+});
+
+dojo.declare("dojox.grid.cells.MultipleRowSelector", dojox.grid.cells.RowSelector, {
+ // summary:
+ // Indirect selection cell for multiple or extended mode, using dijit.form.CheckBox
+ inputType: "CheckBox",
+
+ //swipeStartRowIndex: Integer
+ // Start row index for swipe selection
+ swipeStartRowIndex: -1,
+
+ //swipeMinRowIndex: Integer
+ // Min row index for swipe selection
+ swipeMinRowIndex: -1,
+
+ //swipeMinRowIndex: Integer
+ // Max row index for swipe selection
+ swipeMaxRowIndex: -1,
+
+ //toSelect: Boolean
+ // new state for selection
+ toSelect: false,
+
+ //lastClickRowIdx: Integer
+ // Row index for last click, used for range selection via Shift + click
+ lastClickRowIdx: -1,
+
+ //toggleAllTrigerred: Boolean
+ // Whether toggle all has been triggered or not
+ toggleAllTrigerred: false,
+
+ unCheckedText: '&#9633;',
+
+ constructor: function(){
+ this._connects.push(dojo.connect(dojo.doc, 'onmouseup', this, '_domouseup'));
+ this._connects.push(dojo.connect(this.grid, 'onRowMouseOver', this, '_onRowMouseOver'));
+ this._connects.push(dojo.connect(this.grid.focus, 'move', this, '_swipeByKey'));
+ this._connects.push(dojo.connect(this.grid, 'onCellMouseDown', this, '_onMouseDown'));
+ if(this.headerSelector){//option set by user to add a select-all checkbox in column header
+ this._connects.push(dojo.connect(this.grid.views, 'render', this, '_addHeaderSelector'));
+ this._connects.push(dojo.connect(this.grid, 'onSelectionChanged', this, '_onSelectionChanged'));
+ this._connects.push(dojo.connect(this.grid, 'onKeyDown', this, function(e){
+ if(e.rowIndex == -1 && e.cellIndex == this.index && e.keyCode == dojo.keys.SPACE){
+ this._toggletHeader();//TBD - a better way
+ }
+ }));
+ }
+ },
+ toggleAllSelection:function(checked){
+ // summary:
+ // Toggle select all|deselect all
+ // checked: Boolean
+ // True - select all, False - deselect all
+ var grid = this.grid, selection = grid.selection;
+ if(checked){
+ selection.selectRange(0, grid.rowCount-1);
+ }else{
+ selection.deselectAll();
+ }
+ this.toggleAllTrigerred = true;
+ },
+ _onMouseDown: function(e){
+ if(e.cell == this){
+ this._startSelection(e.rowIndex);
+ dojo.stopEvent(e);
+ }
+ },
+ _onRowMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over a data row(outside of this column).
+ // - from dojox.grid.enhanced._Events.onRowMouseOver()
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this._updateSelection(e, 0);
+ },
+ _domouseup: function(e){
+ // summary:
+ // Event handler for mouse up event - from dojo.doc.domouseup()
+ // e: Event
+ // Mouse up event
+ if(dojo.isIE){
+ this.view.content.decorateEvent(e);//TODO - why only e in IE hasn't been decorated?
+ }
+ var inSwipeSelection = e.cellIndex >= 0 && this.inSwipeSelection() && !this.grid.edit.isEditRow(e.rowIndex);
+ if(inSwipeSelection){
+ this._focusEndingCell(e.rowIndex, e.cellIndex);
+ }
+ this._finishSelect();
+ },
+ _dokeyup: function(e){
+ // summary:
+ // Event handler for key up event
+ // - from dojox.grid.enhanced._Events.dokeyup()
+ // e: Event
+ // Key up event
+ this.inherited(arguments);
+ if(!e.shiftKey){
+ this._finishSelect();
+ }
+ },
+ _startSelection: function(rowIndex){
+ // summary:
+ // Initialize parameters to start a new swipe selection
+ // rowIndex: Integer
+ // Index of the start row
+ this.swipeStartRowIndex = this.swipeMinRowIndex = this.swipeMaxRowIndex = rowIndex;
+ this.toSelect = !this.getValue(rowIndex);
+ },
+ _updateSelection: function(e, delta){
+ // summary:
+ // Update row selections, fired during a swipe selection
+ // e: Event
+ // Event of the current row,
+ // delta: Integer
+ // Row index delta, used for swipe selection via Shift + Arrow key
+ // 0: not via key, -1 : Shift + Up, 1 : Shift + Down
+ if(!this.inSwipeSelection()){ return; }
+
+ var byKey = delta !== 0;//whether via Shift + Arrow Key
+ var currRow = e.rowIndex, deltaRow = currRow - this.swipeStartRowIndex + delta;
+ if(deltaRow > 0 && this.swipeMaxRowIndex < currRow + delta){
+ this.swipeMaxRowIndex = currRow + delta;
+ }
+ if(deltaRow < 0 && this.swipeMinRowIndex > currRow + delta){
+ this.swipeMinRowIndex = currRow + delta;
+ }
+
+ var min = deltaRow > 0 ? this.swipeStartRowIndex : currRow + delta;
+ var max = deltaRow > 0 ? currRow + delta : this.swipeStartRowIndex;
+ for(var i = this.swipeMinRowIndex; i <= this.swipeMaxRowIndex; i++){
+ if(this.disabledMap[i] || i < 0){ continue; }
+ if(i >= min && i <= max){//deltaRow != 0 || this.toSelect
+ this._nativeSelect(i, this.toSelect);
+ }else if(!byKey){
+ this._nativeSelect(i, !this.toSelect);
+ }
+ }
+ },
+ _swipeByKey: function(rowOffset, colOffset, e){
+ // summary:
+ // Update row selections, fired when Shift + Cursor is used for swipe selection
+ // See dojox.grid.enhanced._Events.onKeyDown
+ // e: Event
+ // Event of the current row,
+ // rowOffset: Integer
+ // Row offset, used for swipe selection via Shift + Cursor
+ // -1 : Shift + Up, 1 : Shift + Down
+ if(!e || rowOffset === 0 || !e.shiftKey || e.cellIndex != this.index ||
+ this.grid.focus.rowIndex < 0){ //TBD - e.rowIndex == 0 && delta == -1
+ return;
+ }
+ var rowIndex = e.rowIndex;
+ if(this.swipeStartRowIndex < 0){
+ //A new swipe selection starts via Shift + Arrow key
+ this.swipeStartRowIndex = rowIndex;
+ if(rowOffset > 0){//Shift + Down
+ this.swipeMaxRowIndex = rowIndex + rowOffset;
+ this.swipeMinRowIndex = rowIndex;
+ }else{//Shift + UP
+ this.swipeMinRowIndex = rowIndex + rowOffset;
+ this.swipeMaxRowIndex = rowIndex;
+ }
+ this.toSelect = this.getValue(rowIndex);
+ }
+ this._updateSelection(e, rowOffset);
+ },
+ _finishSelect: function(){
+ // summary:
+ // Reset parameters to end a swipe selection
+ this.swipeStartRowIndex = -1;
+ this.swipeMinRowIndex = -1;
+ this.swipeMaxRowIndex = -1;
+ this.toSelect = false;
+ },
+ inSwipeSelection: function(){
+ // summary:
+ // Check if during a swipe selection
+ // return: Boolean
+ // Whether in swipe selection
+ return this.swipeStartRowIndex >= 0;
+ },
+ _nativeSelect: function(index, value){
+ // summary:
+ // Overwritten
+ this.grid.selection[value ? 'addToSelection' : 'deselect'](index);
+ },
+ _selectRow: function(e){
+ // summary:
+ // Select the target row or range or rows
+ // e: Event
+ // Event fired on the target row
+ var rowIndex = e.rowIndex;
+ if(this.disabledMap[rowIndex]){ return; }
+ dojo.stopEvent(e);
+ this._focusEndingCell(rowIndex, 0);
+
+ var delta = rowIndex - this.lastClickRowIdx;
+ var newValue = !this.grid.selection.selected[rowIndex];
+ if(this.lastClickRowIdx >= 0 && !e.ctrlKey && !e.altKey && e.shiftKey){
+ var min = delta > 0 ? this.lastClickRowIdx : rowIndex;
+ var max = delta > 0 ? rowIndex : this.lastClickRowIdx;
+ for(var i = min; i >= 0 && i <= max; i++){
+ this._nativeSelect(i, newValue);
+ }
+ }else{
+ this._nativeSelect(rowIndex, newValue);
+ }
+ this.lastClickRowIdx = rowIndex;
+ },
+ getValue: function(rowIndex){
+ // summary:
+ // Overwritten
+ if(rowIndex == -1){//header selector
+ var g = this.grid;
+ return g.rowCount > 0 && g.rowCount <= g.selection.getSelectedCount();
+ }
+ return this.inherited(arguments);
+ },
+ _addHeaderSelector: function(){
+ // summary:
+ // Add selector in column header for selecting|deselecting all
+ var headerCellNode = this.view.getHeaderCellNode(this.index);
+ if(!headerCellNode){ return; }
+ dojo.empty(headerCellNode);
+ var g = this.grid;
+ var selector = headerCellNode.appendChild(dojo.create("div", {
+ "tabindex": -1, "id": g.id + "_rowSelector_-1", "class": this.baseClass, "role": "presentation",
+ "innerHTML": "<span class = '" + this.statusTextClass +
+ "'></span><span style='height: 0; width: 0; overflow: hidden; display: block;'>" +
+ g._nls["selectAll"] + "</span>"
+ }));
+ this.map[-1] = selector;
+ var idx = this._headerSelectorConnectIdx;
+ if(idx !== undefined){
+ dojo.disconnect(this._connects[idx]);
+ this._connects.splice(idx, 1);
+ }
+ this._headerSelectorConnectIdx = this._connects.length;
+ this._connects.push(dojo.connect(selector, 'onclick', this, '_toggletHeader'));
+ this._onSelectionChanged();
+ },
+ _toggletHeader: function(){
+ // summary:
+ // Toggle state for head selector
+ if(!!this.disabledMap[-1]){ return; }
+ this.grid._selectingRange = true;
+ this.toggleAllSelection(!this.getValue(-1));
+ this._onSelectionChanged();
+ this.grid._selectingRange = false;
+ },
+ _onSelectionChanged: function(){
+ // summary:
+ // Update header selector anytime selection changed
+ var g = this.grid;
+ if(!this.map[-1] || g._selectingRange){ return; }
+ this._toggleCheckedStyle(-1, this.getValue(-1));
+ },
+ _toggleDisabledStyle: function(index, disabled){
+ // summary:
+ // Overwritten
+ this.inherited(arguments);
+ if(this.headerSelector){
+ var allDisabled = (this.grid.rowCount == this.disabledCount);
+ if(allDisabled != !!this.disabledMap[-1]){//only if needed
+ arguments[0] = -1;
+ arguments[1] = allDisabled;
+ this.inherited(arguments);
+ }
+ }
+ }
+});
+
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.IndirectSelection/*name:'indirectSelection'*/, {"preInit": true});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Menu.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Menu.js
new file mode 100644
index 0000000..bcc09ef
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Menu.js
@@ -0,0 +1,131 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.Menu"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Menu"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Menu");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+
+dojo.declare("dojox.grid.enhanced.plugins.Menu", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provides context menu support, including header menu, row menu, cell menu and selected region menu
+ // example:
+ // <div dojoType="dojox.grid.EnhancedGrid"
+ // plugins="{menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",
+ // selectedRegionMenu:"selectedRegionMenuId"}}" ...>
+ // </div>
+
+ //name: String
+ // Plugin name
+ name: "menus",
+
+ //name: [const] Array
+ // menu types
+ types: ['headerMenu', 'rowMenu', 'cellMenu', 'selectedRegionMenu'],
+
+ constructor: function(){
+ var g = this.grid;
+ g.showMenu = dojo.hitch(g, this.showMenu);
+ g._setRowMenuAttr = dojo.hitch(this, '_setRowMenuAttr');
+ g._setCellMenuAttr = dojo.hitch(this, '_setCellMenuAttr');
+ g._setSelectedRegionMenuAttr = dojo.hitch(this, '_setSelectedRegionMenuAttr');
+ },
+ onStartUp: function(){
+ var type, option = this.option;
+ for(type in option){
+ if(dojo.indexOf(this.types, type) >= 0 && option[type]){
+ this._initMenu(type, option[type]);
+ }
+ }
+ },
+ _initMenu: function(/*String*/menuType, /*String | Widget(dijit.Menu)*/menu){
+ var g = this.grid;
+ if(!g[menuType]){//in case already created in _Grid.postCreate()
+ var m = this._getMenuWidget(menu);
+ if(!m){return;}
+ g.set(menuType, m);
+ if(menuType != "headerMenu"){
+ m._scheduleOpen = function(){return;};
+ }
+ }
+ },
+ _getMenuWidget: function(/*String|Widget(dijit.Menu)*/menu){
+ // summary:
+ // Fetch the required menu widget(should already been created)
+ return (menu instanceof dijit.Menu) ? menu : dijit.byId(menu);
+ },
+ _setRowMenuAttr: function(/*Widget(dijit.Menu)*/menu){
+ // summary:
+ // Set row menu widget
+ this._setMenuAttr(menu, 'rowMenu');
+ },
+ _setCellMenuAttr: function(/*Widget(dijit.Menu)*/menu){
+ // summary:
+ // Set cell menu widget
+ this._setMenuAttr(menu, 'cellMenu');
+ },
+ _setSelectedRegionMenuAttr: function(/*Widget(dijit.Menu)*/menu){
+ // summary:
+ // Set row menu widget
+ this._setMenuAttr(menu, 'selectedRegionMenu');
+ },
+ _setMenuAttr: function(/*Widget(dijit.Menu)*/menu, /*String*/menuType){
+ // summary:
+ // Bind menus to Grid.
+ var g = this.grid, n = g.domNode;
+ if(!menu || !(menu instanceof dijit.Menu)){
+ console.warn(menuType, " of Grid ", g.id, " is not existed!");
+ return;
+ }
+ if(g[menuType]){
+ g[menuType].unBindDomNode(n);
+ }
+ g[menuType] = menu;
+ g[menuType].bindDomNode(n);
+ },
+ showMenu: function(/*Event*/e){
+ // summary:
+ // Show appropriate context menu
+ // Fired from dojox.grid.enhanced._Events.onRowContextMenu, 'this' scope - Grid
+ // TODO: test Shift-F10
+ var inSelectedRegion = (e.cellNode && dojo.hasClass(e.cellNode, 'dojoxGridRowSelected') ||
+ e.rowNode && (dojo.hasClass(e.rowNode, 'dojoxGridRowSelected') || dojo.hasClass(e.rowNode, 'dojoxGridRowbarSelected')));
+
+ if(inSelectedRegion && this.selectedRegionMenu){
+ this.onSelectedRegionContextMenu(e);
+ return;
+ }
+
+ var info = {target: e.target, coords: e.keyCode !== dojo.keys.F10 && "pageX" in e ? {x: e.pageX, y: e.pageY } : null};
+ if(this.rowMenu && (this.selection.isSelected(e.rowIndex) || e.rowNode && dojo.hasClass(e.rowNode, 'dojoxGridRowbar'))){
+ this.rowMenu._openMyself(info);
+ dojo.stopEvent(e);
+ return;
+ }
+
+ if(this.cellMenu){
+ this.cellMenu._openMyself(info);
+ }
+ dojo.stopEvent(e);
+ },
+ destroy: function(){
+ // summary:
+ // Destroy all resources.
+ // _Grid.destroy() will unbind headerMenu
+ var g = this.grid;
+ if(g.headerMenu){g.headerMenu.unBindDomNode(g.viewsHeaderNode);}
+ if(g.rowMenu){g.rowMenu.unBindDomNode(g.domNode);}
+ if(g.cellMenu){g.cellMenu.unBindDomNode(g.domNode);}
+ if(g.selectedRegionMenu){g.selectedRegionMenu.destroy();}
+ this.inherited(arguments);
+ }
+});
+
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Menu/*name:'menus'*/);
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Menu.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Menu.xd.js
new file mode 100644
index 0000000..fc4f7e1
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Menu.xd.js
@@ -0,0 +1,136 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.Menu"],
+["require", "dojox.grid.enhanced._Plugin"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.Menu"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Menu"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Menu");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+
+dojo.declare("dojox.grid.enhanced.plugins.Menu", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provides context menu support, including header menu, row menu, cell menu and selected region menu
+ // example:
+ // <div dojoType="dojox.grid.EnhancedGrid"
+ // plugins="{menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",
+ // selectedRegionMenu:"selectedRegionMenuId"}}" ...>
+ // </div>
+
+ //name: String
+ // Plugin name
+ name: "menus",
+
+ //name: [const] Array
+ // menu types
+ types: ['headerMenu', 'rowMenu', 'cellMenu', 'selectedRegionMenu'],
+
+ constructor: function(){
+ var g = this.grid;
+ g.showMenu = dojo.hitch(g, this.showMenu);
+ g._setRowMenuAttr = dojo.hitch(this, '_setRowMenuAttr');
+ g._setCellMenuAttr = dojo.hitch(this, '_setCellMenuAttr');
+ g._setSelectedRegionMenuAttr = dojo.hitch(this, '_setSelectedRegionMenuAttr');
+ },
+ onStartUp: function(){
+ var type, option = this.option;
+ for(type in option){
+ if(dojo.indexOf(this.types, type) >= 0 && option[type]){
+ this._initMenu(type, option[type]);
+ }
+ }
+ },
+ _initMenu: function(/*String*/menuType, /*String | Widget(dijit.Menu)*/menu){
+ var g = this.grid;
+ if(!g[menuType]){//in case already created in _Grid.postCreate()
+ var m = this._getMenuWidget(menu);
+ if(!m){return;}
+ g.set(menuType, m);
+ if(menuType != "headerMenu"){
+ m._scheduleOpen = function(){return;};
+ }
+ }
+ },
+ _getMenuWidget: function(/*String|Widget(dijit.Menu)*/menu){
+ // summary:
+ // Fetch the required menu widget(should already been created)
+ return (menu instanceof dijit.Menu) ? menu : dijit.byId(menu);
+ },
+ _setRowMenuAttr: function(/*Widget(dijit.Menu)*/menu){
+ // summary:
+ // Set row menu widget
+ this._setMenuAttr(menu, 'rowMenu');
+ },
+ _setCellMenuAttr: function(/*Widget(dijit.Menu)*/menu){
+ // summary:
+ // Set cell menu widget
+ this._setMenuAttr(menu, 'cellMenu');
+ },
+ _setSelectedRegionMenuAttr: function(/*Widget(dijit.Menu)*/menu){
+ // summary:
+ // Set row menu widget
+ this._setMenuAttr(menu, 'selectedRegionMenu');
+ },
+ _setMenuAttr: function(/*Widget(dijit.Menu)*/menu, /*String*/menuType){
+ // summary:
+ // Bind menus to Grid.
+ var g = this.grid, n = g.domNode;
+ if(!menu || !(menu instanceof dijit.Menu)){
+ console.warn(menuType, " of Grid ", g.id, " is not existed!");
+ return;
+ }
+ if(g[menuType]){
+ g[menuType].unBindDomNode(n);
+ }
+ g[menuType] = menu;
+ g[menuType].bindDomNode(n);
+ },
+ showMenu: function(/*Event*/e){
+ // summary:
+ // Show appropriate context menu
+ // Fired from dojox.grid.enhanced._Events.onRowContextMenu, 'this' scope - Grid
+ // TODO: test Shift-F10
+ var inSelectedRegion = (e.cellNode && dojo.hasClass(e.cellNode, 'dojoxGridRowSelected') ||
+ e.rowNode && (dojo.hasClass(e.rowNode, 'dojoxGridRowSelected') || dojo.hasClass(e.rowNode, 'dojoxGridRowbarSelected')));
+
+ if(inSelectedRegion && this.selectedRegionMenu){
+ this.onSelectedRegionContextMenu(e);
+ return;
+ }
+
+ var info = {target: e.target, coords: e.keyCode !== dojo.keys.F10 && "pageX" in e ? {x: e.pageX, y: e.pageY } : null};
+ if(this.rowMenu && (this.selection.isSelected(e.rowIndex) || e.rowNode && dojo.hasClass(e.rowNode, 'dojoxGridRowbar'))){
+ this.rowMenu._openMyself(info);
+ dojo.stopEvent(e);
+ return;
+ }
+
+ if(this.cellMenu){
+ this.cellMenu._openMyself(info);
+ }
+ dojo.stopEvent(e);
+ },
+ destroy: function(){
+ // summary:
+ // Destroy all resources.
+ // _Grid.destroy() will unbind headerMenu
+ var g = this.grid;
+ if(g.headerMenu){g.headerMenu.unBindDomNode(g.viewsHeaderNode);}
+ if(g.rowMenu){g.rowMenu.unBindDomNode(g.domNode);}
+ if(g.cellMenu){g.cellMenu.unBindDomNode(g.domNode);}
+ if(g.selectedRegionMenu){g.selectedRegionMenu.destroy();}
+ this.inherited(arguments);
+ }
+});
+
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Menu/*name:'menus'*/);
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/NestedSorting.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/NestedSorting.js
new file mode 100644
index 0000000..f44ff85
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/NestedSorting.js
@@ -0,0 +1,579 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.NestedSorting"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.NestedSorting"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.NestedSorting");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+
+dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provides nested sorting feature
+ //
+ // description:
+ // A flexible way to control multiple column sorting, including
+ // 1. Set default sorting order
+ // 2. Disable sorting for certain columns
+ // 3. Set sorting order dynamically with JS API
+ //
+ // example:
+ // | <script type="text/javascript">
+ // | var grid = new dojox.grid.EnhancedGrid({plugins : {nestedSorting: true}},
+ // | sortFields: [{attribute: 'col4', descending: false},...],//set default sorting order
+ // | canSort: function(index, field){ return true},//disable sorting for a column
+ // | ... }, dojo.byId('gridDiv'));
+ // | grid.startup();
+ // | //set new sorting order
+ // | grid.setSortIndex([{attribute: 'col3', descending: true},...])
+ // | </script>
+
+ // name: String
+ // Plugin name
+ name: "nestedSorting",
+
+ _currMainSort: 'none',//'none'|'asc'|'desc'
+
+ _currRegionIdx: -1,
+
+ _a11yText: {
+ 'dojoxGridDescending' : '&#9662;',
+ 'dojoxGridAscending' : '&#9652;',
+ 'dojoxGridAscendingTip' : '&#1784;',
+ 'dojoxGridDescendingTip': '&#1783;',
+ 'dojoxGridUnsortedTip' : 'x' //'&#10006;'
+ },
+
+ constructor: function(){
+ this._sortDef = [];
+ this._sortData = {};
+ this._headerNodes = {};
+ //column index that are hidden, un-sortable or indirect selection etc.
+ this._excludedColIdx = [];
+ this.nls = this.grid._nls;
+ this.grid.setSortInfo = function(){};
+ this.grid.setSortIndex = dojo.hitch(this, '_setGridSortIndex');
+ this.grid.getSortProps = dojo.hitch(this, 'getSortProps');
+ if(this.grid.sortFields){
+ this._setGridSortIndex(this.grid.sortFields, null, true);
+ }
+ this.connect(this.grid.views, 'render', '_initSort');//including column resize
+ this.initCookieHandler();
+ },
+ onStartUp: function(){
+ //overwrite base Grid functions
+ this.inherited(arguments);
+ this.connect(this.grid, 'onHeaderCellClick', '_onHeaderCellClick');
+ this.connect(this.grid, 'onHeaderCellMouseOver', '_onHeaderCellMouseOver');
+ this.connect(this.grid, 'onHeaderCellMouseOut', '_onHeaderCellMouseOut');
+ },
+ _setGridSortIndex: function(inIndex, inAsc, noRefresh){
+ if(dojo.isArray(inIndex)){
+ var i, d, cell;
+ for(i = 0; i < inIndex.length; i++){
+ d = inIndex[i];
+ cell = this.grid.getCellByField(d.attribute);
+ if(!cell){
+ console.warn('Invalid sorting option, column ', d.attribute, ' not found.');
+ return;
+ }
+ if(cell['nosort'] || !this.grid.canSort(cell.index, cell.field)){
+ console.warn('Invalid sorting option, column ', d.attribute, ' is unsortable.');
+ return;
+ }
+ }
+ this.clearSort();
+ dojo.forEach(inIndex, function(d, i){
+ cell = this.grid.getCellByField(d.attribute);
+ this.setSortData(cell.index, 'index', i);
+ this.setSortData(cell.index, 'order', d.descending ? 'desc': 'asc');
+ }, this);
+ }else if(!isNaN(inIndex)){
+ if(inAsc === undefined){ return; }//header click from base DataGrid
+ this.setSortData(inIndex, 'order', inAsc ? 'asc' : 'desc');
+ }else{
+ return;
+ }
+ this._updateSortDef();
+ if(!noRefresh){
+ this.grid.sort();
+ }
+ },
+ getSortProps: function(){
+ // summary:
+ // Overwritten, see DataGrid.getSortProps()
+ return this._sortDef.length ? this._sortDef : null;
+ },
+ _initSort: function(postSort){
+ // summary:
+ // Initiate sorting
+ var g = this.grid, n = g.domNode, len = this._sortDef.length;
+ dojo.toggleClass(n, 'dojoxGridSorted', !!len);
+ dojo.toggleClass(n, 'dojoxGridSingleSorted', len === 1);
+ dojo.toggleClass(n, 'dojoxGridNestSorted', len > 1);
+ if(len > 0){
+ this._currMainSort = this._sortDef[0].descending ? 'desc' : 'asc';
+ }
+ var idx, excluded = this._excludedCoIdx = [];//reset it
+ //cache column index of hidden, un-sortable or indirect selection
+ this._headerNodes = dojo.query("th", g.viewsHeaderNode).forEach(function(n){
+ idx = parseInt(dojo.attr(n, 'idx'), 10);
+ if(dojo.style(n, 'display') === 'none' || g.layout.cells[idx]['nosort'] || (g.canSort && !g.canSort(idx, g.layout.cells[idx]['field']))){
+ excluded.push(idx);
+ }
+ });
+ this._headerNodes.forEach(this._initHeaderNode, this);
+ this._initFocus();
+ if(postSort){
+ this._focusHeader();
+ }
+ },
+ _initHeaderNode: function(node){
+ // summary:
+ // Initiate sort for each header cell node
+ var sortNode = dojo.query('.dojoxGridSortNode', node)[0];
+ if(sortNode){
+ dojo.toggleClass(sortNode, 'dojoxGridSortNoWrap', true);
+ }
+ if(dojo.indexOf(this._excludedCoIdx, dojo.attr(node,'idx')) >= 0){
+ dojo.addClass(node, 'dojoxGridNoSort');
+ return;
+ }
+ if(!dojo.query('.dojoxGridSortBtn', node).length){
+ //clear any previous connects
+ this._connects = dojo.filter(this._connects, function(conn){
+ if(conn._sort){
+ dojo.disconnect(conn);
+ return false;
+ }
+ return true;
+ });
+ var n = dojo.create('a', {
+ className: 'dojoxGridSortBtn dojoxGridSortBtnNested',
+ title: this.nls.nestedSort + ' - ' + this.nls.ascending,
+ innerHTML: '1'
+ }, node.firstChild, 'last');
+ var h = this.connect(n, "onmousedown", dojo.stopEvent);
+ h._sort = true;
+ n = dojo.create('a', {
+ className: 'dojoxGridSortBtn dojoxGridSortBtnSingle',
+ title: this.nls.singleSort + ' - ' + this.nls.ascending
+ }, node.firstChild, 'last');
+ h = this.connect(n, "onmousedown", dojo.stopEvent);
+ h._sort = true;
+ }else{
+ //deal with small height grid which doesn't re-render the grid after refresh
+ var a1 = dojo.query('.dojoxGridSortBtnSingle', node)[0];
+ var a2 = dojo.query('.dojoxGridSortBtnNested', node)[0];
+ a1.className = 'dojoxGridSortBtn dojoxGridSortBtnSingle';
+ a2.className = 'dojoxGridSortBtn dojoxGridSortBtnNested';
+ a2.innerHTML = '1';
+ dojo.removeClass(node, 'dojoxGridCellShowIndex');
+ dojo.removeClass(node.firstChild, 'dojoxGridSortNodeSorted');
+ dojo.removeClass(node.firstChild, 'dojoxGridSortNodeAsc');
+ dojo.removeClass(node.firstChild, 'dojoxGridSortNodeDesc');
+ dojo.removeClass(node.firstChild, 'dojoxGridSortNodeMain');
+ dojo.removeClass(node.firstChild, 'dojoxGridSortNodeSub');
+ }
+ this._updateHeaderNodeUI(node);
+ },
+ _onHeaderCellClick: function(e){
+ // summary
+ // See dojox.grid.enhanced._Events._onHeaderCellClick()
+ this._focusRegion(e.target);
+ if(dojo.hasClass(e.target, 'dojoxGridSortBtn')){
+ this._onSortBtnClick(e);
+ dojo.stopEvent(e);
+ this._focusRegion(this._getCurrentRegion());
+ }
+ },
+ _onHeaderCellMouseOver: function(e){
+ // summary
+ // See dojox.grid._Events._onHeaderCellMouseOver()
+ // When user mouseover other columns than sorted column in a single sorted grid,
+ // We need to show 1 in the sorted column
+ if(!e.cell){return; }
+ if(this._sortDef.length > 1){ return; }
+ if(this._sortData[e.cellIndex] && this._sortData[e.cellIndex].index === 0){ return; }
+ var p;
+ for(p in this._sortData){
+ if(this._sortData[p].index === 0){
+ dojo.addClass(this._headerNodes[p], 'dojoxGridCellShowIndex');
+ break;
+ }
+ }
+ if(!dojo.hasClass(dojo.body(), 'dijit_a11y')){ return; }
+ //a11y support
+ var i = e.cell.index, node = e.cellNode;
+ var singleSortBtn = dojo.query('.dojoxGridSortBtnSingle', node)[0];
+ var nestedSortBtn = dojo.query('.dojoxGridSortBtnNested', node)[0];
+
+ var sortMode = 'none';
+ if(dojo.hasClass(this.grid.domNode, 'dojoxGridSingleSorted')){
+ sortMode = 'single';
+ }else if(dojo.hasClass(this.grid.domNode, 'dojoxGridNestSorted')){
+ sortMode = 'nested';
+ }
+ var nestedIndex = dojo.attr(nestedSortBtn, 'orderIndex');
+ if(nestedIndex === null || nestedIndex === undefined){
+ dojo.attr(nestedSortBtn, 'orderIndex', nestedSortBtn.innerHTML);
+ nestedIndex = nestedSortBtn.innerHTML;
+ }
+ if(this.isAsc(i)){
+ nestedSortBtn.innerHTML = nestedIndex + this._a11yText.dojoxGridDescending;
+ }else if(this.isDesc(i)){
+ nestedSortBtn.innerHTML = nestedIndex + this._a11yText.dojoxGridUnsortedTip;
+ }else{
+ nestedSortBtn.innerHTML = nestedIndex + this._a11yText.dojoxGridAscending;
+ }
+ if(this._currMainSort === 'none'){
+ singleSortBtn.innerHTML = this._a11yText.dojoxGridAscending;
+ }else if(this._currMainSort === 'asc'){
+ singleSortBtn.innerHTML = this._a11yText.dojoxGridDescending;
+ }else if(this._currMainSort === 'desc'){
+ singleSortBtn.innerHTML = this._a11yText.dojoxGridUnsortedTip;
+ }
+ },
+ _onHeaderCellMouseOut: function(e){
+ // summary
+ // See dojox.grid.enhanced._Events._onHeaderCellMouseOut()
+ var p;
+ for(p in this._sortData){
+ if(this._sortData[p].index === 0){
+ dojo.removeClass(this._headerNodes[p], 'dojoxGridCellShowIndex');
+ break;
+ }
+ }
+ },
+ _onSortBtnClick: function(e){
+ // summary:
+ // If the click target is single sort button, do single sort.
+ // Else if the click target is nested sort button, do nest sort.
+ // Otherwise return.
+ var cellIdx = e.cell.index;
+ if(dojo.hasClass(e.target, 'dojoxGridSortBtnSingle')){
+ this._prepareSingleSort(cellIdx);
+ }else if(dojo.hasClass(e.target, 'dojoxGridSortBtnNested')){
+ this._prepareNestedSort(cellIdx);
+ }else{
+ return;
+ }
+ dojo.stopEvent(e);
+ this._doSort(cellIdx);
+ },
+ _doSort: function(cellIdx){
+ if(!this._sortData[cellIdx] || !this._sortData[cellIdx].order){
+ this.setSortData(cellIdx, 'order', 'asc'); //no sorting data
+ }else if(this.isAsc(cellIdx)){
+ this.setSortData(cellIdx, 'order', 'desc'); //change to 'desc'
+ }else if(this.isDesc(cellIdx)){
+ this.removeSortData(cellIdx); //remove from sorting sequence
+ }
+ this._updateSortDef();
+ this.grid.sort();
+ this._initSort(true);
+ },
+ setSortData: function(cellIdx, attr, value){
+ // summary:
+ // Set sorting data for a column.
+ var sd = this._sortData[cellIdx];
+ if(!sd){
+ sd = this._sortData[cellIdx] = {};
+ }
+ sd[attr] = value;
+ },
+ removeSortData: function(cellIdx){
+ var d = this._sortData, i = d[cellIdx].index, p;
+ delete d[cellIdx];
+ for(p in d){
+ if(d[p].index > i){
+ d[p].index--;
+ }
+ }
+ },
+ _prepareSingleSort: function(cellIdx){
+ // summary:
+ // Prepare the single sort, also called main sort, this will clear any existing sorting and just sort the grid by current column.
+ var d = this._sortData, p;
+ for(p in d){
+ delete d[p];
+ }
+ this.setSortData(cellIdx, 'index', 0);
+ this.setSortData(cellIdx, 'order', this._currMainSort === 'none' ? null : this._currMainSort);
+ if(!this._sortData[cellIdx] || !this._sortData[cellIdx].order){
+ this._currMainSort = 'asc';
+ }else if(this.isAsc(cellIdx)){
+ this._currMainSort = 'desc';
+ }else if(this.isDesc(cellIdx)){
+ this._currMainSort = 'none';
+ }
+ },
+ _prepareNestedSort: function(cellIdx){
+ // summary
+ // Prepare the nested sorting, this will order the column on existing sorting result.
+ var i = this._sortData[cellIdx] ? this._sortData[cellIdx].index : null;
+ if(i === 0 || !!i){ return; }
+ this.setSortData(cellIdx, 'index', this._sortDef.length);
+ },
+ _updateSortDef: function(){
+ this._sortDef.length = 0;
+ var d = this._sortData, p;
+ for(p in d){
+ this._sortDef[d[p].index] = {
+ attribute: this.grid.layout.cells[p].field,
+ descending: d[p].order === 'desc'
+ };
+ }
+ },
+ _updateHeaderNodeUI: function(node){
+ // summary:
+ // Update the column header UI based on current sorting state.
+ // Show indicator of the sorting order of the column, no order no indicator
+ var cell = this._getCellByNode(node);
+ var cellIdx = cell.index;
+ var data = this._sortData[cellIdx];
+ var sortNode = dojo.query('.dojoxGridSortNode', node)[0];
+ var singleSortBtn = dojo.query('.dojoxGridSortBtnSingle', node)[0];
+ var nestedSortBtn = dojo.query('.dojoxGridSortBtnNested', node)[0];
+
+ dojo.toggleClass(singleSortBtn, 'dojoxGridSortBtnAsc', this._currMainSort === 'asc');
+ dojo.toggleClass(singleSortBtn, 'dojoxGridSortBtnDesc', this._currMainSort === 'desc');
+ if(this._currMainSort === 'asc'){
+ singleSortBtn.title = this.nls.singleSort + ' - ' + this.nls.descending;
+ }else if(this._currMainSort === 'desc'){
+ singleSortBtn.title = this.nls.singleSort + ' - ' + this.nls.unsorted;
+ }else{
+ singleSortBtn.title = this.nls.singleSort + ' - ' + this.nls.ascending;
+ }
+
+ var _this = this;
+ function setWaiState(){
+ var columnInfo = 'Column ' + (cell.index + 1) + ' ' + cell.field;
+ var orderState = 'none';
+ var orderAction = 'ascending';
+ if(data){
+ orderState = data.order === 'asc' ? 'ascending' : 'descending';
+ orderAction = data.order === 'asc' ? 'descending' : 'none';
+ }
+ var a11ySingleLabel = columnInfo + ' - is sorted by ' + orderState;
+ var a11yNestedLabel = columnInfo + ' - is nested sorted by ' + orderState;
+ var a11ySingleLabelHover = columnInfo + ' - choose to sort by ' + orderAction;
+ var a11yNestedLabelHover = columnInfo + ' - choose to nested sort by ' + orderAction;
+
+ dijit.setWaiState(singleSortBtn, 'label', a11ySingleLabel);
+ dijit.setWaiState(nestedSortBtn, 'label', a11yNestedLabel);
+
+ var handles = [
+ _this.connect(singleSortBtn, "onmouseover", function(){
+ dijit.setWaiState(singleSortBtn, 'label', a11ySingleLabelHover);
+ }),
+ _this.connect(singleSortBtn, "onmouseout", function(){
+ dijit.setWaiState(singleSortBtn, 'label', a11ySingleLabel);
+ }),
+ _this.connect(nestedSortBtn, "onmouseover", function(){
+ dijit.setWaiState(nestedSortBtn, 'label', a11yNestedLabelHover);
+ }),
+ _this.connect(nestedSortBtn, "onmouseout", function(){
+ dijit.setWaiState(nestedSortBtn, 'label', a11yNestedLabel);
+ })
+ ];
+ dojo.forEach(handles, function(handle){ handle._sort = true; });
+ }
+ setWaiState();
+
+ var a11y = dojo.hasClass(dojo.body(), "dijit_a11y");
+ if(!data){
+ nestedSortBtn.innerHTML = this._sortDef.length + 1;
+ return;
+ }
+ if(data.index || (data.index === 0 && this._sortDef.length > 1)){
+ nestedSortBtn.innerHTML = data.index + 1;
+ }
+ dojo.addClass(sortNode, 'dojoxGridSortNodeSorted');
+ if(this.isAsc(cellIdx)){
+ dojo.addClass(sortNode, 'dojoxGridSortNodeAsc');
+ nestedSortBtn.title = this.nls.nestedSort + ' - ' + this.nls.descending;
+ if(a11y){sortNode.innerHTML = this._a11yText.dojoxGridAscendingTip;}
+ }else if(this.isDesc(cellIdx)){
+ dojo.addClass(sortNode, 'dojoxGridSortNodeDesc');
+ nestedSortBtn.title = this.nls.nestedSort + ' - ' + this.nls.unsorted;
+ if(a11y){sortNode.innerHTML = this._a11yText.dojoxGridDescendingTip;}
+ }
+ dojo.addClass(sortNode, (data.index === 0 ? 'dojoxGridSortNodeMain' : 'dojoxGridSortNodeSub'));
+ },
+ isAsc: function(cellIndex){
+ return this._sortData[cellIndex].order === 'asc';
+ },
+ isDesc: function(cellIndex){
+ return this._sortData[cellIndex].order === 'desc';
+ },
+ _getCellByNode: function(node){
+ var i;
+ for(i = 0; i < this._headerNodes.length; i++){
+ if(this._headerNodes[i] === node){
+ return this.grid.layout.cells[i];
+ }
+ }
+ return null;
+ },
+ clearSort: function(){
+ this._sortData = {};
+ this._sortDef.length = 0;
+ },
+
+ //persistence
+ initCookieHandler: function(){
+ if(this.grid.addCookieHandler){
+ this.grid.addCookieHandler({
+ name: "sortOrder",
+ onLoad: dojo.hitch(this, '_loadNestedSortingProps'),
+ onSave: dojo.hitch(this, '_saveNestedSortingProps')
+ });
+ }
+ },
+ _loadNestedSortingProps: function(sortInfo, grid){
+ this._setGridSortIndex(sortInfo);
+ },
+ _saveNestedSortingProps: function(grid){
+ return this.getSortProps();
+ },
+
+ //focus & keyboard
+ _initFocus: function(){
+ var f = this.focus = this.grid.focus;
+ this._focusRegions = this._getRegions();
+ if(!this._headerArea){
+ var area = this._headerArea = f.getArea('header');
+ area.onFocus = f.focusHeader = dojo.hitch(this, '_focusHeader');
+ area.onBlur = f.blurHeader = f._blurHeader = dojo.hitch(this, '_blurHeader');
+ area.onMove = dojo.hitch(this, '_onMove');
+ area.onKeyDown = dojo.hitch(this, '_onKeyDown');
+ area._regions = [];
+ area.getRegions = null;
+ this.connect(this.grid, 'onBlur', '_blurHeader');
+ }
+ },
+ _focusHeader: function(evt){
+ // summary:
+ // Overwritten, see _FocusManager.focusHeader()
+ //delayed: Boolean
+ // If called from "this.focus._delayedHeaderFocus()"
+ if(this._currRegionIdx === -1){
+ this._onMove(0, 1, null);
+ }else{
+ this._focusRegion(this._getCurrentRegion());
+ }
+ try{
+ dojo.stopEvent(evt);
+ }catch(e){}
+ return true;
+ },
+ _blurHeader: function(evt){
+ this._blurRegion(this._getCurrentRegion());
+ return true;
+ },
+ _onMove: function(rowStep, colStep, evt){
+ var curr = this._currRegionIdx || 0, regions = this._focusRegions;
+ var region = regions[curr + colStep];
+ if(!region){
+ return;
+ }else if(dojo.style(region, 'display') === 'none' || dojo.style(region, 'visibility') === 'hidden'){
+ //if the region is invisible, keep finding next
+ this._onMove(rowStep, colStep + (colStep > 0 ? 1 : -1), evt);
+ return;
+ }
+ this._focusRegion(region);
+ //keep grid body scrolled by header
+ var view = this._getRegionView(region);
+ view.scrollboxNode.scrollLeft = view.headerNode.scrollLeft;
+ },
+ _onKeyDown: function(e, isBubble){
+ if(isBubble){
+ switch(e.keyCode){
+ case dojo.keys.ENTER:
+ case dojo.keys.SPACE:
+ if(dojo.hasClass(e.target, 'dojoxGridSortBtnSingle') ||
+ dojo.hasClass(e.target, 'dojoxGridSortBtnNested')){
+ this._onSortBtnClick(e);
+ }
+ }
+ }
+ },
+ _getRegionView: function(region){
+ var header = region;
+ while(header && !dojo.hasClass(header, 'dojoxGridHeader')){ header = header.parentNode; }
+ if(header){
+ return dojo.filter(this.grid.views.views, function(view){
+ return view.headerNode === header;
+ })[0] || null;
+ }
+ return null;
+ },
+ _getRegions: function(){
+ var regions = [], cells = this.grid.layout.cells;
+ this._headerNodes.forEach(function(n, i){
+ if(dojo.style(n, 'display') === 'none'){return;}
+ if(cells[i]['isRowSelector']){
+ regions.push(n);
+ return;
+ }
+ dojo.query('.dojoxGridSortNode,.dojoxGridSortBtnNested,.dojoxGridSortBtnSingle', n)
+ .forEach(function(node){
+ dojo.attr(node, 'tabindex', 0);
+ regions.push(node);
+ });
+ },this);
+ return regions;
+ },
+ _focusRegion: function(region){
+ // summary
+ // Focus the given region
+ if(!region){return;}
+ var currRegion = this._getCurrentRegion();
+ if(currRegion && region !== currRegion){
+ this._blurRegion(currRegion);
+ }
+ var header = this._getRegionHeader(region);
+ dojo.addClass(header, 'dojoxGridCellSortFocus');
+ if(dojo.hasClass(region, 'dojoxGridSortNode')){
+ dojo.addClass(region, 'dojoxGridSortNodeFocus');
+ }else if(dojo.hasClass(region, 'dojoxGridSortBtn')){
+ dojo.addClass(region, 'dojoxGridSortBtnFocus');
+ }
+ region.focus();
+ this.focus.currentArea('header');
+ this._currRegionIdx = dojo.indexOf(this._focusRegions, region);
+ },
+ _blurRegion: function(region){
+ if(!region){return;}
+ var header = this._getRegionHeader(region);
+ dojo.removeClass(header, 'dojoxGridCellSortFocus');
+ if(dojo.hasClass(region, 'dojoxGridSortNode')){
+ dojo.removeClass(region, 'dojoxGridSortNodeFocus');
+ }else if(dojo.hasClass(region, 'dojoxGridSortBtn')){
+ dojo.removeClass(region, 'dojoxGridSortBtnFocus');
+ }
+ region.blur();
+ },
+ _getCurrentRegion: function(){
+ return this._focusRegions[this._currRegionIdx];
+ },
+ _getRegionHeader: function(region){
+ while(region && !dojo.hasClass(region, 'dojoxGridCell')){
+ region = region.parentNode;
+ }
+ return region;
+ },
+ destroy: function(){
+ this._sortDef = this._sortData = null;
+ this._headerNodes = this._focusRegions = null;
+ this.inherited(arguments);
+ }
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.NestedSorting);
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/NestedSorting.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/NestedSorting.xd.js
new file mode 100644
index 0000000..3556665
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/NestedSorting.xd.js
@@ -0,0 +1,584 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.NestedSorting"],
+["require", "dojox.grid.enhanced._Plugin"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.NestedSorting"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.NestedSorting"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.NestedSorting");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+
+dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provides nested sorting feature
+ //
+ // description:
+ // A flexible way to control multiple column sorting, including
+ // 1. Set default sorting order
+ // 2. Disable sorting for certain columns
+ // 3. Set sorting order dynamically with JS API
+ //
+ // example:
+ // | <script type="text/javascript">
+ // | var grid = new dojox.grid.EnhancedGrid({plugins : {nestedSorting: true}},
+ // | sortFields: [{attribute: 'col4', descending: false},...],//set default sorting order
+ // | canSort: function(index, field){ return true},//disable sorting for a column
+ // | ... }, dojo.byId('gridDiv'));
+ // | grid.startup();
+ // | //set new sorting order
+ // | grid.setSortIndex([{attribute: 'col3', descending: true},...])
+ // | </script>
+
+ // name: String
+ // Plugin name
+ name: "nestedSorting",
+
+ _currMainSort: 'none',//'none'|'asc'|'desc'
+
+ _currRegionIdx: -1,
+
+ _a11yText: {
+ 'dojoxGridDescending' : '&#9662;',
+ 'dojoxGridAscending' : '&#9652;',
+ 'dojoxGridAscendingTip' : '&#1784;',
+ 'dojoxGridDescendingTip': '&#1783;',
+ 'dojoxGridUnsortedTip' : 'x' //'&#10006;'
+ },
+
+ constructor: function(){
+ this._sortDef = [];
+ this._sortData = {};
+ this._headerNodes = {};
+ //column index that are hidden, un-sortable or indirect selection etc.
+ this._excludedColIdx = [];
+ this.nls = this.grid._nls;
+ this.grid.setSortInfo = function(){};
+ this.grid.setSortIndex = dojo.hitch(this, '_setGridSortIndex');
+ this.grid.getSortProps = dojo.hitch(this, 'getSortProps');
+ if(this.grid.sortFields){
+ this._setGridSortIndex(this.grid.sortFields, null, true);
+ }
+ this.connect(this.grid.views, 'render', '_initSort');//including column resize
+ this.initCookieHandler();
+ },
+ onStartUp: function(){
+ //overwrite base Grid functions
+ this.inherited(arguments);
+ this.connect(this.grid, 'onHeaderCellClick', '_onHeaderCellClick');
+ this.connect(this.grid, 'onHeaderCellMouseOver', '_onHeaderCellMouseOver');
+ this.connect(this.grid, 'onHeaderCellMouseOut', '_onHeaderCellMouseOut');
+ },
+ _setGridSortIndex: function(inIndex, inAsc, noRefresh){
+ if(dojo.isArray(inIndex)){
+ var i, d, cell;
+ for(i = 0; i < inIndex.length; i++){
+ d = inIndex[i];
+ cell = this.grid.getCellByField(d.attribute);
+ if(!cell){
+ console.warn('Invalid sorting option, column ', d.attribute, ' not found.');
+ return;
+ }
+ if(cell['nosort'] || !this.grid.canSort(cell.index, cell.field)){
+ console.warn('Invalid sorting option, column ', d.attribute, ' is unsortable.');
+ return;
+ }
+ }
+ this.clearSort();
+ dojo.forEach(inIndex, function(d, i){
+ cell = this.grid.getCellByField(d.attribute);
+ this.setSortData(cell.index, 'index', i);
+ this.setSortData(cell.index, 'order', d.descending ? 'desc': 'asc');
+ }, this);
+ }else if(!isNaN(inIndex)){
+ if(inAsc === undefined){ return; }//header click from base DataGrid
+ this.setSortData(inIndex, 'order', inAsc ? 'asc' : 'desc');
+ }else{
+ return;
+ }
+ this._updateSortDef();
+ if(!noRefresh){
+ this.grid.sort();
+ }
+ },
+ getSortProps: function(){
+ // summary:
+ // Overwritten, see DataGrid.getSortProps()
+ return this._sortDef.length ? this._sortDef : null;
+ },
+ _initSort: function(postSort){
+ // summary:
+ // Initiate sorting
+ var g = this.grid, n = g.domNode, len = this._sortDef.length;
+ dojo.toggleClass(n, 'dojoxGridSorted', !!len);
+ dojo.toggleClass(n, 'dojoxGridSingleSorted', len === 1);
+ dojo.toggleClass(n, 'dojoxGridNestSorted', len > 1);
+ if(len > 0){
+ this._currMainSort = this._sortDef[0].descending ? 'desc' : 'asc';
+ }
+ var idx, excluded = this._excludedCoIdx = [];//reset it
+ //cache column index of hidden, un-sortable or indirect selection
+ this._headerNodes = dojo.query("th", g.viewsHeaderNode).forEach(function(n){
+ idx = parseInt(dojo.attr(n, 'idx'), 10);
+ if(dojo.style(n, 'display') === 'none' || g.layout.cells[idx]['nosort'] || (g.canSort && !g.canSort(idx, g.layout.cells[idx]['field']))){
+ excluded.push(idx);
+ }
+ });
+ this._headerNodes.forEach(this._initHeaderNode, this);
+ this._initFocus();
+ if(postSort){
+ this._focusHeader();
+ }
+ },
+ _initHeaderNode: function(node){
+ // summary:
+ // Initiate sort for each header cell node
+ var sortNode = dojo.query('.dojoxGridSortNode', node)[0];
+ if(sortNode){
+ dojo.toggleClass(sortNode, 'dojoxGridSortNoWrap', true);
+ }
+ if(dojo.indexOf(this._excludedCoIdx, dojo.attr(node,'idx')) >= 0){
+ dojo.addClass(node, 'dojoxGridNoSort');
+ return;
+ }
+ if(!dojo.query('.dojoxGridSortBtn', node).length){
+ //clear any previous connects
+ this._connects = dojo.filter(this._connects, function(conn){
+ if(conn._sort){
+ dojo.disconnect(conn);
+ return false;
+ }
+ return true;
+ });
+ var n = dojo.create('a', {
+ className: 'dojoxGridSortBtn dojoxGridSortBtnNested',
+ title: this.nls.nestedSort + ' - ' + this.nls.ascending,
+ innerHTML: '1'
+ }, node.firstChild, 'last');
+ var h = this.connect(n, "onmousedown", dojo.stopEvent);
+ h._sort = true;
+ n = dojo.create('a', {
+ className: 'dojoxGridSortBtn dojoxGridSortBtnSingle',
+ title: this.nls.singleSort + ' - ' + this.nls.ascending
+ }, node.firstChild, 'last');
+ h = this.connect(n, "onmousedown", dojo.stopEvent);
+ h._sort = true;
+ }else{
+ //deal with small height grid which doesn't re-render the grid after refresh
+ var a1 = dojo.query('.dojoxGridSortBtnSingle', node)[0];
+ var a2 = dojo.query('.dojoxGridSortBtnNested', node)[0];
+ a1.className = 'dojoxGridSortBtn dojoxGridSortBtnSingle';
+ a2.className = 'dojoxGridSortBtn dojoxGridSortBtnNested';
+ a2.innerHTML = '1';
+ dojo.removeClass(node, 'dojoxGridCellShowIndex');
+ dojo.removeClass(node.firstChild, 'dojoxGridSortNodeSorted');
+ dojo.removeClass(node.firstChild, 'dojoxGridSortNodeAsc');
+ dojo.removeClass(node.firstChild, 'dojoxGridSortNodeDesc');
+ dojo.removeClass(node.firstChild, 'dojoxGridSortNodeMain');
+ dojo.removeClass(node.firstChild, 'dojoxGridSortNodeSub');
+ }
+ this._updateHeaderNodeUI(node);
+ },
+ _onHeaderCellClick: function(e){
+ // summary
+ // See dojox.grid.enhanced._Events._onHeaderCellClick()
+ this._focusRegion(e.target);
+ if(dojo.hasClass(e.target, 'dojoxGridSortBtn')){
+ this._onSortBtnClick(e);
+ dojo.stopEvent(e);
+ this._focusRegion(this._getCurrentRegion());
+ }
+ },
+ _onHeaderCellMouseOver: function(e){
+ // summary
+ // See dojox.grid._Events._onHeaderCellMouseOver()
+ // When user mouseover other columns than sorted column in a single sorted grid,
+ // We need to show 1 in the sorted column
+ if(!e.cell){return; }
+ if(this._sortDef.length > 1){ return; }
+ if(this._sortData[e.cellIndex] && this._sortData[e.cellIndex].index === 0){ return; }
+ var p;
+ for(p in this._sortData){
+ if(this._sortData[p].index === 0){
+ dojo.addClass(this._headerNodes[p], 'dojoxGridCellShowIndex');
+ break;
+ }
+ }
+ if(!dojo.hasClass(dojo.body(), 'dijit_a11y')){ return; }
+ //a11y support
+ var i = e.cell.index, node = e.cellNode;
+ var singleSortBtn = dojo.query('.dojoxGridSortBtnSingle', node)[0];
+ var nestedSortBtn = dojo.query('.dojoxGridSortBtnNested', node)[0];
+
+ var sortMode = 'none';
+ if(dojo.hasClass(this.grid.domNode, 'dojoxGridSingleSorted')){
+ sortMode = 'single';
+ }else if(dojo.hasClass(this.grid.domNode, 'dojoxGridNestSorted')){
+ sortMode = 'nested';
+ }
+ var nestedIndex = dojo.attr(nestedSortBtn, 'orderIndex');
+ if(nestedIndex === null || nestedIndex === undefined){
+ dojo.attr(nestedSortBtn, 'orderIndex', nestedSortBtn.innerHTML);
+ nestedIndex = nestedSortBtn.innerHTML;
+ }
+ if(this.isAsc(i)){
+ nestedSortBtn.innerHTML = nestedIndex + this._a11yText.dojoxGridDescending;
+ }else if(this.isDesc(i)){
+ nestedSortBtn.innerHTML = nestedIndex + this._a11yText.dojoxGridUnsortedTip;
+ }else{
+ nestedSortBtn.innerHTML = nestedIndex + this._a11yText.dojoxGridAscending;
+ }
+ if(this._currMainSort === 'none'){
+ singleSortBtn.innerHTML = this._a11yText.dojoxGridAscending;
+ }else if(this._currMainSort === 'asc'){
+ singleSortBtn.innerHTML = this._a11yText.dojoxGridDescending;
+ }else if(this._currMainSort === 'desc'){
+ singleSortBtn.innerHTML = this._a11yText.dojoxGridUnsortedTip;
+ }
+ },
+ _onHeaderCellMouseOut: function(e){
+ // summary
+ // See dojox.grid.enhanced._Events._onHeaderCellMouseOut()
+ var p;
+ for(p in this._sortData){
+ if(this._sortData[p].index === 0){
+ dojo.removeClass(this._headerNodes[p], 'dojoxGridCellShowIndex');
+ break;
+ }
+ }
+ },
+ _onSortBtnClick: function(e){
+ // summary:
+ // If the click target is single sort button, do single sort.
+ // Else if the click target is nested sort button, do nest sort.
+ // Otherwise return.
+ var cellIdx = e.cell.index;
+ if(dojo.hasClass(e.target, 'dojoxGridSortBtnSingle')){
+ this._prepareSingleSort(cellIdx);
+ }else if(dojo.hasClass(e.target, 'dojoxGridSortBtnNested')){
+ this._prepareNestedSort(cellIdx);
+ }else{
+ return;
+ }
+ dojo.stopEvent(e);
+ this._doSort(cellIdx);
+ },
+ _doSort: function(cellIdx){
+ if(!this._sortData[cellIdx] || !this._sortData[cellIdx].order){
+ this.setSortData(cellIdx, 'order', 'asc'); //no sorting data
+ }else if(this.isAsc(cellIdx)){
+ this.setSortData(cellIdx, 'order', 'desc'); //change to 'desc'
+ }else if(this.isDesc(cellIdx)){
+ this.removeSortData(cellIdx); //remove from sorting sequence
+ }
+ this._updateSortDef();
+ this.grid.sort();
+ this._initSort(true);
+ },
+ setSortData: function(cellIdx, attr, value){
+ // summary:
+ // Set sorting data for a column.
+ var sd = this._sortData[cellIdx];
+ if(!sd){
+ sd = this._sortData[cellIdx] = {};
+ }
+ sd[attr] = value;
+ },
+ removeSortData: function(cellIdx){
+ var d = this._sortData, i = d[cellIdx].index, p;
+ delete d[cellIdx];
+ for(p in d){
+ if(d[p].index > i){
+ d[p].index--;
+ }
+ }
+ },
+ _prepareSingleSort: function(cellIdx){
+ // summary:
+ // Prepare the single sort, also called main sort, this will clear any existing sorting and just sort the grid by current column.
+ var d = this._sortData, p;
+ for(p in d){
+ delete d[p];
+ }
+ this.setSortData(cellIdx, 'index', 0);
+ this.setSortData(cellIdx, 'order', this._currMainSort === 'none' ? null : this._currMainSort);
+ if(!this._sortData[cellIdx] || !this._sortData[cellIdx].order){
+ this._currMainSort = 'asc';
+ }else if(this.isAsc(cellIdx)){
+ this._currMainSort = 'desc';
+ }else if(this.isDesc(cellIdx)){
+ this._currMainSort = 'none';
+ }
+ },
+ _prepareNestedSort: function(cellIdx){
+ // summary
+ // Prepare the nested sorting, this will order the column on existing sorting result.
+ var i = this._sortData[cellIdx] ? this._sortData[cellIdx].index : null;
+ if(i === 0 || !!i){ return; }
+ this.setSortData(cellIdx, 'index', this._sortDef.length);
+ },
+ _updateSortDef: function(){
+ this._sortDef.length = 0;
+ var d = this._sortData, p;
+ for(p in d){
+ this._sortDef[d[p].index] = {
+ attribute: this.grid.layout.cells[p].field,
+ descending: d[p].order === 'desc'
+ };
+ }
+ },
+ _updateHeaderNodeUI: function(node){
+ // summary:
+ // Update the column header UI based on current sorting state.
+ // Show indicator of the sorting order of the column, no order no indicator
+ var cell = this._getCellByNode(node);
+ var cellIdx = cell.index;
+ var data = this._sortData[cellIdx];
+ var sortNode = dojo.query('.dojoxGridSortNode', node)[0];
+ var singleSortBtn = dojo.query('.dojoxGridSortBtnSingle', node)[0];
+ var nestedSortBtn = dojo.query('.dojoxGridSortBtnNested', node)[0];
+
+ dojo.toggleClass(singleSortBtn, 'dojoxGridSortBtnAsc', this._currMainSort === 'asc');
+ dojo.toggleClass(singleSortBtn, 'dojoxGridSortBtnDesc', this._currMainSort === 'desc');
+ if(this._currMainSort === 'asc'){
+ singleSortBtn.title = this.nls.singleSort + ' - ' + this.nls.descending;
+ }else if(this._currMainSort === 'desc'){
+ singleSortBtn.title = this.nls.singleSort + ' - ' + this.nls.unsorted;
+ }else{
+ singleSortBtn.title = this.nls.singleSort + ' - ' + this.nls.ascending;
+ }
+
+ var _this = this;
+ function setWaiState(){
+ var columnInfo = 'Column ' + (cell.index + 1) + ' ' + cell.field;
+ var orderState = 'none';
+ var orderAction = 'ascending';
+ if(data){
+ orderState = data.order === 'asc' ? 'ascending' : 'descending';
+ orderAction = data.order === 'asc' ? 'descending' : 'none';
+ }
+ var a11ySingleLabel = columnInfo + ' - is sorted by ' + orderState;
+ var a11yNestedLabel = columnInfo + ' - is nested sorted by ' + orderState;
+ var a11ySingleLabelHover = columnInfo + ' - choose to sort by ' + orderAction;
+ var a11yNestedLabelHover = columnInfo + ' - choose to nested sort by ' + orderAction;
+
+ dijit.setWaiState(singleSortBtn, 'label', a11ySingleLabel);
+ dijit.setWaiState(nestedSortBtn, 'label', a11yNestedLabel);
+
+ var handles = [
+ _this.connect(singleSortBtn, "onmouseover", function(){
+ dijit.setWaiState(singleSortBtn, 'label', a11ySingleLabelHover);
+ }),
+ _this.connect(singleSortBtn, "onmouseout", function(){
+ dijit.setWaiState(singleSortBtn, 'label', a11ySingleLabel);
+ }),
+ _this.connect(nestedSortBtn, "onmouseover", function(){
+ dijit.setWaiState(nestedSortBtn, 'label', a11yNestedLabelHover);
+ }),
+ _this.connect(nestedSortBtn, "onmouseout", function(){
+ dijit.setWaiState(nestedSortBtn, 'label', a11yNestedLabel);
+ })
+ ];
+ dojo.forEach(handles, function(handle){ handle._sort = true; });
+ }
+ setWaiState();
+
+ var a11y = dojo.hasClass(dojo.body(), "dijit_a11y");
+ if(!data){
+ nestedSortBtn.innerHTML = this._sortDef.length + 1;
+ return;
+ }
+ if(data.index || (data.index === 0 && this._sortDef.length > 1)){
+ nestedSortBtn.innerHTML = data.index + 1;
+ }
+ dojo.addClass(sortNode, 'dojoxGridSortNodeSorted');
+ if(this.isAsc(cellIdx)){
+ dojo.addClass(sortNode, 'dojoxGridSortNodeAsc');
+ nestedSortBtn.title = this.nls.nestedSort + ' - ' + this.nls.descending;
+ if(a11y){sortNode.innerHTML = this._a11yText.dojoxGridAscendingTip;}
+ }else if(this.isDesc(cellIdx)){
+ dojo.addClass(sortNode, 'dojoxGridSortNodeDesc');
+ nestedSortBtn.title = this.nls.nestedSort + ' - ' + this.nls.unsorted;
+ if(a11y){sortNode.innerHTML = this._a11yText.dojoxGridDescendingTip;}
+ }
+ dojo.addClass(sortNode, (data.index === 0 ? 'dojoxGridSortNodeMain' : 'dojoxGridSortNodeSub'));
+ },
+ isAsc: function(cellIndex){
+ return this._sortData[cellIndex].order === 'asc';
+ },
+ isDesc: function(cellIndex){
+ return this._sortData[cellIndex].order === 'desc';
+ },
+ _getCellByNode: function(node){
+ var i;
+ for(i = 0; i < this._headerNodes.length; i++){
+ if(this._headerNodes[i] === node){
+ return this.grid.layout.cells[i];
+ }
+ }
+ return null;
+ },
+ clearSort: function(){
+ this._sortData = {};
+ this._sortDef.length = 0;
+ },
+
+ //persistence
+ initCookieHandler: function(){
+ if(this.grid.addCookieHandler){
+ this.grid.addCookieHandler({
+ name: "sortOrder",
+ onLoad: dojo.hitch(this, '_loadNestedSortingProps'),
+ onSave: dojo.hitch(this, '_saveNestedSortingProps')
+ });
+ }
+ },
+ _loadNestedSortingProps: function(sortInfo, grid){
+ this._setGridSortIndex(sortInfo);
+ },
+ _saveNestedSortingProps: function(grid){
+ return this.getSortProps();
+ },
+
+ //focus & keyboard
+ _initFocus: function(){
+ var f = this.focus = this.grid.focus;
+ this._focusRegions = this._getRegions();
+ if(!this._headerArea){
+ var area = this._headerArea = f.getArea('header');
+ area.onFocus = f.focusHeader = dojo.hitch(this, '_focusHeader');
+ area.onBlur = f.blurHeader = f._blurHeader = dojo.hitch(this, '_blurHeader');
+ area.onMove = dojo.hitch(this, '_onMove');
+ area.onKeyDown = dojo.hitch(this, '_onKeyDown');
+ area._regions = [];
+ area.getRegions = null;
+ this.connect(this.grid, 'onBlur', '_blurHeader');
+ }
+ },
+ _focusHeader: function(evt){
+ // summary:
+ // Overwritten, see _FocusManager.focusHeader()
+ //delayed: Boolean
+ // If called from "this.focus._delayedHeaderFocus()"
+ if(this._currRegionIdx === -1){
+ this._onMove(0, 1, null);
+ }else{
+ this._focusRegion(this._getCurrentRegion());
+ }
+ try{
+ dojo.stopEvent(evt);
+ }catch(e){}
+ return true;
+ },
+ _blurHeader: function(evt){
+ this._blurRegion(this._getCurrentRegion());
+ return true;
+ },
+ _onMove: function(rowStep, colStep, evt){
+ var curr = this._currRegionIdx || 0, regions = this._focusRegions;
+ var region = regions[curr + colStep];
+ if(!region){
+ return;
+ }else if(dojo.style(region, 'display') === 'none' || dojo.style(region, 'visibility') === 'hidden'){
+ //if the region is invisible, keep finding next
+ this._onMove(rowStep, colStep + (colStep > 0 ? 1 : -1), evt);
+ return;
+ }
+ this._focusRegion(region);
+ //keep grid body scrolled by header
+ var view = this._getRegionView(region);
+ view.scrollboxNode.scrollLeft = view.headerNode.scrollLeft;
+ },
+ _onKeyDown: function(e, isBubble){
+ if(isBubble){
+ switch(e.keyCode){
+ case dojo.keys.ENTER:
+ case dojo.keys.SPACE:
+ if(dojo.hasClass(e.target, 'dojoxGridSortBtnSingle') ||
+ dojo.hasClass(e.target, 'dojoxGridSortBtnNested')){
+ this._onSortBtnClick(e);
+ }
+ }
+ }
+ },
+ _getRegionView: function(region){
+ var header = region;
+ while(header && !dojo.hasClass(header, 'dojoxGridHeader')){ header = header.parentNode; }
+ if(header){
+ return dojo.filter(this.grid.views.views, function(view){
+ return view.headerNode === header;
+ })[0] || null;
+ }
+ return null;
+ },
+ _getRegions: function(){
+ var regions = [], cells = this.grid.layout.cells;
+ this._headerNodes.forEach(function(n, i){
+ if(dojo.style(n, 'display') === 'none'){return;}
+ if(cells[i]['isRowSelector']){
+ regions.push(n);
+ return;
+ }
+ dojo.query('.dojoxGridSortNode,.dojoxGridSortBtnNested,.dojoxGridSortBtnSingle', n)
+ .forEach(function(node){
+ dojo.attr(node, 'tabindex', 0);
+ regions.push(node);
+ });
+ },this);
+ return regions;
+ },
+ _focusRegion: function(region){
+ // summary
+ // Focus the given region
+ if(!region){return;}
+ var currRegion = this._getCurrentRegion();
+ if(currRegion && region !== currRegion){
+ this._blurRegion(currRegion);
+ }
+ var header = this._getRegionHeader(region);
+ dojo.addClass(header, 'dojoxGridCellSortFocus');
+ if(dojo.hasClass(region, 'dojoxGridSortNode')){
+ dojo.addClass(region, 'dojoxGridSortNodeFocus');
+ }else if(dojo.hasClass(region, 'dojoxGridSortBtn')){
+ dojo.addClass(region, 'dojoxGridSortBtnFocus');
+ }
+ region.focus();
+ this.focus.currentArea('header');
+ this._currRegionIdx = dojo.indexOf(this._focusRegions, region);
+ },
+ _blurRegion: function(region){
+ if(!region){return;}
+ var header = this._getRegionHeader(region);
+ dojo.removeClass(header, 'dojoxGridCellSortFocus');
+ if(dojo.hasClass(region, 'dojoxGridSortNode')){
+ dojo.removeClass(region, 'dojoxGridSortNodeFocus');
+ }else if(dojo.hasClass(region, 'dojoxGridSortBtn')){
+ dojo.removeClass(region, 'dojoxGridSortBtnFocus');
+ }
+ region.blur();
+ },
+ _getCurrentRegion: function(){
+ return this._focusRegions[this._currRegionIdx];
+ },
+ _getRegionHeader: function(region){
+ while(region && !dojo.hasClass(region, 'dojoxGridCell')){
+ region = region.parentNode;
+ }
+ return region;
+ },
+ destroy: function(){
+ this._sortDef = this._sortData = null;
+ this._headerNodes = this._focusRegions = null;
+ this.inherited(arguments);
+ }
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.NestedSorting);
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Pagination.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Pagination.js
new file mode 100644
index 0000000..e9b92e1
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Pagination.js
@@ -0,0 +1,1235 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.Pagination"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Pagination"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Pagination");
+
+dojo.require("dijit.form.NumberTextBox");
+dojo.require("dijit.form.Button");
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid.enhanced.plugins.Dialog");
+dojo.require("dojox.grid.enhanced.plugins._StoreLayer");
+
+dojo.requireLocalization("dojox.grid.enhanced", "Pagination", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ru,sl,sv,th,tr,zh,zh-tw");
+
+dojo.declare("dojox.grid.enhanced.plugins.Pagination", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // The typical pagination way as an alternative to deal with huge data set besides the default virtual scrolling way
+
+ name: "pagination",
+ // The page size used with the store, default = 25.
+ pageSize: 25,
+
+ defaultRows: 25,
+
+ //current page we are at
+ _currentPage: 0,
+
+ //The currently obtained max # of rows to page through.
+ _maxSize: 0,
+
+ init: function(){
+ this.gh = null;
+ this.grid.rowsPerPage = this.pageSize = this.grid.rowsPerPage ? this.grid.rowsPerPage : this.pageSize;
+ this.grid.usingPagination = true;
+ this.nls = dojo.i18n.getLocalization("dojox.grid.enhanced", "Pagination");
+
+ this._wrapStoreLayer();
+ this._createPaginators(this.option);
+
+ this._regApis();
+ },
+
+ _createPaginators: function(paginationArgs){
+ // summary:
+ // Function to create the pagination control bar.
+ this.paginators = [];
+ if(paginationArgs.position === "both"){
+ this.paginators = [
+ new dojox.grid.enhanced.plugins._Paginator(dojo.mixin(paginationArgs, {position: "bottom", plugin: this})),
+ new dojox.grid.enhanced.plugins._Paginator(dojo.mixin(paginationArgs, {position: "top", plugin: this}))
+ ];
+ }else{
+ this.paginators = [new dojox.grid.enhanced.plugins._Paginator(dojo.mixin(paginationArgs, {plugin: this}))];
+ }
+ },
+
+ _wrapStoreLayer: function(){
+ var g = this.grid,
+ ns = dojox.grid.enhanced.plugins;
+ this._store = g.store;
+ this.query = g.query;
+
+ this.forcePageStoreLayer = new ns._ForcedPageStoreLayer(this);
+ ns.wrap(g, "_storeLayerFetch", this.forcePageStoreLayer);
+
+ this.connect(g, "setQuery", function(query){
+ if(query !== this.query){
+ this.query = query;
+ }
+ });
+ },
+
+ _stopEvent: function(event){
+ try{
+ dojo.stopEvent(event);
+ }catch(e){}
+ },
+
+ _onNew: function(item, parentInfo){
+ var totalPages = Math.ceil(this._maxSize / this.pageSize);
+ if(((this._currentPage + 1 === totalPages || totalPages === 0) && this.grid.rowCount < this.pageSize) || this.showAll){
+ dojo.hitch(this.grid, this._originalOnNew)(item, parentInfo);
+ this.forcePageStoreLayer.endIdx++;
+ }
+ this._maxSize++;
+ if(this.showAll){
+ this.pageSize++;
+ }
+ if(this.showAll && this.grid.autoHeight){
+ this.grid._refresh();
+ }else{
+ dojo.forEach(this.paginators, function(p){
+ p.update();
+ });
+ }
+ },
+
+ _removeSelectedRows: function(){
+ this._multiRemoving = true;
+ this._originalRemove();
+ this._multiRemoving = false;
+ this.grid.resize();
+ this.grid._refresh();
+ },
+
+ _onDelete: function(){
+ if(!this._multiRemoving){
+ this.grid.resize();
+ if(this.showAll){
+ this.grid._refresh();
+ }
+ }
+ if(this.grid.get('rowCount') === 0){
+ this.prevPage();
+ }
+ },
+
+ _regApis: function(){
+ // summary:
+ // register pagination public APIs to grid.
+ var g = this.grid;
+ // New added APIs
+ g.gotoPage = dojo.hitch(this, this.gotoPage);
+ g.nextPage = dojo.hitch(this, this.nextPage);
+ g.prevPage = dojo.hitch(this, this.prevPage);
+ g.gotoFirstPage = dojo.hitch(this, this.gotoFirstPage);
+ g.gotoLastPage = dojo.hitch(this, this.gotoLastPage);
+ g.changePageSize = dojo.hitch(this, this.changePageSize);
+ g.showGotoPageButton = dojo.hitch(this, this.showGotoPageButton);
+ g.getTotalRowCount = dojo.hitch(this, this.getTotalRowCount);
+ // Changed APIs
+ this.originalScrollToRow = dojo.hitch(g, g.scrollToRow);
+ g.scrollToRow = dojo.hitch(this, this.scrollToRow);
+ this._originalOnNew = dojo.hitch(g, g._onNew);
+ this._originalRemove = dojo.hitch(g, g.removeSelectedRows);
+ g.removeSelectedRows = dojo.hitch(this, this._removeSelectedRows);
+ g._onNew = dojo.hitch(this, this._onNew);
+ this.connect(g, "_onDelete", dojo.hitch(this, this._onDelete));
+ },
+
+ destroy: function(){
+ this.inherited(arguments);
+ var g = this.grid;
+ try{
+ dojo.forEach(this.paginators, function(p){
+ p.destroy();
+ });
+ g.unwrap(this.forcePageStoreLayer.name());
+ g._onNew = this._originalOnNew;
+ g.removeSelectedRows = this._originalRemove;
+ g.scrollToRow = this.originalScrollToRow;
+ this.paginators = null;
+ this.nls = null;
+ }catch(e){
+ console.warn("Pagination.destroy() error: ", e);
+ }
+ },
+
+ nextPage: function(){
+ // summary:
+ // Function to handle shifting to the next page in the list.
+ if(this._maxSize > ((this._currentPage + 1) * this.pageSize)){
+ //Current page is indexed at 0 and gotoPage expects 1-X. So to go
+ //up one, pass current page + 2!
+ this.gotoPage(this._currentPage + 2);
+ }
+ },
+
+ prevPage: function(){
+ // summary:
+ // Function to handle shifting to the previous page in the list.
+ if(this._currentPage > 0){
+ //Current page is indexed at 0 and gotoPage expects 1-X. So to go
+ //back one, pass current page!
+ this.gotoPage(this._currentPage);
+ }
+ },
+
+ gotoPage: function(page){
+ // summary:
+ // Function to handle shifting to an arbirtary page in the list.
+ // page:
+ // The page to go to, starting at 1.
+ var totalPages = Math.ceil(this._maxSize / this.pageSize);
+ page--;
+ if(page < totalPages && page >= 0 && this._currentPage !== page){
+ this._currentPage = page;
+ // this._updateSelected();
+ this.grid.setQuery(this.query);
+ this.grid.resize();
+ }
+ },
+
+ gotoFirstPage: function(){
+ // summary:
+ // Go to the first page
+ this.gotoPage(1);
+ },
+
+ gotoLastPage: function(){
+ // summary:
+ // Go to the last page
+ var totalPages = Math.ceil(this._maxSize / this.pageSize);
+ this.gotoPage(totalPages);
+ },
+
+ changePageSize: function(size){
+ // summary:
+ // Change size of items per page.
+ // This function will only be called by _Paginator
+ if(typeof size == "string"){
+ size = parseInt(size, 10);
+ }
+ var startIndex = this.pageSize * this._currentPage;
+ dojo.forEach(this.paginators, function(f){
+ f.currentPageSize = this.grid.rowsPerPage = this.pageSize = size;
+ if(size >= this._maxSize){
+ this.grid.rowsPerPage = this.defaultRows;
+ this.grid.usingPagination = false;
+ }else{
+ this.grid.usingPagination = true;
+ }
+ }, this);
+ var endIndex = startIndex + Math.min(this.pageSize, this._maxSize);
+ if(endIndex > this._maxSize){
+ this.gotoLastPage();
+ }else{
+ var cp = Math.ceil(startIndex / this.pageSize);
+ if(cp !== this._currentPage){
+ this.gotoPage(cp + 1);
+ }else{
+ this.grid._refresh(true);
+ }
+ }
+ this.grid.resize();
+ },
+
+ showGotoPageButton: function(flag){
+ // summary:
+ // For show/hide the go to page button dynamically
+ // flag: boolean
+ // Show the go to page button when flag is true, otherwise hide it
+ dojo.forEach(this.paginators, function(p){
+ p._showGotoButton(flag);
+ });
+ },
+
+ scrollToRow: function(inRowIndex){
+ // summary:
+ // Override the grid.scrollToRow(), could jump to the right page
+ // and scroll to the specific row
+ // inRowIndex: integer
+ // The row index
+ var page = parseInt(inRowIndex / this.pageSize, 10),
+ totalPages = Math.ceil(this._maxSize / this.pageSize);
+ if(page > totalPages){
+ return;
+ }
+ this.gotoPage(page + 1);
+ var rowIdx = inRowIndex % this.pageSize;
+ this.grid.setScrollTop(this.grid.scroller.findScrollTop(rowIdx) + 1);
+ },
+
+ getTotalRowCount: function(){
+ // summary:
+ // Function for get total row count
+ return this._maxSize;
+ }
+});
+
+dojo.declare("dojox.grid.enhanced.plugins._ForcedPageStoreLayer", dojox.grid.enhanced.plugins._StoreLayer, {
+ tags: ["presentation"],
+
+ constructor: function(plugin){
+ this._plugin = plugin;
+ },
+
+ _fetch: function(request){
+ var self = this,
+ plugin = self._plugin,
+ grid = plugin.grid,
+ scope = request.scope || dojo.global,
+ onBegin = request.onBegin;
+
+ request.start = plugin._currentPage * plugin.pageSize + request.start;
+ self.startIdx = request.start;
+ self.endIdx = request.start + plugin.pageSize - 1;
+ if(onBegin && (plugin.showAll || dojo.every(plugin.paginators, function(p){
+ return plugin.showAll = !p.sizeSwitch && !p.pageStepper && !p.gotoButton;
+ }))){
+ request.onBegin = function(size, req){
+ plugin._maxSize = plugin.pageSize = size;
+ self.startIdx = 0;
+ self.endIdx = size - 1;
+ dojo.forEach(plugin.paginators, function(f){
+ f.update();
+ });
+ req.onBegin = onBegin;
+ req.onBegin.call(scope, size, req);
+ };
+ }else if(onBegin){
+ request.onBegin = function(size, req){
+ req.start = 0;
+ req.count = plugin.pageSize;
+ plugin._maxSize = size;
+ self.endIdx = self.endIdx > size ? (size - 1) : self.endIdx;
+ if(self.startIdx > size && size !== 0){
+ grid._pending_requests[req.start] = false;
+ plugin.gotoFirstPage();
+ }
+ dojo.forEach(plugin.paginators, function(f){
+ f.update();
+ });
+ req.onBegin = onBegin;
+ req.onBegin.call(scope, Math.min(plugin.pageSize, (size - self.startIdx)), req);
+ };
+ }
+ return dojo.hitch(this._store, this._originFetch)(request);
+ }
+});
+
+dojo.declare("dojox.grid.enhanced.plugins._Paginator", [dijit._Widget,dijit._Templated], {
+ templateString:"<div dojoAttachPoint=\"paginatorBar\">\r\n\t<table cellpadding=\"0\" cellspacing=\"0\" class=\"dojoxGridPaginator\">\r\n\t\t<tr>\r\n\t\t\t<td dojoAttachPoint=\"descriptionTd\" class=\"dojoxGridDescriptionTd\">\r\n\t\t\t\t<div dojoAttachPoint=\"descriptionDiv\" class=\"dojoxGridDescription\" />\r\n\t\t\t</td>\r\n\t\t\t<td dojoAttachPoint=\"sizeSwitchTd\"></td>\r\n\t\t\t<td dojoAttachPoint=\"pageStepperTd\" class=\"dojoxGridPaginatorFastStep\">\r\n\t\t\t\t<div dojoAttachPoint=\"pageStepperDiv\" class=\"dojoxGridPaginatorStep\"></div>\r\n\t\t\t</td>\r\n\t\t</tr>\r\n\t</table>\r\n</div>\r\n",
+
+ // pagination bar position - "bottom"|"top"
+ position: "bottom",
+
+ // max data item size
+ _maxItemSize: 0,
+
+ // description message status params
+ description: true,
+
+ // fast step page status params
+ pageStepper: true,
+
+ maxPageStep: 7,
+
+ // items per page size switch params
+ sizeSwitch: true,
+
+ pageSizes: ["10", "25", "50", "100", "All"],
+
+ gotoButton: false,
+
+ constructor: function(params){
+ dojo.mixin(this, params);
+ this.grid = this.plugin.grid;
+ this.itemTitle = this.itemTitle ? this.itemTitle : this.plugin.nls.itemTitle;
+ this.descTemplate = this.descTemplate ? this.descTemplate : this.plugin.nls.descTemplate;
+ },
+
+ postCreate: function(){
+ this.inherited(arguments);
+ this._setWidthValue();
+ var self = this;
+ var g = this.grid;
+ this.plugin.connect(g, "_resize", dojo.hitch(this, "_resetGridHeight"));
+ this._originalResize = dojo.hitch(g, "resize");
+ g.resize = function(changeSize, resultSize){
+ self._changeSize = g._pendingChangeSize = changeSize;
+ self._resultSize = g._pendingResultSize = resultSize;
+ g.sizeChange();
+ };
+ this._placeSelf();
+ },
+
+ destroy: function(){
+ this.inherited(arguments);
+ this.grid.focus.removeArea("pagination" + this.position.toLowerCase());
+ if(this._gotoPageDialog){
+ this._gotoPageDialog.destroy();
+ dojo.destroy(this.gotoPageTd);
+ delete this.gotoPageTd;
+ delete this._gotoPageDialog;
+ }
+ this.grid.resize = this._originalResize;
+ this.pageSizes = null;
+ },
+
+ update: function(){
+ // summary:
+ // Function to update paging information and update
+ // pagination bar display.
+ this.currentPageSize = this.plugin.pageSize;
+ this._maxItemSize = this.plugin._maxSize;
+
+ // update pagination bar display information
+ this._updateDescription();
+ this._updatePageStepper();
+ this._updateSizeSwitch();
+ this._updateGotoButton();
+ },
+
+ _setWidthValue: function(){
+ var type = ["description", "sizeSwitch", "pageStepper"];
+ var endWith = function(str1, str2){
+ var reg = new RegExp(str2+"$");
+ return reg.test(str1);
+ };
+ dojo.forEach(type, function(t){
+ var width, flag = this[t];
+ if(flag === undefined || typeof flag == "boolean"){
+ return;
+ }
+ if(dojo.isString(flag)){
+ width = endWith(flag, "px") || endWith(flag, "%") || endWith(flag, "em") ? flag : parseInt(flag, 10) > 0 ? parseInt(flag, 10) + "px" : null;
+ }else if(typeof flag === "number" && flag > 0){
+ width = flag + "px";
+ }
+ this[t] = width ? true : false;
+ this[t + "Width"] = width;
+ }, this);
+ },
+
+ _regFocusMgr: function(position){
+ // summary:
+ // Function to register pagination bar to focus manager.
+ this.grid.focus.addArea({
+ name: "pagination" + position,
+ onFocus: dojo.hitch(this, this._onFocusPaginator),
+ onBlur: dojo.hitch(this, this._onBlurPaginator),
+ onMove: dojo.hitch(this, this._moveFocus),
+ onKeyDown: dojo.hitch(this, this._onKeyDown)
+ });
+ switch(position){
+ case "top":
+ this.grid.focus.placeArea("pagination" + position, "before", "header");
+ break;
+ case "bottom":
+ default:
+ this.grid.focus.placeArea("pagination" + position, "after", "content");
+ break;
+ }
+ },
+
+ _placeSelf: function(){
+ // summary:
+ // Place pagination bar to a position.
+ // There are two options, top of the grid, bottom of the grid.
+ var g = this.grid;
+ var position = dojo.trim(this.position.toLowerCase());
+ switch(position){
+ case "top":
+ this.placeAt(g.viewsHeaderNode, "before");
+ this._regFocusMgr("top");
+ break;
+ case "bottom":
+ default:
+ this.placeAt(g.viewsNode, "after");
+ this._regFocusMgr("bottom");
+ break;
+ }
+ },
+
+ _resetGridHeight: function(changeSize, resultSize){
+ // summary:
+ // Function of resize grid height to place this pagination bar.
+ // Since the grid would be able to add other element in its domNode, we have
+ // change the grid view size to place the pagination bar.
+ // This function will resize the grid viewsNode height, scorllboxNode height
+ var g = this.grid;
+ changeSize = changeSize || this._changeSize;
+ resultSize = resultSize || this._resultSize;
+ delete this._changeSize;
+ delete this._resultSize;
+ if(g._autoHeight){
+ return;
+ }
+ var padBorder = g._getPadBorder().h;
+ if(!this.plugin.gh){
+ this.plugin.gh = dojo.contentBox(g.domNode).h + 2 * padBorder;
+ }
+ if(resultSize){
+ changeSize = resultSize;
+ }
+ if(changeSize){
+ this.plugin.gh = dojo.contentBox(g.domNode).h + 2 * padBorder;
+ }
+ var gh = this.plugin.gh,
+ hh = g._getHeaderHeight(),
+ ph = dojo.marginBox(this.domNode).h;
+ ph = this.plugin.paginators[1] ? ph * 2 : ph;
+ if(typeof g.autoHeight == "number"){
+ var cgh = gh + ph - padBorder;
+ dojo.style(g.domNode, "height", cgh + "px");
+ dojo.style(g.viewsNode, "height", (cgh - ph - hh) + "px");
+
+ this._styleMsgNode(hh, dojo.marginBox(g.viewsNode).w, cgh - ph - hh);
+ }else{
+ var h = gh - ph - hh - padBorder;
+ dojo.style(g.viewsNode, "height", h + "px");
+ var hasHScroller = dojo.some(g.views.views, function(v){
+ return v.hasHScrollbar();
+ });
+ dojo.forEach(g.viewsNode.childNodes, function(c, idx){
+ dojo.style(c, "height", h + "px");
+ });
+ dojo.forEach(g.views.views, function(v, idx){
+ if(v.scrollboxNode){
+ if(!v.hasHScrollbar() && hasHScroller){
+ dojo.style(v.scrollboxNode, "height", (h - dojox.html.metrics.getScrollbar().h) + "px");
+ }else{
+ dojo.style(v.scrollboxNode, "height", h + "px");
+ }
+ }
+ });
+ this._styleMsgNode(hh, dojo.marginBox(g.viewsNode).w, h);
+ }
+ },
+
+ _styleMsgNode: function(top, width, height){
+ var messagesNode = this.grid.messagesNode;
+ dojo.style(messagesNode, {"position": "absolute", "top": top + "px", "width": width + "px", "height": height + "px", "z-Index": "100"});
+ },
+
+ _updateDescription: function(){
+ // summary:
+ // Update size information.
+ var s = this.plugin.forcePageStoreLayer;
+ if(this.description && this.descriptionDiv){
+ this.descriptionDiv.innerHTML = this._maxItemSize > 0 ? dojo.string.substitute(this.descTemplate, [this.itemTitle, this._maxItemSize, s.startIdx + 1, s.endIdx + 1]) : "0 " + this.itemTitle;
+ }
+ if(this.descriptionWidth){
+ dojo.style(this.descriptionTd, "width", this.descriptionWidth);
+ }
+ },
+
+ _updateSizeSwitch: function(){
+ // summary:
+ // Update "items per page" information.
+ if(!this.sizeSwitchTd){
+ return;
+ }
+ if(!this.sizeSwitch || this._maxItemSize <= 0){
+ dojo.style(this.sizeSwitchTd, "display", "none");
+ return;
+ }else{
+ dojo.style(this.sizeSwitchTd, "display", "");
+ }
+ if(this.initializedSizeNode && !this.pageSizeValue){
+ // do not update page size if page size was not changed
+ return;
+ }
+ if(this.sizeSwitchTd.childNodes.length < 1){
+ this._createSizeSwitchNodes();
+ }
+ this._updateSwitchNodeClass();
+
+ // move focus to next activable node
+ this._moveToNextActivableNode(this._getAllPageSizeNodes(), this.pageSizeValue);
+ this.pageSizeValue = null;
+ },
+
+ _createSizeSwitchNodes: function(){
+ // summary:
+ // The function to create the size switch nodes
+ var node = null;
+ if(!this.pageSizes || this.pageSizes.length < 1){
+ return;
+ }
+ dojo.forEach(this.pageSizes, function(size){
+ // create page size switch node
+ size = dojo.trim(size);
+ var labelValue = size.toLowerCase() == "all" ? this.plugin.nls.allItemsLabelTemplate : dojo.string.substitute(this.plugin.nls.pageSizeLabelTemplate, [size]);
+ node = dojo.create("span", {innerHTML: size, title: labelValue, value: size, tabindex: 0}, this.sizeSwitchTd, "last");
+ // for accessibility
+ dijit.setWaiState(node, "label", labelValue);
+ // connect event
+ this.plugin.connect(node, "onclick", dojo.hitch(this, "_onSwitchPageSize"));
+ this.plugin.connect(node, "onmouseover", function(e){
+ dojo.addClass(e.target, "dojoxGridPageTextHover");
+ });
+ this.plugin.connect(node, "onmouseout", function(e){
+ dojo.removeClass(e.target, "dojoxGridPageTextHover");
+ });
+ // create a separation node
+ node = dojo.create("span", {innerHTML: "|"}, this.sizeSwitchTd, "last");
+ dojo.addClass(node, "dojoxGridSeparator");
+ }, this);
+ // delete last separation node
+ dojo.destroy(node);
+ this.initializedSizeNode = true;
+ if(this.sizeSwitchWidth){
+ dojo.style(this.sizeSwitchTd, "width", this.sizeSwitchWidth);
+ }
+ },
+
+ _updateSwitchNodeClass: function(){
+ // summary:
+ // Update the switch nodes style
+ var size = null;
+ var hasActivedNode = false;
+ var styleNode = function(node, status){
+ if(status){
+ dojo.addClass(node, "dojoxGridActivedSwitch");
+ dojo.attr(node, "tabindex", "-1");
+ hasActivedNode = true;
+ }else{
+ dojo.addClass(node, "dojoxGridInactiveSwitch");
+ dojo.attr(node, "tabindex", "0");
+ }
+ };
+ dojo.forEach(this.sizeSwitchTd.childNodes, function(node){
+ if(node.value){
+ size = node.value;
+ dojo.removeClass(node);
+ if(this.pageSizeValue){
+ styleNode(node, size === this.pageSizeValue && !hasActivedNode);
+ }else{
+ if(size.toLowerCase() == "all"){
+ size = this._maxItemSize;
+ }
+ styleNode(node, this.currentPageSize === parseInt(size, 10) && !hasActivedNode);
+ }
+ }
+ }, this);
+ },
+
+ _updatePageStepper: function(){
+ // summary:
+ // Update the page step nodes
+ if(!this.pageStepperTd){
+ return;
+ }
+ if(!this.pageStepper || this._maxItemSize <= 0){
+ dojo.style(this.pageStepperTd, "display", "none");
+ return;
+ }else{
+ dojo.style(this.pageStepperTd, "display", "");
+ }
+ if(this.pageStepperDiv.childNodes.length < 1){
+ this._createPageStepNodes();
+ this._createWardBtns();
+ }else{
+ this._resetPageStepNodes();
+ }
+ this._updatePageStepNodeClass();
+
+ this._moveToNextActivableNode(this._getAllPageStepNodes(), this.pageStepValue);
+ this.pageStepValue = null;
+ },
+
+ _createPageStepNodes: function(){
+ // summary:
+ // Create the page step nodes if they do not exist
+ var startPage = this._getStartPage(),
+ stepSize = this._getStepPageSize(),
+ label = "",
+ node = null;
+ for(var i = startPage; i < this.maxPageStep + 1; i++){
+ label = dojo.string.substitute(this.plugin.nls.pageStepLabelTemplate, [i + ""]);
+ node = dojo.create("div", {innerHTML: i, value: i, title: label, tabindex: i < startPage + stepSize ? 0 : -1}, this.pageStepperDiv, "last");
+ dijit.setWaiState(node, "label", label);
+ // connect event
+ this.plugin.connect(node, "onclick", dojo.hitch(this, "_onPageStep"));
+ this.plugin.connect(node, "onmouseover", function(e){
+ dojo.addClass(e.target, "dojoxGridPageTextHover");
+ });
+ this.plugin.connect(node, "onmouseout", function(e){
+ dojo.removeClass(e.target, "dojoxGridPageTextHover");
+ });
+ dojo.style(node, "display", i < startPage + stepSize ? "block" : "none");
+ }
+ if(this.pageStepperWidth){
+ dojo.style(this.pageStepperTd, "width", this.pageStepperWidth);
+ }
+ },
+
+ _createWardBtns: function(){
+ // summary:
+ // Create the previous/next/first/last button
+ var self = this;
+ var highContrastLabel = {prevPage: "&#60;", firstPage: "&#171;", nextPage: "&#62;", lastPage: "&#187;"};
+ var createWardBtn = function(value, label, position){
+ var node = dojo.create("div", {value: value, title: label, tabindex: 1}, self.pageStepperDiv, position);
+ self.plugin.connect(node, "onclick", dojo.hitch(self, "_onPageStep"));
+ dijit.setWaiState(node, "label", label);
+ // for high contrast
+ var highConrastNode = dojo.create("span", {value: value, title: label, innerHTML: highContrastLabel[value]}, node, position);
+ dojo.addClass(highConrastNode, "dojoxGridWardButtonInner");
+ };
+ createWardBtn("prevPage", this.plugin.nls.prevTip, "first");
+ createWardBtn("firstPage", this.plugin.nls.firstTip, "first");
+ createWardBtn("nextPage", this.plugin.nls.nextTip, "last");
+ createWardBtn("lastPage", this.plugin.nls.lastTip, "last");
+ },
+
+ _resetPageStepNodes: function(){
+ // summary:
+ // The page step nodes might be changed when fetch data, we need to
+ // update/reset them
+ var startPage = this._getStartPage(),
+ stepSize = this._getStepPageSize(),
+ stepNodes = this.pageStepperDiv.childNodes,
+ node = null;
+ for(var i = startPage, j = 2; j < stepNodes.length - 2; j++, i++){
+ node = stepNodes[j];
+ if(i < startPage + stepSize){
+ dojo.attr(node, "innerHTML", i);
+ dojo.attr(node, "value", i);
+ dojo.style(node, "display", "block");
+ dijit.setWaiState(node, "label", dojo.string.substitute(this.plugin.nls.pageStepLabelTemplate, [i + ""]));
+ }else{
+ dojo.style(node, "display", "none");
+ }
+ }
+ },
+
+ _updatePageStepNodeClass: function(){
+ // summary:
+ // Update the style of the page step nodes
+ var value = null,
+ curPage = this._getCurrentPageNo(),
+ pageCount = this._getPageCount(),
+ visibleNodeLen = 0;
+
+ var updateClass = function(node, isWardBtn, status){
+ var value = node.value,
+ enableClass = isWardBtn ? "dojoxGrid" + value + "Btn" : "dojoxGridInactived",
+ disableClass = isWardBtn ? "dojoxGrid" + value + "BtnDisable" : "dojoxGridActived";
+ if(status){
+ dojo.addClass(node, disableClass);
+ dojo.attr(node, "tabindex", "-1");
+ }else{
+ dojo.addClass(node, enableClass);
+ dojo.attr(node, "tabindex", "0");
+ }
+ };
+ dojo.forEach(this.pageStepperDiv.childNodes, function(node){
+ dojo.removeClass(node);
+ if(isNaN(parseInt(node.value, 10))){
+ dojo.addClass(node, "dojoxGridWardButton");
+ var disablePageNum = node.value == "prevPage" || node.value == "firstPage" ? 1 : pageCount;
+ updateClass(node, true, (curPage == disablePageNum));
+ }else{
+ value = parseInt(node.value, 10);
+ updateClass(node, false, (value === curPage || dojo.style(node, "display") === "none"));
+ }
+ }, this);
+ },
+
+ _showGotoButton: function(flag){
+ this.gotoButton = flag;
+ this._updateGotoButton();
+ },
+
+ _updateGotoButton: function(){
+ // summary:
+ // Create/destroy the goto page button
+ if(!this.gotoButton){
+ if(this.gotoPageTd){
+ if(this._gotoPageDialog){
+ this._gotoPageDialog.destroy();
+ }
+ dojo.destroy(this.gotoPageDiv);
+ dojo.destroy(this.gotoPageTd);
+ delete this.gotoPageDiv;
+ delete this.gotoPageTd;
+ }
+ return;
+ }
+ if(!this.gotoPageTd){
+ this._createGotoNode();
+ }
+ dojo.toggleClass(this.gotoPageDiv, "dojoxGridPaginatorGotoDivDisabled", this.plugin.pageSize >= this.plugin._maxSize);
+ },
+
+ _createGotoNode: function(){
+ // summary:
+ // Create the goto page button
+ this.gotoPageTd = dojo.create("td", {}, dojo.query("tr", this.domNode)[0], "last");
+ dojo.addClass(this.gotoPageTd, "dojoxGridPaginatorGotoTd");
+ this.gotoPageDiv = dojo.create("div", {tabindex: "0", title: this.plugin.nls.gotoButtonTitle}, this.gotoPageTd, "first");
+ dojo.addClass(this.gotoPageDiv, "dojoxGridPaginatorGotoDiv");
+ this.plugin.connect(this.gotoPageDiv, "onclick", dojo.hitch(this, "_openGotopageDialog"));
+ // for high contrast
+ var highConrastNode = dojo.create("span", {title: this.plugin.nls.gotoButtonTitle, innerHTML: "&#8869;"}, this.gotoPageDiv, "last");
+ dojo.addClass(highConrastNode, "dojoxGridWardButtonInner");
+ },
+
+ _openGotopageDialog: function(event){
+ // summary:
+ // Show the goto page dialog
+ if(!this._gotoPageDialog){
+ this._gotoPageDialog = new dojox.grid.enhanced.plugins.pagination._GotoPageDialog(this.plugin);
+ }
+ // focus
+ if(!this._currentFocusNode){
+ this.grid.focus.focusArea("pagination" + this.position, event);
+ }else{
+ this._currentFocusNode = this.gotoPageDiv;
+ }
+ if(this.focusArea != "pageStep"){
+ this.focusArea = "pageStep";
+ }
+ this._gotoPageDialog.updatePageCount();
+ this._gotoPageDialog.showDialog();
+ },
+
+ // ===== focus handlers ===== //
+ _onFocusPaginator: function(event, step){
+ // summary:
+ // Focus handler
+ if(!this._currentFocusNode){
+ if(step > 0){
+ return this._onFocusPageSizeNode(event) ? true : this._onFocusPageStepNode(event);
+ }else if(step < 0){
+ return this._onFocusPageStepNode(event) ? true : this._onFocusPageSizeNode(event);
+ }else{
+ return false;
+ }
+ }else{
+ if(step > 0){
+ return this.focusArea === "pageSize" ? this._onFocusPageStepNode(event) : false;
+ }else if(step < 0){
+ return this.focusArea === "pageStep" ? this._onFocusPageSizeNode(event) : false;
+ }else{
+ return false;
+ }
+ }
+ },
+
+ _onFocusPageSizeNode: function(event){
+ // summary:
+ // Focus the page size area, if there is no focusable node, return false
+ var pageSizeNodes = this._getPageSizeActivableNodes();
+ if(event && event.type !== "click"){
+ if(pageSizeNodes[0]){
+ dijit.focus(pageSizeNodes[0]);
+ this._currentFocusNode = pageSizeNodes[0];
+ this.focusArea = "pageSize";
+ this.plugin._stopEvent(event);
+ return true;
+ }else{
+ return false;
+ }
+ }
+ if(event && event.type == "click"){
+ if(dojo.indexOf(this._getPageSizeActivableNodes(), event.target) > -1){
+ this.focusArea = "pageSize";
+ this.plugin._stopEvent(event);
+ return true;
+ }
+ }
+ return false;
+ },
+
+ _onFocusPageStepNode: function(event){
+ // summary:
+ // Focus the page step area, if there is no focusable node, return false
+ var pageStepNodes = this._getPageStepActivableNodes();
+ if(event && event.type !== "click"){
+ if(pageStepNodes[0]){
+ dijit.focus(pageStepNodes[0]);
+ this._currentFocusNode = pageStepNodes[0];
+ this.focusArea = "pageStep";
+ this.plugin._stopEvent(event);
+ return true;
+ }else if(this.gotoPageDiv){
+ dijit.focus(this.gotoPageDiv);
+ this._currentFocusNode = this.gotoPageDiv;
+ this.focusArea = "pageStep";
+ this.plugin._stopEvent(event);
+ return true;
+ }else{
+ return false;
+ }
+ }
+ if(event && event.type == "click"){
+ if(dojo.indexOf(this._getPageStepActivableNodes(), event.target) > -1){
+ this.focusArea = "pageStep";
+ this.plugin._stopEvent(event);
+ return true;
+ }else if(event.target == this.gotoPageDiv){
+ dijit.focus(this.gotoPageDiv);
+ this._currentFocusNode = this.gotoPageDiv;
+ this.focusArea = "pageStep";
+ this.plugin._stopEvent(event);
+ return true;
+ }
+ }
+ return false;
+ },
+
+ _onFocusGotoPageNode: function(event){
+ // summary:
+ // Focus the goto page button, if there is no focusable node, return false
+ if(!this.gotoButton || !this.gotoPageTd){
+ return false;
+ }
+ if(event && event.type !== "click" || (event.type == "click" && event.target == this.gotoPageDiv)){
+ dijit.focus(this.gotoPageDiv);
+ this._currentFocusNode = this.gotoPageDiv;
+ this.focusArea = "gotoButton";
+ this.plugin._stopEvent(event);
+ return true;
+ }
+ return true;
+ },
+
+ _onBlurPaginator: function(event, step){
+ var pageSizeNodes = this._getPageSizeActivableNodes(),
+ pageStepNodes = this._getPageStepActivableNodes();
+
+ if(step > 0 && this.focusArea === "pageSize" && (pageStepNodes.length > 1 || this.gotoButton)){
+ return false;
+ }else if(step < 0 && this.focusArea === "pageStep" && pageSizeNodes.length > 1){
+ return false;
+ }
+ this._currentFocusNode = null;
+ this.focusArea = null;
+ return true;
+ },
+
+ _onKeyDown: function(event, isBubble){
+ // summary:
+ // Focus navigation
+ if(isBubble){
+ return;
+ }
+ if(event.altKey || event.metaKey){
+ return;
+ }
+ var dk = dojo.keys;
+ if(event.keyCode === dk.ENTER || event.keyCode === dk.SPACE){
+ if(dojo.indexOf(this._getPageStepActivableNodes(), this._currentFocusNode) > -1){
+ this._onPageStep(event);
+ }else if(dojo.indexOf(this._getPageSizeActivableNodes(), this._currentFocusNode) > -1){
+ this._onSwitchPageSize(event);
+ }else if(this._currentFocusNode === this.gotoPageDiv){
+ this._openGotopageDialog(event);
+ }
+ }
+ this.plugin._stopEvent(event);
+ },
+
+ _moveFocus: function(rowDelta, colDelta, evt){
+ // summary:
+ // Move focus according row delta&column delta
+ var nodes;
+ if(this.focusArea == "pageSize"){
+ nodes = this._getPageSizeActivableNodes();
+ }else if(this.focusArea == "pageStep"){
+ nodes = this._getPageStepActivableNodes();
+ if(this.gotoPageDiv){
+ nodes.push(this.gotoPageDiv);
+ }
+ }
+ if(nodes.length < 1){
+ return;
+ }
+ var currentIdx = dojo.indexOf(nodes, this._currentFocusNode);
+ var focusIdx = currentIdx + colDelta;
+ if(focusIdx >= 0 && focusIdx < nodes.length){
+ dijit.focus(nodes[focusIdx]);
+ this._currentFocusNode = nodes[focusIdx];
+ }
+ this.plugin._stopEvent(evt);
+ },
+
+ _getPageSizeActivableNodes: function(){
+ return dojo.query("span[tabindex='0']", this.sizeSwitchTd);
+ },
+
+ _getPageStepActivableNodes: function(){
+ return (dojo.query("div[tabindex='0']", this.pageStepperDiv));
+ },
+
+ _getAllPageSizeNodes: function(){
+ var nodeList = [];
+ dojo.forEach(this.sizeSwitchTd.childNodes, function(node){
+ if(node.value){
+ nodeList.push(node);
+ }
+ });
+ return nodeList;
+ },
+
+ _getAllPageStepNodes: function(){
+ var nodeList = [];
+ for(var i = 0, len = this.pageStepperDiv.childNodes.length; i < len; i++){
+ nodeList.push(this.pageStepperDiv.childNodes[i]);
+ }
+ return nodeList;
+ },
+
+ _moveToNextActivableNode: function(nodeList, curNodeValue){
+ // summary:
+ // Need to move the focus to next node since current node is inactive and unfocusable
+ if(!curNodeValue){
+ return;
+ }
+ if(nodeList.length < 2){
+ this.grid.focus.tab(1);
+ }
+ var nl = [],
+ node = null,
+ index = 0;
+ dojo.forEach(nodeList, function(n){
+ if(n.value == curNodeValue){
+ nl.push(n);
+ node = n;
+ }else if(dojo.attr(n, "tabindex") == "0"){
+ nl.push(n);
+ }
+ });
+ if(nl.length < 2){
+ this.grid.focus.tab(1);
+ }
+ index = dojo.indexOf(nl, node);
+ if(dojo.attr(node, "tabindex") != "0"){
+ node = nl[index + 1] ? nl[index + 1] : nl[index - 1];
+ }
+ dijit.focus(node);
+ this._currentFocusNode = node;
+ },
+
+ // ===== pagination events handlers ===== //
+ _onSwitchPageSize: function(/*Event*/e){
+ // summary:
+ // The handler of switch the page size
+ var size = this.pageSizeValue = e.target.value;
+ if(!size){
+ return;
+ }
+ if(dojo.trim(size.toLowerCase()) == "all"){
+ size = this._maxItemSize;
+ }
+ this.plugin.showAll = parseInt(size, 10) >= this._maxItemSize ? true : false;
+ this.plugin.grid.usingPagination = !this.plugin.showAll;
+
+ size = parseInt(size, 10);
+ if(isNaN(size) || size <= 0/* || size == this.currentPageSize*/){
+ return;
+ }
+
+ if(!this._currentFocusNode){
+ this.grid.focus.currentArea("pagination" + this.position);
+ }
+ if(this.focusArea != "pageSize"){
+ this.focusArea = "pageSize";
+ }
+ this.plugin.changePageSize(size);
+ },
+
+ _onPageStep: function(/*Event*/e){
+ // summary:
+ // The handler jump page event
+ var p = this.plugin,
+ value = this.pageStepValue = e.target.value;
+
+ if(!this._currentFocusNode){
+ this.grid.focus.currentArea("pagination" + this.position);
+ }
+ if(this.focusArea != "pageStep"){
+ this.focusArea = "pageStep";
+ }
+ if(!isNaN(parseInt(value, 10))){
+ p.gotoPage(value);
+ }else{
+ switch(e.target.value){
+ case "prevPage":
+ p.prevPage();
+ break;
+ case "nextPage":
+ p.nextPage();
+ break;
+ case "firstPage":
+ p.gotoFirstPage();
+ break;
+ case "lastPage":
+ p.gotoLastPage();
+ }
+ }
+ },
+
+ // ===== information getters ===== //
+ _getCurrentPageNo: function(){
+ return this.plugin._currentPage + 1;
+ },
+
+ _getPageCount: function(){
+ if(!this._maxItemSize || !this.currentPageSize){
+ return 0;
+ }
+ return Math.ceil(this._maxItemSize / this.currentPageSize);
+ },
+
+ _getStartPage: function(){
+ var cp = this._getCurrentPageNo();
+ var ms = parseInt(this.maxPageStep / 2, 10);
+ var pc = this._getPageCount();
+ if(cp < ms || (cp - ms) < 1){
+ return 1;
+ }else if(pc <= this.maxPageStep){
+ return 1;
+ }else{
+ if(pc - cp < ms && cp - this.maxPageStep >= 0){
+ return pc - this.maxPageStep + 1;
+ }else{
+ return (cp - ms);
+ }
+ }
+ },
+
+ _getStepPageSize: function(){
+ var sp = this._getStartPage();
+ var count = this._getPageCount();
+ if((sp + this.maxPageStep) > count){
+ return count - sp + 1;
+ }else{
+ return this.maxPageStep;
+ }
+ }
+
+});
+
+dojo.declare("dojox.grid.enhanced.plugins.pagination._GotoPageDialog", null, {
+
+ pageCount: 0,
+
+ constructor: function(plugin){
+ this.plugin = plugin;
+ this.pageCount = this.plugin.paginators[0]._getPageCount();
+ this._dialogNode = dojo.create("div", {}, dojo.body(), "last");
+ this._gotoPageDialog = new dojox.grid.enhanced.plugins.Dialog({
+ "refNode": plugin.grid.domNode,
+ "title": this.plugin.nls.dialogTitle
+ }, this._dialogNode);
+ this._createDialogContent();
+ this._gotoPageDialog.startup();
+ },
+
+ _createDialogContent: function(){
+ // summary:
+ // Create the dialog content
+ this._specifyNode = dojo.create("div", {innerHTML: this.plugin.nls.dialogIndication}, this._gotoPageDialog.containerNode, "last");
+
+ this._pageInputDiv = dojo.create("div", {}, this._gotoPageDialog.containerNode, "last");
+ this._pageTextBox = new dijit.form.NumberTextBox();
+ this._pageTextBox.constraints = {fractional:false, min:1, max:this.pageCount};
+ this.plugin.connect(this._pageTextBox.textbox, "onkeyup", dojo.hitch(this, "_setConfirmBtnState"));
+
+ this._pageInputDiv.appendChild(this._pageTextBox.domNode);
+ this._pageLabel = dojo.create("label", {innerHTML: dojo.string.substitute(this.plugin.nls.pageCountIndication, [this.pageCount])}, this._pageInputDiv, "last");
+
+ this._buttonDiv = dojo.create("div", {}, this._gotoPageDialog.containerNode, "last");
+ this._confirmBtn = new dijit.form.Button({label: this.plugin.nls.dialogConfirm, onClick: dojo.hitch(this, this._onConfirm)});
+ this._confirmBtn.set("disabled", true);
+
+ this._cancelBtn = new dijit.form.Button({label: this.plugin.nls.dialogCancel, onClick: dojo.hitch(this, this._onCancel)});
+ this._buttonDiv.appendChild(this._confirmBtn.domNode);
+ this._buttonDiv.appendChild(this._cancelBtn.domNode);
+ this._styleContent();
+ this._gotoPageDialog.onCancel = dojo.hitch(this, this._onCancel);
+ this.plugin.connect(this._gotoPageDialog, "_onKey", dojo.hitch(this, "_onKeyDown"));
+ },
+
+ _styleContent: function(){
+ dojo.addClass(this._specifyNode, "dojoxGridDialogMargin");
+ dojo.addClass(this._pageInputDiv, "dojoxGridDialogMargin");
+ dojo.addClass(this._buttonDiv, "dojoxGridDialogButton");
+ dojo.style(this._pageTextBox.domNode, "width", "50px");
+ },
+
+ updatePageCount: function(){
+ this.pageCount = this.plugin.paginators[0]._getPageCount();
+ this._pageTextBox.constraints = {fractional:false, min:1, max:this.pageCount};
+ dojo.attr(this._pageLabel, "innerHTML", dojo.string.substitute(this.plugin.nls.pageCountIndication, [this.pageCount]));
+ },
+
+ showDialog: function(){
+ this._gotoPageDialog.show();
+ },
+
+ _onConfirm: function(event){
+ // summary:
+ // Jump to the given page
+ if(this._pageTextBox.isValid() && this._pageTextBox.getDisplayedValue() !== ""){
+ this.plugin.gotoPage(this._pageTextBox.getDisplayedValue());
+ this._gotoPageDialog.hide();
+ this._pageTextBox.reset();
+ }
+ this.plugin._stopEvent(event);
+ },
+
+ _onCancel: function(event){
+ // summary:
+ // Cancel action and hide the dialog
+ this._pageTextBox.reset();
+ this._gotoPageDialog.hide();
+ this.plugin._stopEvent(event);
+ },
+
+ _onKeyDown: function(event){
+ if(event.altKey || event.metaKey){
+ return;
+ }
+ var dk = dojo.keys;
+ if(event.keyCode === dk.ENTER){
+ this._onConfirm(event);
+ }
+ },
+
+ _setConfirmBtnState: function(){
+ if(this._pageTextBox.isValid() && this._pageTextBox.getDisplayedValue() !== ""){
+ this._confirmBtn.set("disabled", false);
+ }else{
+ this._confirmBtn.set("disabled", true);
+ }
+ },
+
+ destroy: function(){
+ this._pageTextBox.destroy();
+ this._confirmBtn.destroy();
+ this._cancelBtn.destroy();
+ this._gotoPageDialog.destroy();
+
+ dojo.destroy(this._specifyNode);
+ dojo.destroy(this._pageInputDiv);
+ dojo.destroy(this._pageLabel);
+ dojo.destroy(this._buttonDiv);
+ dojo.destroy(this._dialogNode);
+ }
+});
+
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Pagination/*name:'pagination'*/);
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Pagination.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Pagination.xd.js
new file mode 100644
index 0000000..97a6497
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Pagination.xd.js
@@ -0,0 +1,1245 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.Pagination"],
+["require", "dijit.form.NumberTextBox"],
+["require", "dijit.form.Button"],
+["require", "dojox.grid.enhanced._Plugin"],
+["require", "dojox.grid.enhanced.plugins.Dialog"],
+["require", "dojox.grid.enhanced.plugins._StoreLayer"],
+["requireLocalization", "dojox.grid.enhanced", "Pagination", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ru,sl,sv,th,tr,zh,zh-tw", "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ru,sl,sv,th,tr,zh,zh-tw"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.Pagination"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Pagination"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Pagination");
+
+dojo.require("dijit.form.NumberTextBox");
+dojo.require("dijit.form.Button");
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid.enhanced.plugins.Dialog");
+dojo.require("dojox.grid.enhanced.plugins._StoreLayer");
+
+;
+
+dojo.declare("dojox.grid.enhanced.plugins.Pagination", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // The typical pagination way as an alternative to deal with huge data set besides the default virtual scrolling way
+
+ name: "pagination",
+ // The page size used with the store, default = 25.
+ pageSize: 25,
+
+ defaultRows: 25,
+
+ //current page we are at
+ _currentPage: 0,
+
+ //The currently obtained max # of rows to page through.
+ _maxSize: 0,
+
+ init: function(){
+ this.gh = null;
+ this.grid.rowsPerPage = this.pageSize = this.grid.rowsPerPage ? this.grid.rowsPerPage : this.pageSize;
+ this.grid.usingPagination = true;
+ this.nls = dojo.i18n.getLocalization("dojox.grid.enhanced", "Pagination");
+
+ this._wrapStoreLayer();
+ this._createPaginators(this.option);
+
+ this._regApis();
+ },
+
+ _createPaginators: function(paginationArgs){
+ // summary:
+ // Function to create the pagination control bar.
+ this.paginators = [];
+ if(paginationArgs.position === "both"){
+ this.paginators = [
+ new dojox.grid.enhanced.plugins._Paginator(dojo.mixin(paginationArgs, {position: "bottom", plugin: this})),
+ new dojox.grid.enhanced.plugins._Paginator(dojo.mixin(paginationArgs, {position: "top", plugin: this}))
+ ];
+ }else{
+ this.paginators = [new dojox.grid.enhanced.plugins._Paginator(dojo.mixin(paginationArgs, {plugin: this}))];
+ }
+ },
+
+ _wrapStoreLayer: function(){
+ var g = this.grid,
+ ns = dojox.grid.enhanced.plugins;
+ this._store = g.store;
+ this.query = g.query;
+
+ this.forcePageStoreLayer = new ns._ForcedPageStoreLayer(this);
+ ns.wrap(g, "_storeLayerFetch", this.forcePageStoreLayer);
+
+ this.connect(g, "setQuery", function(query){
+ if(query !== this.query){
+ this.query = query;
+ }
+ });
+ },
+
+ _stopEvent: function(event){
+ try{
+ dojo.stopEvent(event);
+ }catch(e){}
+ },
+
+ _onNew: function(item, parentInfo){
+ var totalPages = Math.ceil(this._maxSize / this.pageSize);
+ if(((this._currentPage + 1 === totalPages || totalPages === 0) && this.grid.rowCount < this.pageSize) || this.showAll){
+ dojo.hitch(this.grid, this._originalOnNew)(item, parentInfo);
+ this.forcePageStoreLayer.endIdx++;
+ }
+ this._maxSize++;
+ if(this.showAll){
+ this.pageSize++;
+ }
+ if(this.showAll && this.grid.autoHeight){
+ this.grid._refresh();
+ }else{
+ dojo.forEach(this.paginators, function(p){
+ p.update();
+ });
+ }
+ },
+
+ _removeSelectedRows: function(){
+ this._multiRemoving = true;
+ this._originalRemove();
+ this._multiRemoving = false;
+ this.grid.resize();
+ this.grid._refresh();
+ },
+
+ _onDelete: function(){
+ if(!this._multiRemoving){
+ this.grid.resize();
+ if(this.showAll){
+ this.grid._refresh();
+ }
+ }
+ if(this.grid.get('rowCount') === 0){
+ this.prevPage();
+ }
+ },
+
+ _regApis: function(){
+ // summary:
+ // register pagination public APIs to grid.
+ var g = this.grid;
+ // New added APIs
+ g.gotoPage = dojo.hitch(this, this.gotoPage);
+ g.nextPage = dojo.hitch(this, this.nextPage);
+ g.prevPage = dojo.hitch(this, this.prevPage);
+ g.gotoFirstPage = dojo.hitch(this, this.gotoFirstPage);
+ g.gotoLastPage = dojo.hitch(this, this.gotoLastPage);
+ g.changePageSize = dojo.hitch(this, this.changePageSize);
+ g.showGotoPageButton = dojo.hitch(this, this.showGotoPageButton);
+ g.getTotalRowCount = dojo.hitch(this, this.getTotalRowCount);
+ // Changed APIs
+ this.originalScrollToRow = dojo.hitch(g, g.scrollToRow);
+ g.scrollToRow = dojo.hitch(this, this.scrollToRow);
+ this._originalOnNew = dojo.hitch(g, g._onNew);
+ this._originalRemove = dojo.hitch(g, g.removeSelectedRows);
+ g.removeSelectedRows = dojo.hitch(this, this._removeSelectedRows);
+ g._onNew = dojo.hitch(this, this._onNew);
+ this.connect(g, "_onDelete", dojo.hitch(this, this._onDelete));
+ },
+
+ destroy: function(){
+ this.inherited(arguments);
+ var g = this.grid;
+ try{
+ dojo.forEach(this.paginators, function(p){
+ p.destroy();
+ });
+ g.unwrap(this.forcePageStoreLayer.name());
+ g._onNew = this._originalOnNew;
+ g.removeSelectedRows = this._originalRemove;
+ g.scrollToRow = this.originalScrollToRow;
+ this.paginators = null;
+ this.nls = null;
+ }catch(e){
+ console.warn("Pagination.destroy() error: ", e);
+ }
+ },
+
+ nextPage: function(){
+ // summary:
+ // Function to handle shifting to the next page in the list.
+ if(this._maxSize > ((this._currentPage + 1) * this.pageSize)){
+ //Current page is indexed at 0 and gotoPage expects 1-X. So to go
+ //up one, pass current page + 2!
+ this.gotoPage(this._currentPage + 2);
+ }
+ },
+
+ prevPage: function(){
+ // summary:
+ // Function to handle shifting to the previous page in the list.
+ if(this._currentPage > 0){
+ //Current page is indexed at 0 and gotoPage expects 1-X. So to go
+ //back one, pass current page!
+ this.gotoPage(this._currentPage);
+ }
+ },
+
+ gotoPage: function(page){
+ // summary:
+ // Function to handle shifting to an arbirtary page in the list.
+ // page:
+ // The page to go to, starting at 1.
+ var totalPages = Math.ceil(this._maxSize / this.pageSize);
+ page--;
+ if(page < totalPages && page >= 0 && this._currentPage !== page){
+ this._currentPage = page;
+ // this._updateSelected();
+ this.grid.setQuery(this.query);
+ this.grid.resize();
+ }
+ },
+
+ gotoFirstPage: function(){
+ // summary:
+ // Go to the first page
+ this.gotoPage(1);
+ },
+
+ gotoLastPage: function(){
+ // summary:
+ // Go to the last page
+ var totalPages = Math.ceil(this._maxSize / this.pageSize);
+ this.gotoPage(totalPages);
+ },
+
+ changePageSize: function(size){
+ // summary:
+ // Change size of items per page.
+ // This function will only be called by _Paginator
+ if(typeof size == "string"){
+ size = parseInt(size, 10);
+ }
+ var startIndex = this.pageSize * this._currentPage;
+ dojo.forEach(this.paginators, function(f){
+ f.currentPageSize = this.grid.rowsPerPage = this.pageSize = size;
+ if(size >= this._maxSize){
+ this.grid.rowsPerPage = this.defaultRows;
+ this.grid.usingPagination = false;
+ }else{
+ this.grid.usingPagination = true;
+ }
+ }, this);
+ var endIndex = startIndex + Math.min(this.pageSize, this._maxSize);
+ if(endIndex > this._maxSize){
+ this.gotoLastPage();
+ }else{
+ var cp = Math.ceil(startIndex / this.pageSize);
+ if(cp !== this._currentPage){
+ this.gotoPage(cp + 1);
+ }else{
+ this.grid._refresh(true);
+ }
+ }
+ this.grid.resize();
+ },
+
+ showGotoPageButton: function(flag){
+ // summary:
+ // For show/hide the go to page button dynamically
+ // flag: boolean
+ // Show the go to page button when flag is true, otherwise hide it
+ dojo.forEach(this.paginators, function(p){
+ p._showGotoButton(flag);
+ });
+ },
+
+ scrollToRow: function(inRowIndex){
+ // summary:
+ // Override the grid.scrollToRow(), could jump to the right page
+ // and scroll to the specific row
+ // inRowIndex: integer
+ // The row index
+ var page = parseInt(inRowIndex / this.pageSize, 10),
+ totalPages = Math.ceil(this._maxSize / this.pageSize);
+ if(page > totalPages){
+ return;
+ }
+ this.gotoPage(page + 1);
+ var rowIdx = inRowIndex % this.pageSize;
+ this.grid.setScrollTop(this.grid.scroller.findScrollTop(rowIdx) + 1);
+ },
+
+ getTotalRowCount: function(){
+ // summary:
+ // Function for get total row count
+ return this._maxSize;
+ }
+});
+
+dojo.declare("dojox.grid.enhanced.plugins._ForcedPageStoreLayer", dojox.grid.enhanced.plugins._StoreLayer, {
+ tags: ["presentation"],
+
+ constructor: function(plugin){
+ this._plugin = plugin;
+ },
+
+ _fetch: function(request){
+ var self = this,
+ plugin = self._plugin,
+ grid = plugin.grid,
+ scope = request.scope || dojo.global,
+ onBegin = request.onBegin;
+
+ request.start = plugin._currentPage * plugin.pageSize + request.start;
+ self.startIdx = request.start;
+ self.endIdx = request.start + plugin.pageSize - 1;
+ if(onBegin && (plugin.showAll || dojo.every(plugin.paginators, function(p){
+ return plugin.showAll = !p.sizeSwitch && !p.pageStepper && !p.gotoButton;
+ }))){
+ request.onBegin = function(size, req){
+ plugin._maxSize = plugin.pageSize = size;
+ self.startIdx = 0;
+ self.endIdx = size - 1;
+ dojo.forEach(plugin.paginators, function(f){
+ f.update();
+ });
+ req.onBegin = onBegin;
+ req.onBegin.call(scope, size, req);
+ };
+ }else if(onBegin){
+ request.onBegin = function(size, req){
+ req.start = 0;
+ req.count = plugin.pageSize;
+ plugin._maxSize = size;
+ self.endIdx = self.endIdx > size ? (size - 1) : self.endIdx;
+ if(self.startIdx > size && size !== 0){
+ grid._pending_requests[req.start] = false;
+ plugin.gotoFirstPage();
+ }
+ dojo.forEach(plugin.paginators, function(f){
+ f.update();
+ });
+ req.onBegin = onBegin;
+ req.onBegin.call(scope, Math.min(plugin.pageSize, (size - self.startIdx)), req);
+ };
+ }
+ return dojo.hitch(this._store, this._originFetch)(request);
+ }
+});
+
+dojo.declare("dojox.grid.enhanced.plugins._Paginator", [dijit._Widget,dijit._Templated], {
+ templateString:"<div dojoAttachPoint=\"paginatorBar\">\r\n\t<table cellpadding=\"0\" cellspacing=\"0\" class=\"dojoxGridPaginator\">\r\n\t\t<tr>\r\n\t\t\t<td dojoAttachPoint=\"descriptionTd\" class=\"dojoxGridDescriptionTd\">\r\n\t\t\t\t<div dojoAttachPoint=\"descriptionDiv\" class=\"dojoxGridDescription\" />\r\n\t\t\t</td>\r\n\t\t\t<td dojoAttachPoint=\"sizeSwitchTd\"></td>\r\n\t\t\t<td dojoAttachPoint=\"pageStepperTd\" class=\"dojoxGridPaginatorFastStep\">\r\n\t\t\t\t<div dojoAttachPoint=\"pageStepperDiv\" class=\"dojoxGridPaginatorStep\"></div>\r\n\t\t\t</td>\r\n\t\t</tr>\r\n\t</table>\r\n</div>\r\n",
+
+ // pagination bar position - "bottom"|"top"
+ position: "bottom",
+
+ // max data item size
+ _maxItemSize: 0,
+
+ // description message status params
+ description: true,
+
+ // fast step page status params
+ pageStepper: true,
+
+ maxPageStep: 7,
+
+ // items per page size switch params
+ sizeSwitch: true,
+
+ pageSizes: ["10", "25", "50", "100", "All"],
+
+ gotoButton: false,
+
+ constructor: function(params){
+ dojo.mixin(this, params);
+ this.grid = this.plugin.grid;
+ this.itemTitle = this.itemTitle ? this.itemTitle : this.plugin.nls.itemTitle;
+ this.descTemplate = this.descTemplate ? this.descTemplate : this.plugin.nls.descTemplate;
+ },
+
+ postCreate: function(){
+ this.inherited(arguments);
+ this._setWidthValue();
+ var self = this;
+ var g = this.grid;
+ this.plugin.connect(g, "_resize", dojo.hitch(this, "_resetGridHeight"));
+ this._originalResize = dojo.hitch(g, "resize");
+ g.resize = function(changeSize, resultSize){
+ self._changeSize = g._pendingChangeSize = changeSize;
+ self._resultSize = g._pendingResultSize = resultSize;
+ g.sizeChange();
+ };
+ this._placeSelf();
+ },
+
+ destroy: function(){
+ this.inherited(arguments);
+ this.grid.focus.removeArea("pagination" + this.position.toLowerCase());
+ if(this._gotoPageDialog){
+ this._gotoPageDialog.destroy();
+ dojo.destroy(this.gotoPageTd);
+ delete this.gotoPageTd;
+ delete this._gotoPageDialog;
+ }
+ this.grid.resize = this._originalResize;
+ this.pageSizes = null;
+ },
+
+ update: function(){
+ // summary:
+ // Function to update paging information and update
+ // pagination bar display.
+ this.currentPageSize = this.plugin.pageSize;
+ this._maxItemSize = this.plugin._maxSize;
+
+ // update pagination bar display information
+ this._updateDescription();
+ this._updatePageStepper();
+ this._updateSizeSwitch();
+ this._updateGotoButton();
+ },
+
+ _setWidthValue: function(){
+ var type = ["description", "sizeSwitch", "pageStepper"];
+ var endWith = function(str1, str2){
+ var reg = new RegExp(str2+"$");
+ return reg.test(str1);
+ };
+ dojo.forEach(type, function(t){
+ var width, flag = this[t];
+ if(flag === undefined || typeof flag == "boolean"){
+ return;
+ }
+ if(dojo.isString(flag)){
+ width = endWith(flag, "px") || endWith(flag, "%") || endWith(flag, "em") ? flag : parseInt(flag, 10) > 0 ? parseInt(flag, 10) + "px" : null;
+ }else if(typeof flag === "number" && flag > 0){
+ width = flag + "px";
+ }
+ this[t] = width ? true : false;
+ this[t + "Width"] = width;
+ }, this);
+ },
+
+ _regFocusMgr: function(position){
+ // summary:
+ // Function to register pagination bar to focus manager.
+ this.grid.focus.addArea({
+ name: "pagination" + position,
+ onFocus: dojo.hitch(this, this._onFocusPaginator),
+ onBlur: dojo.hitch(this, this._onBlurPaginator),
+ onMove: dojo.hitch(this, this._moveFocus),
+ onKeyDown: dojo.hitch(this, this._onKeyDown)
+ });
+ switch(position){
+ case "top":
+ this.grid.focus.placeArea("pagination" + position, "before", "header");
+ break;
+ case "bottom":
+ default:
+ this.grid.focus.placeArea("pagination" + position, "after", "content");
+ break;
+ }
+ },
+
+ _placeSelf: function(){
+ // summary:
+ // Place pagination bar to a position.
+ // There are two options, top of the grid, bottom of the grid.
+ var g = this.grid;
+ var position = dojo.trim(this.position.toLowerCase());
+ switch(position){
+ case "top":
+ this.placeAt(g.viewsHeaderNode, "before");
+ this._regFocusMgr("top");
+ break;
+ case "bottom":
+ default:
+ this.placeAt(g.viewsNode, "after");
+ this._regFocusMgr("bottom");
+ break;
+ }
+ },
+
+ _resetGridHeight: function(changeSize, resultSize){
+ // summary:
+ // Function of resize grid height to place this pagination bar.
+ // Since the grid would be able to add other element in its domNode, we have
+ // change the grid view size to place the pagination bar.
+ // This function will resize the grid viewsNode height, scorllboxNode height
+ var g = this.grid;
+ changeSize = changeSize || this._changeSize;
+ resultSize = resultSize || this._resultSize;
+ delete this._changeSize;
+ delete this._resultSize;
+ if(g._autoHeight){
+ return;
+ }
+ var padBorder = g._getPadBorder().h;
+ if(!this.plugin.gh){
+ this.plugin.gh = dojo.contentBox(g.domNode).h + 2 * padBorder;
+ }
+ if(resultSize){
+ changeSize = resultSize;
+ }
+ if(changeSize){
+ this.plugin.gh = dojo.contentBox(g.domNode).h + 2 * padBorder;
+ }
+ var gh = this.plugin.gh,
+ hh = g._getHeaderHeight(),
+ ph = dojo.marginBox(this.domNode).h;
+ ph = this.plugin.paginators[1] ? ph * 2 : ph;
+ if(typeof g.autoHeight == "number"){
+ var cgh = gh + ph - padBorder;
+ dojo.style(g.domNode, "height", cgh + "px");
+ dojo.style(g.viewsNode, "height", (cgh - ph - hh) + "px");
+
+ this._styleMsgNode(hh, dojo.marginBox(g.viewsNode).w, cgh - ph - hh);
+ }else{
+ var h = gh - ph - hh - padBorder;
+ dojo.style(g.viewsNode, "height", h + "px");
+ var hasHScroller = dojo.some(g.views.views, function(v){
+ return v.hasHScrollbar();
+ });
+ dojo.forEach(g.viewsNode.childNodes, function(c, idx){
+ dojo.style(c, "height", h + "px");
+ });
+ dojo.forEach(g.views.views, function(v, idx){
+ if(v.scrollboxNode){
+ if(!v.hasHScrollbar() && hasHScroller){
+ dojo.style(v.scrollboxNode, "height", (h - dojox.html.metrics.getScrollbar().h) + "px");
+ }else{
+ dojo.style(v.scrollboxNode, "height", h + "px");
+ }
+ }
+ });
+ this._styleMsgNode(hh, dojo.marginBox(g.viewsNode).w, h);
+ }
+ },
+
+ _styleMsgNode: function(top, width, height){
+ var messagesNode = this.grid.messagesNode;
+ dojo.style(messagesNode, {"position": "absolute", "top": top + "px", "width": width + "px", "height": height + "px", "z-Index": "100"});
+ },
+
+ _updateDescription: function(){
+ // summary:
+ // Update size information.
+ var s = this.plugin.forcePageStoreLayer;
+ if(this.description && this.descriptionDiv){
+ this.descriptionDiv.innerHTML = this._maxItemSize > 0 ? dojo.string.substitute(this.descTemplate, [this.itemTitle, this._maxItemSize, s.startIdx + 1, s.endIdx + 1]) : "0 " + this.itemTitle;
+ }
+ if(this.descriptionWidth){
+ dojo.style(this.descriptionTd, "width", this.descriptionWidth);
+ }
+ },
+
+ _updateSizeSwitch: function(){
+ // summary:
+ // Update "items per page" information.
+ if(!this.sizeSwitchTd){
+ return;
+ }
+ if(!this.sizeSwitch || this._maxItemSize <= 0){
+ dojo.style(this.sizeSwitchTd, "display", "none");
+ return;
+ }else{
+ dojo.style(this.sizeSwitchTd, "display", "");
+ }
+ if(this.initializedSizeNode && !this.pageSizeValue){
+ // do not update page size if page size was not changed
+ return;
+ }
+ if(this.sizeSwitchTd.childNodes.length < 1){
+ this._createSizeSwitchNodes();
+ }
+ this._updateSwitchNodeClass();
+
+ // move focus to next activable node
+ this._moveToNextActivableNode(this._getAllPageSizeNodes(), this.pageSizeValue);
+ this.pageSizeValue = null;
+ },
+
+ _createSizeSwitchNodes: function(){
+ // summary:
+ // The function to create the size switch nodes
+ var node = null;
+ if(!this.pageSizes || this.pageSizes.length < 1){
+ return;
+ }
+ dojo.forEach(this.pageSizes, function(size){
+ // create page size switch node
+ size = dojo.trim(size);
+ var labelValue = size.toLowerCase() == "all" ? this.plugin.nls.allItemsLabelTemplate : dojo.string.substitute(this.plugin.nls.pageSizeLabelTemplate, [size]);
+ node = dojo.create("span", {innerHTML: size, title: labelValue, value: size, tabindex: 0}, this.sizeSwitchTd, "last");
+ // for accessibility
+ dijit.setWaiState(node, "label", labelValue);
+ // connect event
+ this.plugin.connect(node, "onclick", dojo.hitch(this, "_onSwitchPageSize"));
+ this.plugin.connect(node, "onmouseover", function(e){
+ dojo.addClass(e.target, "dojoxGridPageTextHover");
+ });
+ this.plugin.connect(node, "onmouseout", function(e){
+ dojo.removeClass(e.target, "dojoxGridPageTextHover");
+ });
+ // create a separation node
+ node = dojo.create("span", {innerHTML: "|"}, this.sizeSwitchTd, "last");
+ dojo.addClass(node, "dojoxGridSeparator");
+ }, this);
+ // delete last separation node
+ dojo.destroy(node);
+ this.initializedSizeNode = true;
+ if(this.sizeSwitchWidth){
+ dojo.style(this.sizeSwitchTd, "width", this.sizeSwitchWidth);
+ }
+ },
+
+ _updateSwitchNodeClass: function(){
+ // summary:
+ // Update the switch nodes style
+ var size = null;
+ var hasActivedNode = false;
+ var styleNode = function(node, status){
+ if(status){
+ dojo.addClass(node, "dojoxGridActivedSwitch");
+ dojo.attr(node, "tabindex", "-1");
+ hasActivedNode = true;
+ }else{
+ dojo.addClass(node, "dojoxGridInactiveSwitch");
+ dojo.attr(node, "tabindex", "0");
+ }
+ };
+ dojo.forEach(this.sizeSwitchTd.childNodes, function(node){
+ if(node.value){
+ size = node.value;
+ dojo.removeClass(node);
+ if(this.pageSizeValue){
+ styleNode(node, size === this.pageSizeValue && !hasActivedNode);
+ }else{
+ if(size.toLowerCase() == "all"){
+ size = this._maxItemSize;
+ }
+ styleNode(node, this.currentPageSize === parseInt(size, 10) && !hasActivedNode);
+ }
+ }
+ }, this);
+ },
+
+ _updatePageStepper: function(){
+ // summary:
+ // Update the page step nodes
+ if(!this.pageStepperTd){
+ return;
+ }
+ if(!this.pageStepper || this._maxItemSize <= 0){
+ dojo.style(this.pageStepperTd, "display", "none");
+ return;
+ }else{
+ dojo.style(this.pageStepperTd, "display", "");
+ }
+ if(this.pageStepperDiv.childNodes.length < 1){
+ this._createPageStepNodes();
+ this._createWardBtns();
+ }else{
+ this._resetPageStepNodes();
+ }
+ this._updatePageStepNodeClass();
+
+ this._moveToNextActivableNode(this._getAllPageStepNodes(), this.pageStepValue);
+ this.pageStepValue = null;
+ },
+
+ _createPageStepNodes: function(){
+ // summary:
+ // Create the page step nodes if they do not exist
+ var startPage = this._getStartPage(),
+ stepSize = this._getStepPageSize(),
+ label = "",
+ node = null;
+ for(var i = startPage; i < this.maxPageStep + 1; i++){
+ label = dojo.string.substitute(this.plugin.nls.pageStepLabelTemplate, [i + ""]);
+ node = dojo.create("div", {innerHTML: i, value: i, title: label, tabindex: i < startPage + stepSize ? 0 : -1}, this.pageStepperDiv, "last");
+ dijit.setWaiState(node, "label", label);
+ // connect event
+ this.plugin.connect(node, "onclick", dojo.hitch(this, "_onPageStep"));
+ this.plugin.connect(node, "onmouseover", function(e){
+ dojo.addClass(e.target, "dojoxGridPageTextHover");
+ });
+ this.plugin.connect(node, "onmouseout", function(e){
+ dojo.removeClass(e.target, "dojoxGridPageTextHover");
+ });
+ dojo.style(node, "display", i < startPage + stepSize ? "block" : "none");
+ }
+ if(this.pageStepperWidth){
+ dojo.style(this.pageStepperTd, "width", this.pageStepperWidth);
+ }
+ },
+
+ _createWardBtns: function(){
+ // summary:
+ // Create the previous/next/first/last button
+ var self = this;
+ var highContrastLabel = {prevPage: "&#60;", firstPage: "&#171;", nextPage: "&#62;", lastPage: "&#187;"};
+ var createWardBtn = function(value, label, position){
+ var node = dojo.create("div", {value: value, title: label, tabindex: 1}, self.pageStepperDiv, position);
+ self.plugin.connect(node, "onclick", dojo.hitch(self, "_onPageStep"));
+ dijit.setWaiState(node, "label", label);
+ // for high contrast
+ var highConrastNode = dojo.create("span", {value: value, title: label, innerHTML: highContrastLabel[value]}, node, position);
+ dojo.addClass(highConrastNode, "dojoxGridWardButtonInner");
+ };
+ createWardBtn("prevPage", this.plugin.nls.prevTip, "first");
+ createWardBtn("firstPage", this.plugin.nls.firstTip, "first");
+ createWardBtn("nextPage", this.plugin.nls.nextTip, "last");
+ createWardBtn("lastPage", this.plugin.nls.lastTip, "last");
+ },
+
+ _resetPageStepNodes: function(){
+ // summary:
+ // The page step nodes might be changed when fetch data, we need to
+ // update/reset them
+ var startPage = this._getStartPage(),
+ stepSize = this._getStepPageSize(),
+ stepNodes = this.pageStepperDiv.childNodes,
+ node = null;
+ for(var i = startPage, j = 2; j < stepNodes.length - 2; j++, i++){
+ node = stepNodes[j];
+ if(i < startPage + stepSize){
+ dojo.attr(node, "innerHTML", i);
+ dojo.attr(node, "value", i);
+ dojo.style(node, "display", "block");
+ dijit.setWaiState(node, "label", dojo.string.substitute(this.plugin.nls.pageStepLabelTemplate, [i + ""]));
+ }else{
+ dojo.style(node, "display", "none");
+ }
+ }
+ },
+
+ _updatePageStepNodeClass: function(){
+ // summary:
+ // Update the style of the page step nodes
+ var value = null,
+ curPage = this._getCurrentPageNo(),
+ pageCount = this._getPageCount(),
+ visibleNodeLen = 0;
+
+ var updateClass = function(node, isWardBtn, status){
+ var value = node.value,
+ enableClass = isWardBtn ? "dojoxGrid" + value + "Btn" : "dojoxGridInactived",
+ disableClass = isWardBtn ? "dojoxGrid" + value + "BtnDisable" : "dojoxGridActived";
+ if(status){
+ dojo.addClass(node, disableClass);
+ dojo.attr(node, "tabindex", "-1");
+ }else{
+ dojo.addClass(node, enableClass);
+ dojo.attr(node, "tabindex", "0");
+ }
+ };
+ dojo.forEach(this.pageStepperDiv.childNodes, function(node){
+ dojo.removeClass(node);
+ if(isNaN(parseInt(node.value, 10))){
+ dojo.addClass(node, "dojoxGridWardButton");
+ var disablePageNum = node.value == "prevPage" || node.value == "firstPage" ? 1 : pageCount;
+ updateClass(node, true, (curPage == disablePageNum));
+ }else{
+ value = parseInt(node.value, 10);
+ updateClass(node, false, (value === curPage || dojo.style(node, "display") === "none"));
+ }
+ }, this);
+ },
+
+ _showGotoButton: function(flag){
+ this.gotoButton = flag;
+ this._updateGotoButton();
+ },
+
+ _updateGotoButton: function(){
+ // summary:
+ // Create/destroy the goto page button
+ if(!this.gotoButton){
+ if(this.gotoPageTd){
+ if(this._gotoPageDialog){
+ this._gotoPageDialog.destroy();
+ }
+ dojo.destroy(this.gotoPageDiv);
+ dojo.destroy(this.gotoPageTd);
+ delete this.gotoPageDiv;
+ delete this.gotoPageTd;
+ }
+ return;
+ }
+ if(!this.gotoPageTd){
+ this._createGotoNode();
+ }
+ dojo.toggleClass(this.gotoPageDiv, "dojoxGridPaginatorGotoDivDisabled", this.plugin.pageSize >= this.plugin._maxSize);
+ },
+
+ _createGotoNode: function(){
+ // summary:
+ // Create the goto page button
+ this.gotoPageTd = dojo.create("td", {}, dojo.query("tr", this.domNode)[0], "last");
+ dojo.addClass(this.gotoPageTd, "dojoxGridPaginatorGotoTd");
+ this.gotoPageDiv = dojo.create("div", {tabindex: "0", title: this.plugin.nls.gotoButtonTitle}, this.gotoPageTd, "first");
+ dojo.addClass(this.gotoPageDiv, "dojoxGridPaginatorGotoDiv");
+ this.plugin.connect(this.gotoPageDiv, "onclick", dojo.hitch(this, "_openGotopageDialog"));
+ // for high contrast
+ var highConrastNode = dojo.create("span", {title: this.plugin.nls.gotoButtonTitle, innerHTML: "&#8869;"}, this.gotoPageDiv, "last");
+ dojo.addClass(highConrastNode, "dojoxGridWardButtonInner");
+ },
+
+ _openGotopageDialog: function(event){
+ // summary:
+ // Show the goto page dialog
+ if(!this._gotoPageDialog){
+ this._gotoPageDialog = new dojox.grid.enhanced.plugins.pagination._GotoPageDialog(this.plugin);
+ }
+ // focus
+ if(!this._currentFocusNode){
+ this.grid.focus.focusArea("pagination" + this.position, event);
+ }else{
+ this._currentFocusNode = this.gotoPageDiv;
+ }
+ if(this.focusArea != "pageStep"){
+ this.focusArea = "pageStep";
+ }
+ this._gotoPageDialog.updatePageCount();
+ this._gotoPageDialog.showDialog();
+ },
+
+ // ===== focus handlers ===== //
+ _onFocusPaginator: function(event, step){
+ // summary:
+ // Focus handler
+ if(!this._currentFocusNode){
+ if(step > 0){
+ return this._onFocusPageSizeNode(event) ? true : this._onFocusPageStepNode(event);
+ }else if(step < 0){
+ return this._onFocusPageStepNode(event) ? true : this._onFocusPageSizeNode(event);
+ }else{
+ return false;
+ }
+ }else{
+ if(step > 0){
+ return this.focusArea === "pageSize" ? this._onFocusPageStepNode(event) : false;
+ }else if(step < 0){
+ return this.focusArea === "pageStep" ? this._onFocusPageSizeNode(event) : false;
+ }else{
+ return false;
+ }
+ }
+ },
+
+ _onFocusPageSizeNode: function(event){
+ // summary:
+ // Focus the page size area, if there is no focusable node, return false
+ var pageSizeNodes = this._getPageSizeActivableNodes();
+ if(event && event.type !== "click"){
+ if(pageSizeNodes[0]){
+ dijit.focus(pageSizeNodes[0]);
+ this._currentFocusNode = pageSizeNodes[0];
+ this.focusArea = "pageSize";
+ this.plugin._stopEvent(event);
+ return true;
+ }else{
+ return false;
+ }
+ }
+ if(event && event.type == "click"){
+ if(dojo.indexOf(this._getPageSizeActivableNodes(), event.target) > -1){
+ this.focusArea = "pageSize";
+ this.plugin._stopEvent(event);
+ return true;
+ }
+ }
+ return false;
+ },
+
+ _onFocusPageStepNode: function(event){
+ // summary:
+ // Focus the page step area, if there is no focusable node, return false
+ var pageStepNodes = this._getPageStepActivableNodes();
+ if(event && event.type !== "click"){
+ if(pageStepNodes[0]){
+ dijit.focus(pageStepNodes[0]);
+ this._currentFocusNode = pageStepNodes[0];
+ this.focusArea = "pageStep";
+ this.plugin._stopEvent(event);
+ return true;
+ }else if(this.gotoPageDiv){
+ dijit.focus(this.gotoPageDiv);
+ this._currentFocusNode = this.gotoPageDiv;
+ this.focusArea = "pageStep";
+ this.plugin._stopEvent(event);
+ return true;
+ }else{
+ return false;
+ }
+ }
+ if(event && event.type == "click"){
+ if(dojo.indexOf(this._getPageStepActivableNodes(), event.target) > -1){
+ this.focusArea = "pageStep";
+ this.plugin._stopEvent(event);
+ return true;
+ }else if(event.target == this.gotoPageDiv){
+ dijit.focus(this.gotoPageDiv);
+ this._currentFocusNode = this.gotoPageDiv;
+ this.focusArea = "pageStep";
+ this.plugin._stopEvent(event);
+ return true;
+ }
+ }
+ return false;
+ },
+
+ _onFocusGotoPageNode: function(event){
+ // summary:
+ // Focus the goto page button, if there is no focusable node, return false
+ if(!this.gotoButton || !this.gotoPageTd){
+ return false;
+ }
+ if(event && event.type !== "click" || (event.type == "click" && event.target == this.gotoPageDiv)){
+ dijit.focus(this.gotoPageDiv);
+ this._currentFocusNode = this.gotoPageDiv;
+ this.focusArea = "gotoButton";
+ this.plugin._stopEvent(event);
+ return true;
+ }
+ return true;
+ },
+
+ _onBlurPaginator: function(event, step){
+ var pageSizeNodes = this._getPageSizeActivableNodes(),
+ pageStepNodes = this._getPageStepActivableNodes();
+
+ if(step > 0 && this.focusArea === "pageSize" && (pageStepNodes.length > 1 || this.gotoButton)){
+ return false;
+ }else if(step < 0 && this.focusArea === "pageStep" && pageSizeNodes.length > 1){
+ return false;
+ }
+ this._currentFocusNode = null;
+ this.focusArea = null;
+ return true;
+ },
+
+ _onKeyDown: function(event, isBubble){
+ // summary:
+ // Focus navigation
+ if(isBubble){
+ return;
+ }
+ if(event.altKey || event.metaKey){
+ return;
+ }
+ var dk = dojo.keys;
+ if(event.keyCode === dk.ENTER || event.keyCode === dk.SPACE){
+ if(dojo.indexOf(this._getPageStepActivableNodes(), this._currentFocusNode) > -1){
+ this._onPageStep(event);
+ }else if(dojo.indexOf(this._getPageSizeActivableNodes(), this._currentFocusNode) > -1){
+ this._onSwitchPageSize(event);
+ }else if(this._currentFocusNode === this.gotoPageDiv){
+ this._openGotopageDialog(event);
+ }
+ }
+ this.plugin._stopEvent(event);
+ },
+
+ _moveFocus: function(rowDelta, colDelta, evt){
+ // summary:
+ // Move focus according row delta&column delta
+ var nodes;
+ if(this.focusArea == "pageSize"){
+ nodes = this._getPageSizeActivableNodes();
+ }else if(this.focusArea == "pageStep"){
+ nodes = this._getPageStepActivableNodes();
+ if(this.gotoPageDiv){
+ nodes.push(this.gotoPageDiv);
+ }
+ }
+ if(nodes.length < 1){
+ return;
+ }
+ var currentIdx = dojo.indexOf(nodes, this._currentFocusNode);
+ var focusIdx = currentIdx + colDelta;
+ if(focusIdx >= 0 && focusIdx < nodes.length){
+ dijit.focus(nodes[focusIdx]);
+ this._currentFocusNode = nodes[focusIdx];
+ }
+ this.plugin._stopEvent(evt);
+ },
+
+ _getPageSizeActivableNodes: function(){
+ return dojo.query("span[tabindex='0']", this.sizeSwitchTd);
+ },
+
+ _getPageStepActivableNodes: function(){
+ return (dojo.query("div[tabindex='0']", this.pageStepperDiv));
+ },
+
+ _getAllPageSizeNodes: function(){
+ var nodeList = [];
+ dojo.forEach(this.sizeSwitchTd.childNodes, function(node){
+ if(node.value){
+ nodeList.push(node);
+ }
+ });
+ return nodeList;
+ },
+
+ _getAllPageStepNodes: function(){
+ var nodeList = [];
+ for(var i = 0, len = this.pageStepperDiv.childNodes.length; i < len; i++){
+ nodeList.push(this.pageStepperDiv.childNodes[i]);
+ }
+ return nodeList;
+ },
+
+ _moveToNextActivableNode: function(nodeList, curNodeValue){
+ // summary:
+ // Need to move the focus to next node since current node is inactive and unfocusable
+ if(!curNodeValue){
+ return;
+ }
+ if(nodeList.length < 2){
+ this.grid.focus.tab(1);
+ }
+ var nl = [],
+ node = null,
+ index = 0;
+ dojo.forEach(nodeList, function(n){
+ if(n.value == curNodeValue){
+ nl.push(n);
+ node = n;
+ }else if(dojo.attr(n, "tabindex") == "0"){
+ nl.push(n);
+ }
+ });
+ if(nl.length < 2){
+ this.grid.focus.tab(1);
+ }
+ index = dojo.indexOf(nl, node);
+ if(dojo.attr(node, "tabindex") != "0"){
+ node = nl[index + 1] ? nl[index + 1] : nl[index - 1];
+ }
+ dijit.focus(node);
+ this._currentFocusNode = node;
+ },
+
+ // ===== pagination events handlers ===== //
+ _onSwitchPageSize: function(/*Event*/e){
+ // summary:
+ // The handler of switch the page size
+ var size = this.pageSizeValue = e.target.value;
+ if(!size){
+ return;
+ }
+ if(dojo.trim(size.toLowerCase()) == "all"){
+ size = this._maxItemSize;
+ }
+ this.plugin.showAll = parseInt(size, 10) >= this._maxItemSize ? true : false;
+ this.plugin.grid.usingPagination = !this.plugin.showAll;
+
+ size = parseInt(size, 10);
+ if(isNaN(size) || size <= 0/* || size == this.currentPageSize*/){
+ return;
+ }
+
+ if(!this._currentFocusNode){
+ this.grid.focus.currentArea("pagination" + this.position);
+ }
+ if(this.focusArea != "pageSize"){
+ this.focusArea = "pageSize";
+ }
+ this.plugin.changePageSize(size);
+ },
+
+ _onPageStep: function(/*Event*/e){
+ // summary:
+ // The handler jump page event
+ var p = this.plugin,
+ value = this.pageStepValue = e.target.value;
+
+ if(!this._currentFocusNode){
+ this.grid.focus.currentArea("pagination" + this.position);
+ }
+ if(this.focusArea != "pageStep"){
+ this.focusArea = "pageStep";
+ }
+ if(!isNaN(parseInt(value, 10))){
+ p.gotoPage(value);
+ }else{
+ switch(e.target.value){
+ case "prevPage":
+ p.prevPage();
+ break;
+ case "nextPage":
+ p.nextPage();
+ break;
+ case "firstPage":
+ p.gotoFirstPage();
+ break;
+ case "lastPage":
+ p.gotoLastPage();
+ }
+ }
+ },
+
+ // ===== information getters ===== //
+ _getCurrentPageNo: function(){
+ return this.plugin._currentPage + 1;
+ },
+
+ _getPageCount: function(){
+ if(!this._maxItemSize || !this.currentPageSize){
+ return 0;
+ }
+ return Math.ceil(this._maxItemSize / this.currentPageSize);
+ },
+
+ _getStartPage: function(){
+ var cp = this._getCurrentPageNo();
+ var ms = parseInt(this.maxPageStep / 2, 10);
+ var pc = this._getPageCount();
+ if(cp < ms || (cp - ms) < 1){
+ return 1;
+ }else if(pc <= this.maxPageStep){
+ return 1;
+ }else{
+ if(pc - cp < ms && cp - this.maxPageStep >= 0){
+ return pc - this.maxPageStep + 1;
+ }else{
+ return (cp - ms);
+ }
+ }
+ },
+
+ _getStepPageSize: function(){
+ var sp = this._getStartPage();
+ var count = this._getPageCount();
+ if((sp + this.maxPageStep) > count){
+ return count - sp + 1;
+ }else{
+ return this.maxPageStep;
+ }
+ }
+
+});
+
+dojo.declare("dojox.grid.enhanced.plugins.pagination._GotoPageDialog", null, {
+
+ pageCount: 0,
+
+ constructor: function(plugin){
+ this.plugin = plugin;
+ this.pageCount = this.plugin.paginators[0]._getPageCount();
+ this._dialogNode = dojo.create("div", {}, dojo.body(), "last");
+ this._gotoPageDialog = new dojox.grid.enhanced.plugins.Dialog({
+ "refNode": plugin.grid.domNode,
+ "title": this.plugin.nls.dialogTitle
+ }, this._dialogNode);
+ this._createDialogContent();
+ this._gotoPageDialog.startup();
+ },
+
+ _createDialogContent: function(){
+ // summary:
+ // Create the dialog content
+ this._specifyNode = dojo.create("div", {innerHTML: this.plugin.nls.dialogIndication}, this._gotoPageDialog.containerNode, "last");
+
+ this._pageInputDiv = dojo.create("div", {}, this._gotoPageDialog.containerNode, "last");
+ this._pageTextBox = new dijit.form.NumberTextBox();
+ this._pageTextBox.constraints = {fractional:false, min:1, max:this.pageCount};
+ this.plugin.connect(this._pageTextBox.textbox, "onkeyup", dojo.hitch(this, "_setConfirmBtnState"));
+
+ this._pageInputDiv.appendChild(this._pageTextBox.domNode);
+ this._pageLabel = dojo.create("label", {innerHTML: dojo.string.substitute(this.plugin.nls.pageCountIndication, [this.pageCount])}, this._pageInputDiv, "last");
+
+ this._buttonDiv = dojo.create("div", {}, this._gotoPageDialog.containerNode, "last");
+ this._confirmBtn = new dijit.form.Button({label: this.plugin.nls.dialogConfirm, onClick: dojo.hitch(this, this._onConfirm)});
+ this._confirmBtn.set("disabled", true);
+
+ this._cancelBtn = new dijit.form.Button({label: this.plugin.nls.dialogCancel, onClick: dojo.hitch(this, this._onCancel)});
+ this._buttonDiv.appendChild(this._confirmBtn.domNode);
+ this._buttonDiv.appendChild(this._cancelBtn.domNode);
+ this._styleContent();
+ this._gotoPageDialog.onCancel = dojo.hitch(this, this._onCancel);
+ this.plugin.connect(this._gotoPageDialog, "_onKey", dojo.hitch(this, "_onKeyDown"));
+ },
+
+ _styleContent: function(){
+ dojo.addClass(this._specifyNode, "dojoxGridDialogMargin");
+ dojo.addClass(this._pageInputDiv, "dojoxGridDialogMargin");
+ dojo.addClass(this._buttonDiv, "dojoxGridDialogButton");
+ dojo.style(this._pageTextBox.domNode, "width", "50px");
+ },
+
+ updatePageCount: function(){
+ this.pageCount = this.plugin.paginators[0]._getPageCount();
+ this._pageTextBox.constraints = {fractional:false, min:1, max:this.pageCount};
+ dojo.attr(this._pageLabel, "innerHTML", dojo.string.substitute(this.plugin.nls.pageCountIndication, [this.pageCount]));
+ },
+
+ showDialog: function(){
+ this._gotoPageDialog.show();
+ },
+
+ _onConfirm: function(event){
+ // summary:
+ // Jump to the given page
+ if(this._pageTextBox.isValid() && this._pageTextBox.getDisplayedValue() !== ""){
+ this.plugin.gotoPage(this._pageTextBox.getDisplayedValue());
+ this._gotoPageDialog.hide();
+ this._pageTextBox.reset();
+ }
+ this.plugin._stopEvent(event);
+ },
+
+ _onCancel: function(event){
+ // summary:
+ // Cancel action and hide the dialog
+ this._pageTextBox.reset();
+ this._gotoPageDialog.hide();
+ this.plugin._stopEvent(event);
+ },
+
+ _onKeyDown: function(event){
+ if(event.altKey || event.metaKey){
+ return;
+ }
+ var dk = dojo.keys;
+ if(event.keyCode === dk.ENTER){
+ this._onConfirm(event);
+ }
+ },
+
+ _setConfirmBtnState: function(){
+ if(this._pageTextBox.isValid() && this._pageTextBox.getDisplayedValue() !== ""){
+ this._confirmBtn.set("disabled", false);
+ }else{
+ this._confirmBtn.set("disabled", true);
+ }
+ },
+
+ destroy: function(){
+ this._pageTextBox.destroy();
+ this._confirmBtn.destroy();
+ this._cancelBtn.destroy();
+ this._gotoPageDialog.destroy();
+
+ dojo.destroy(this._specifyNode);
+ dojo.destroy(this._pageInputDiv);
+ dojo.destroy(this._pageLabel);
+ dojo.destroy(this._buttonDiv);
+ dojo.destroy(this._dialogNode);
+ }
+});
+
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Pagination/*name:'pagination'*/);
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Printer.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Printer.js
new file mode 100644
index 0000000..a8b55cc
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Printer.js
@@ -0,0 +1,269 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.Printer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Printer"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Printer");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid.enhanced.plugins.exporter.TableWriter");
+
+dojo.declare("dojox.grid.enhanced.plugins.Printer", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provide printGrid function to the grid.
+ // example:
+ // | dojo.require("dojox.grid.enhanced.plugins.Printer");
+ // | dijit.byId("grid1").printGrid("my grid", //A title for the grid,optional
+ // | ["cssfile1.css","cssfile2.css"],//An array of css files to decorate the printed gird,optional
+ // | {table:"border='border'"} //tagName:"attrbuteList" pairs, optional,
+ // | //control the html tags in the generated html
+ // | );
+
+ // __printArgs: {
+ // title: String
+ // A title of the printed page can be specified. Optional.
+ // If given, it's shown in an <h1> tag at the top of the page.
+ // cssFiles: Array | String
+ // CSS file paths. Optional.
+ // Every row and column is given CSS classes, including:
+ // grid_row_{row-number}, grid_odd_row, grid_even_row, grid_header,
+ // grid_col_{col-number}, grid_odd_col, grid_even_col
+ // {row_number} and {col-number} are both integers starting from 1.
+ // Row classes are for <thead> and <tbody> tags.
+ // Column classes are for <th> and <td> tags.
+ // Users can use these classes in the CSS files, but cannot define their own.
+ // writerArgs: Object (Association Array)
+ // Arguments for TableWriter.
+ // fetchArgs: object?
+ // Any arguments for store.fetch
+ // }
+
+ // name: String
+ // Plugin name
+ name: "printer",
+
+ constructor: function(grid){
+ // summary:
+ // only newed by _Plugin
+ // inGrid: EnhancedGrid
+ // The grid to plug in to.
+ this.grid = grid;
+ this._mixinGrid(grid);
+
+ //For print, we usually need the HTML instead of raw data.
+ grid.setExportFormatter(function(data, cell, rowIndex, rowItem){
+ return cell.format(rowIndex, rowItem);
+ });
+ },
+ _mixinGrid: function(){
+ var g = this.grid;
+ g.printGrid = dojo.hitch(this, this.printGrid);
+ g.printSelected = dojo.hitch(this, this.printSelected);
+ g.exportToHTML = dojo.hitch(this, this.exportToHTML);
+ g.exportSelectedToHTML = dojo.hitch(this, this.exportSelectedToHTML);
+ g.normalizePrintedGrid = dojo.hitch(this, this.normalizeRowHeight);
+ },
+ printGrid: function(args){
+ // summary:
+ // Print all the data in the grid, using title as a title,
+ // decorating generated html by cssFiles,
+ // using tagName:"attrbuteList" pairs(writerArgs) to control html tags
+ // in the generated html string.
+ // tags:
+ // public
+ // args: __printArgs?
+ // Arguments for print.
+ this.exportToHTML(args, dojo.hitch(this, this._print));
+ },
+ printSelected: function(args){
+ // summary:
+ // Print selected data. All other features are the same as printGrid.
+ // For meaning of arguments see function *printGrid*
+ // tags:
+ // public
+ // args: __printArgs?
+ // Arguments for print.
+ this._print(this.exportSelectedToHTML(args));
+ },
+ exportToHTML: function(args, onExported){
+ // summary:
+ // Export to HTML string, but do NOT print.
+ // Users can use this to implement print preview.
+ // For meaning of the 1st-3rd arguments see function *printGrid*.
+ // tags:
+ // public
+ // args: __printArgs?
+ // Arguments for print.
+ // onExported: function(string)
+ // call back function
+ args = this._formalizeArgs(args);
+ var _this = this;
+ this.grid.exportGrid("table", args, function(str){
+ onExported(_this._wrapHTML(args.title, args.cssFiles, args.titleInBody + str));
+ });
+ },
+ exportSelectedToHTML: function(args){
+ // summary:
+ // Export selected rows to HTML string, but do NOT print.
+ // Users can use this to implement print preview.
+ // For meaning of arguments see function *printGrid*
+ // tags:
+ // public
+ // args: __printArgs?
+ // Arguments for print.
+ args = this._formalizeArgs(args);
+ var str = this.grid.exportSelected("table", args.writerArgs);
+ return this._wrapHTML(args.title, args.cssFiles, args.titleInBody + str); //String
+ },
+ _print: function(/* string */htmlStr){
+ // summary:
+ // Do the print job.
+ // tags:
+ // private
+ // htmlStr: String
+ // The html content string to be printed.
+ // returns:
+ // undefined
+ var win, _this = this,
+ fillDoc = function(w){
+ var doc = win.document;
+ doc.open();
+ doc.write(htmlStr);
+ doc.close();
+ _this.normalizeRowHeight(doc);
+ };
+ if(!window.print){
+ //We don't have a print facility.
+ return;
+ }else if(dojo.isChrome || dojo.isOpera){
+ //referred from dijit._editor.plugins.Print._print()
+ //In opera and chrome the iframe.contentWindow.print
+ //will also print the outside window. So we must create a
+ //stand-alone new window.
+ win = window.open("javascript: ''", "", "status=0,menubar=0,location=0,toolbar=0,width=1,height=1,resizable=0,scrollbars=0");
+ fillDoc(win);
+ //Opera will stop at this point, showing the popping-out window.
+ //If the user closes the window, the following codes will not execute.
+ //If the user returns focus to the main window, the print function
+ // is executed, but still a no-op.
+ win.print();
+ win.close();
+ }else{
+ //Put private things in deeper namespace to avoid poluting grid namespace.
+ var fn = this._printFrame,
+ dn = this.grid.domNode;
+ if(!fn){
+ var frameId = dn.id + "_print_frame";
+ if(!(fn = dojo.byId(frameId))){
+ //create an iframe to store the grid data.
+ fn = dojo.create("iframe");
+ fn.id = frameId;
+ fn.frameBorder = 0;
+ dojo.style(fn, {
+ width: "1px",
+ height: "1px",
+ position: "absolute",
+ right: 0,
+ bottoom: 0,
+ border: "none",
+ overflow: "hidden"
+ });
+ if(!dojo.isIE){
+ dojo.style(fn, "visibility","hidden");
+ }
+ dn.appendChild(fn);
+ }
+ //Reuse this iframe
+ this._printFrame = fn;
+ }
+ win = fn.contentWindow;
+ fillDoc(win);
+ // IE requires the frame to be focused for
+ // print to work, but since this is okay for all
+ // no special casing.
+ dijit.focus(fn);
+ win.print();
+ }
+ },
+ _wrapHTML: function(/* string */title, /* Array */cssFiles, /* string */body_content){
+ // summary:
+ // Put title, cssFiles, and body_content together into an HTML string.
+ // tags:
+ // private
+ // title: String
+ // A title for the html page.
+ // cssFiles: Array
+ // css file pathes.
+ // body_content: String
+ // Content to print, not including <head></head> part and <html> tags
+ // returns:
+ // the wrapped HTML string ready for print
+ var html = ['<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
+ '<html><head><title>', title,
+ '</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>'];
+ for(var i = 0; i < cssFiles.length; ++i){
+ html.push('<link rel="stylesheet" type="text/css" href="' + cssFiles[i] + '" />');
+ }
+ html.push('</head>');
+ if(body_content.search(/^\s*<body/i) < 0){
+ body_content = '<body>' + body_content + '</body>';
+ }
+ html.push(body_content);
+ return html.join('\n'); //String
+ },
+ normalizeRowHeight: function(doc){
+ var views = dojo.query("table.grid_view", doc.body);
+ var headPerView = dojo.map(views, function(view){
+ return dojo.query("thead.grid_header", view)[0];
+ });
+ var rowsPerView = dojo.map(views, function(view){
+ return dojo.query("tbody.grid_row", view);
+ });
+ var rowCount = rowsPerView[0].length;
+ var i, v, h, maxHeight = 0;
+ for(v = views.length - 1; v >= 0; --v){
+ h = dojo.contentBox(headPerView[v]).h;
+ if(h > maxHeight){
+ maxHeight = h;
+ }
+ }
+ for(v = views.length - 1; v >= 0; --v){
+ dojo.style(headPerView[v], "height", maxHeight + "px");
+ }
+ for(i = 0; i < rowCount; ++i){
+ maxHeight = 0;
+ for(v = views.length - 1; v >= 0; --v){
+ h = dojo.contentBox(rowsPerView[v][i]).h;
+ if(h > maxHeight){
+ maxHeight = h;
+ }
+ }
+ for(v = views.length - 1; v >= 0; --v){
+ dojo.style(rowsPerView[v][i], "height", maxHeight + "px");
+ }
+ }
+ var left = 0;
+ for(v = 0; v < views.length; ++v){
+ dojo.style(views[v], "left", left + "px");
+ left += dojo.marginBox(views[v]).w;
+ }
+ },
+ _formalizeArgs: function(args){
+ args = (args && dojo.isObject(args)) ? args : {};
+ args.title = String(args.title) || "";
+ if(!dojo.isArray(args.cssFiles)){
+ args.cssFiles = [args.cssFiles];
+ }
+ args.titleInBody = args.title ? ['<h1>', args.title, '</h1>'].join('') : '';
+ return args; //Object
+ }
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Printer/*name:'printer'*/, {
+ "dependency": ["exporter"]
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Printer.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Printer.xd.js
new file mode 100644
index 0000000..a2b4bd3
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Printer.xd.js
@@ -0,0 +1,275 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.Printer"],
+["require", "dojox.grid.enhanced._Plugin"],
+["require", "dojox.grid.enhanced.plugins.exporter.TableWriter"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.Printer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Printer"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Printer");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid.enhanced.plugins.exporter.TableWriter");
+
+dojo.declare("dojox.grid.enhanced.plugins.Printer", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provide printGrid function to the grid.
+ // example:
+ // | dojo.require("dojox.grid.enhanced.plugins.Printer");
+ // | dijit.byId("grid1").printGrid("my grid", //A title for the grid,optional
+ // | ["cssfile1.css","cssfile2.css"],//An array of css files to decorate the printed gird,optional
+ // | {table:"border='border'"} //tagName:"attrbuteList" pairs, optional,
+ // | //control the html tags in the generated html
+ // | );
+
+ // __printArgs: {
+ // title: String
+ // A title of the printed page can be specified. Optional.
+ // If given, it's shown in an <h1> tag at the top of the page.
+ // cssFiles: Array | String
+ // CSS file paths. Optional.
+ // Every row and column is given CSS classes, including:
+ // grid_row_{row-number}, grid_odd_row, grid_even_row, grid_header,
+ // grid_col_{col-number}, grid_odd_col, grid_even_col
+ // {row_number} and {col-number} are both integers starting from 1.
+ // Row classes are for <thead> and <tbody> tags.
+ // Column classes are for <th> and <td> tags.
+ // Users can use these classes in the CSS files, but cannot define their own.
+ // writerArgs: Object (Association Array)
+ // Arguments for TableWriter.
+ // fetchArgs: object?
+ // Any arguments for store.fetch
+ // }
+
+ // name: String
+ // Plugin name
+ name: "printer",
+
+ constructor: function(grid){
+ // summary:
+ // only newed by _Plugin
+ // inGrid: EnhancedGrid
+ // The grid to plug in to.
+ this.grid = grid;
+ this._mixinGrid(grid);
+
+ //For print, we usually need the HTML instead of raw data.
+ grid.setExportFormatter(function(data, cell, rowIndex, rowItem){
+ return cell.format(rowIndex, rowItem);
+ });
+ },
+ _mixinGrid: function(){
+ var g = this.grid;
+ g.printGrid = dojo.hitch(this, this.printGrid);
+ g.printSelected = dojo.hitch(this, this.printSelected);
+ g.exportToHTML = dojo.hitch(this, this.exportToHTML);
+ g.exportSelectedToHTML = dojo.hitch(this, this.exportSelectedToHTML);
+ g.normalizePrintedGrid = dojo.hitch(this, this.normalizeRowHeight);
+ },
+ printGrid: function(args){
+ // summary:
+ // Print all the data in the grid, using title as a title,
+ // decorating generated html by cssFiles,
+ // using tagName:"attrbuteList" pairs(writerArgs) to control html tags
+ // in the generated html string.
+ // tags:
+ // public
+ // args: __printArgs?
+ // Arguments for print.
+ this.exportToHTML(args, dojo.hitch(this, this._print));
+ },
+ printSelected: function(args){
+ // summary:
+ // Print selected data. All other features are the same as printGrid.
+ // For meaning of arguments see function *printGrid*
+ // tags:
+ // public
+ // args: __printArgs?
+ // Arguments for print.
+ this._print(this.exportSelectedToHTML(args));
+ },
+ exportToHTML: function(args, onExported){
+ // summary:
+ // Export to HTML string, but do NOT print.
+ // Users can use this to implement print preview.
+ // For meaning of the 1st-3rd arguments see function *printGrid*.
+ // tags:
+ // public
+ // args: __printArgs?
+ // Arguments for print.
+ // onExported: function(string)
+ // call back function
+ args = this._formalizeArgs(args);
+ var _this = this;
+ this.grid.exportGrid("table", args, function(str){
+ onExported(_this._wrapHTML(args.title, args.cssFiles, args.titleInBody + str));
+ });
+ },
+ exportSelectedToHTML: function(args){
+ // summary:
+ // Export selected rows to HTML string, but do NOT print.
+ // Users can use this to implement print preview.
+ // For meaning of arguments see function *printGrid*
+ // tags:
+ // public
+ // args: __printArgs?
+ // Arguments for print.
+ args = this._formalizeArgs(args);
+ var str = this.grid.exportSelected("table", args.writerArgs);
+ return this._wrapHTML(args.title, args.cssFiles, args.titleInBody + str); //String
+ },
+ _print: function(/* string */htmlStr){
+ // summary:
+ // Do the print job.
+ // tags:
+ // private
+ // htmlStr: String
+ // The html content string to be printed.
+ // returns:
+ // undefined
+ var win, _this = this,
+ fillDoc = function(w){
+ var doc = win.document;
+ doc.open();
+ doc.write(htmlStr);
+ doc.close();
+ _this.normalizeRowHeight(doc);
+ };
+ if(!window.print){
+ //We don't have a print facility.
+ return;
+ }else if(dojo.isChrome || dojo.isOpera){
+ //referred from dijit._editor.plugins.Print._print()
+ //In opera and chrome the iframe.contentWindow.print
+ //will also print the outside window. So we must create a
+ //stand-alone new window.
+ win = window.open("javascript: ''", "", "status=0,menubar=0,location=0,toolbar=0,width=1,height=1,resizable=0,scrollbars=0");
+ fillDoc(win);
+ //Opera will stop at this point, showing the popping-out window.
+ //If the user closes the window, the following codes will not execute.
+ //If the user returns focus to the main window, the print function
+ // is executed, but still a no-op.
+ win.print();
+ win.close();
+ }else{
+ //Put private things in deeper namespace to avoid poluting grid namespace.
+ var fn = this._printFrame,
+ dn = this.grid.domNode;
+ if(!fn){
+ var frameId = dn.id + "_print_frame";
+ if(!(fn = dojo.byId(frameId))){
+ //create an iframe to store the grid data.
+ fn = dojo.create("iframe");
+ fn.id = frameId;
+ fn.frameBorder = 0;
+ dojo.style(fn, {
+ width: "1px",
+ height: "1px",
+ position: "absolute",
+ right: 0,
+ bottoom: 0,
+ border: "none",
+ overflow: "hidden"
+ });
+ if(!dojo.isIE){
+ dojo.style(fn, "visibility","hidden");
+ }
+ dn.appendChild(fn);
+ }
+ //Reuse this iframe
+ this._printFrame = fn;
+ }
+ win = fn.contentWindow;
+ fillDoc(win);
+ // IE requires the frame to be focused for
+ // print to work, but since this is okay for all
+ // no special casing.
+ dijit.focus(fn);
+ win.print();
+ }
+ },
+ _wrapHTML: function(/* string */title, /* Array */cssFiles, /* string */body_content){
+ // summary:
+ // Put title, cssFiles, and body_content together into an HTML string.
+ // tags:
+ // private
+ // title: String
+ // A title for the html page.
+ // cssFiles: Array
+ // css file pathes.
+ // body_content: String
+ // Content to print, not including <head></head> part and <html> tags
+ // returns:
+ // the wrapped HTML string ready for print
+ var html = ['<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
+ '<html><head><title>', title,
+ '</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>'];
+ for(var i = 0; i < cssFiles.length; ++i){
+ html.push('<link rel="stylesheet" type="text/css" href="' + cssFiles[i] + '" />');
+ }
+ html.push('</head>');
+ if(body_content.search(/^\s*<body/i) < 0){
+ body_content = '<body>' + body_content + '</body>';
+ }
+ html.push(body_content);
+ return html.join('\n'); //String
+ },
+ normalizeRowHeight: function(doc){
+ var views = dojo.query("table.grid_view", doc.body);
+ var headPerView = dojo.map(views, function(view){
+ return dojo.query("thead.grid_header", view)[0];
+ });
+ var rowsPerView = dojo.map(views, function(view){
+ return dojo.query("tbody.grid_row", view);
+ });
+ var rowCount = rowsPerView[0].length;
+ var i, v, h, maxHeight = 0;
+ for(v = views.length - 1; v >= 0; --v){
+ h = dojo.contentBox(headPerView[v]).h;
+ if(h > maxHeight){
+ maxHeight = h;
+ }
+ }
+ for(v = views.length - 1; v >= 0; --v){
+ dojo.style(headPerView[v], "height", maxHeight + "px");
+ }
+ for(i = 0; i < rowCount; ++i){
+ maxHeight = 0;
+ for(v = views.length - 1; v >= 0; --v){
+ h = dojo.contentBox(rowsPerView[v][i]).h;
+ if(h > maxHeight){
+ maxHeight = h;
+ }
+ }
+ for(v = views.length - 1; v >= 0; --v){
+ dojo.style(rowsPerView[v][i], "height", maxHeight + "px");
+ }
+ }
+ var left = 0;
+ for(v = 0; v < views.length; ++v){
+ dojo.style(views[v], "left", left + "px");
+ left += dojo.marginBox(views[v]).w;
+ }
+ },
+ _formalizeArgs: function(args){
+ args = (args && dojo.isObject(args)) ? args : {};
+ args.title = String(args.title) || "";
+ if(!dojo.isArray(args.cssFiles)){
+ args.cssFiles = [args.cssFiles];
+ }
+ args.titleInBody = args.title ? ['<h1>', args.title, '</h1>'].join('') : '';
+ return args; //Object
+ }
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Printer/*name:'printer'*/, {
+ "dependency": ["exporter"]
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Rearrange.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Rearrange.js
new file mode 100644
index 0000000..1d1584a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Rearrange.js
@@ -0,0 +1,492 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.Rearrange"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Rearrange"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Rearrange");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid.enhanced.plugins._RowMapLayer");
+
+dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provides a set of method to re-arrange the structure of grid.
+
+ // name: String
+ // plugin name
+ name: "rearrange",
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ this.setArgs(args);
+ var rowMapLayer = new dojox.grid.enhanced.plugins._RowMapLayer(grid);
+ dojox.grid.enhanced.plugins.wrap(grid, "_storeLayerFetch", rowMapLayer);
+ },
+ setArgs: function(args){
+ this.args = dojo.mixin(this.args || {}, args || {});
+ this.args.setIdentifierForNewItem = this.args.setIdentifierForNewItem || function(v){return v;};
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ this.grid.unwrap("rowmap");
+ },
+ onSetStore: function(store){
+ this.grid.layer("rowmap").clearMapping();
+ },
+ _hasIdentity: function(points){
+ var g = this.grid, s = g.store, cells = g.layout.cells;
+ if(s.getFeatures()["dojo.data.api.Identity"]){
+ if(dojo.some(points, function(point){
+ return s.getIdentityAttributes(g._by_idx[point.r].item) == cells[point.c].field;
+ })){
+ return true;
+ }
+ }
+ return false;
+ },
+ moveColumns: function(colsToMove, targetPos){
+ // summary:
+ // Move a set of columns to a given position.
+ // tag:
+ // public
+ // colsToMove: Integer[]
+ // Array of column indexes.
+ // targetPos: Integer
+ // The target position
+ var g = this.grid,
+ layout = g.layout,
+ cells = layout.cells,
+ colIndex, i, delta = 0,
+ before = true, tmp = {}, mapping = {};
+ colsToMove.sort(function(a, b){
+ return a - b;
+ });
+ for(i = 0; i < colsToMove.length; ++i){
+ tmp[colsToMove[i]] = i;
+ if(colsToMove[i] < targetPos){
+ ++delta;
+ }
+ }
+ var leftCount = 0;
+ var rightCount = 0;
+ var maxCol = Math.max(colsToMove[colsToMove.length - 1], targetPos);
+ if(maxCol == cells.length){
+ --maxCol;
+ }
+ for(i = colsToMove[0]; i <= maxCol; ++i){
+ var j = tmp[i];
+ if(j >= 0){
+ if(i != targetPos - delta + j){
+ mapping[i] = targetPos - delta + j;
+ }
+ leftCount = j + 1;
+ rightCount = colsToMove.length - j - 1;
+ }else if(i < targetPos && leftCount > 0){
+ mapping[i] = i - leftCount;
+ }else if(i >= targetPos && rightCount > 0){
+ mapping[i] = i + rightCount;
+ }
+ }
+ //console.log("mapping:", mapping, ", colsToMove:", colsToMove,", target:", targetPos);
+ delta = 0;
+ if(targetPos == cells.length){
+ --targetPos;
+ before = false;
+ }
+ g._notRefreshSelection = true;
+ for(i = 0; i < colsToMove.length; ++i){
+ colIndex = colsToMove[i];
+ if(colIndex < targetPos){
+ colIndex -= delta;
+ }
+ ++delta;
+ if(colIndex != targetPos){
+ layout.moveColumn(cells[colIndex].view.idx, cells[targetPos].view.idx, colIndex, targetPos, before);
+ cells = layout.cells;
+ }
+ if(targetPos <= colIndex){
+ ++targetPos;
+ }
+ }
+ delete g._notRefreshSelection;
+ dojo.publish("dojox/grid/rearrange/move/" + g.id, ["col", mapping]);
+ },
+ moveRows: function(rowsToMove, targetPos){
+ // summary:
+ // Move a set of rows to a given position
+ // tag:
+ // public
+ // rowsToMove: Integer[]
+ // Array of row indexes.
+ // targetPos: Integer
+ // The target position
+ var g = this.grid,
+ mapping = {},
+ preRowsToMove = [],
+ postRowsToMove = [],
+ len = rowsToMove.length,
+ i, r, k, arr, rowMap, lastPos;
+
+ for(i = 0; i < len; ++i){
+ r = rowsToMove[i];
+ if(r >= targetPos){
+ break;
+ }
+ preRowsToMove.push(r);
+ }
+ postRowsToMove = rowsToMove.slice(i);
+
+ arr = preRowsToMove;
+ len = arr.length;
+ if(len){
+ rowMap = {};
+ dojo.forEach(arr, function(r){
+ rowMap[r] = true;
+ });
+ mapping[arr[0]] = targetPos - len;
+ for(k = 0, i = arr[k] + 1, lastPos = i - 1; i < targetPos; ++i){
+ if(!rowMap[i]){
+ mapping[i] = lastPos;
+ ++lastPos;
+ }else{
+ ++k;
+ mapping[i] = targetPos - len + k;
+ }
+ }
+ }
+ arr = postRowsToMove;
+ len = arr.length;
+ if(len){
+ rowMap = {};
+ dojo.forEach(arr, function(r){
+ rowMap[r] = true;
+ });
+ mapping[arr[len - 1]] = targetPos + len - 1;
+ for(k = len - 1, i = arr[k] - 1, lastPos = i + 1; i >= targetPos; --i){
+ if(!rowMap[i]){
+ mapping[i] = lastPos;
+ --lastPos;
+ }else{
+ --k;
+ mapping[i] = targetPos + k;
+ }
+ }
+ }
+ var tmpMapping = dojo.clone(mapping);
+ g.layer("rowmap").setMapping(mapping);
+ g.forEachLayer(function(layer){
+ if(layer.name() != "rowmap"){
+ layer.invalidate();
+ return true;
+ }else{
+ return false;
+ }
+ }, false);
+ g.selection.selected = [];
+ g._noInternalMapping = true;
+ g._refresh();
+ setTimeout(function(){
+ dojo.publish("dojox/grid/rearrange/move/" + g.id, ["row", tmpMapping]);
+ g._noInternalMapping = false;
+ }, 0);
+ },
+ moveCells: function(cellsToMove, target){
+ var g = this.grid,
+ s = g.store;
+ if(s.getFeatures()["dojo.data.api.Write"]){
+ if(cellsToMove.min.row == target.min.row && cellsToMove.min.col == target.min.col){
+ //Same position, no need to move
+ return;
+ }
+ var cells = g.layout.cells,
+ cnt = cellsToMove.max.row - cellsToMove.min.row + 1,
+ r, c, tr, tc,
+ sources = [], targets = [];
+ for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){
+ for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){
+ while(cells[c] && cells[c].hidden){
+ ++c;
+ }
+ while(cells[tc] && cells[tc].hidden){
+ ++tc;
+ }
+ sources.push({
+ "r": r,
+ "c": c
+ });
+ targets.push({
+ "r": tr,
+ "c": tc,
+ "v": cells[c].get(r, g._by_idx[r].item)
+ });
+ }
+ }
+ if(this._hasIdentity(sources.concat(targets))){
+ console.warn("Can not write to identity!");
+ return;
+ }
+ dojo.forEach(sources, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, "");
+ });
+ dojo.forEach(targets, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v);
+ });
+ s.save({
+ onComplete: function(){
+ dojo.publish("dojox/grid/rearrange/move/" + g.id, ["cell", {
+ "from": cellsToMove,
+ "to": target
+ }]);
+ }
+ });
+ }
+ },
+ copyCells: function(cellsToMove, target){
+ var g = this.grid,
+ s = g.store;
+ if(s.getFeatures()["dojo.data.api.Write"]){
+ if(cellsToMove.min.row == target.min.row && cellsToMove.min.col == target.min.col){
+ return;
+ }
+ var cells = g.layout.cells,
+ cnt = cellsToMove.max.row - cellsToMove.min.row + 1,
+ r, c, tr, tc,
+ targets = [];
+ for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){
+ for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){
+ while(cells[c] && cells[c].hidden){
+ ++c;
+ }
+ while(cells[tc] && cells[tc].hidden){
+ ++tc;
+ }
+ targets.push({
+ "r": tr,
+ "c": tc,
+ "v": cells[c].get(r, g._by_idx[r].item)
+ });
+ }
+ }
+ if(this._hasIdentity(targets)){
+ console.warn("Can not write to identity!");
+ return;
+ }
+ dojo.forEach(targets, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v);
+ });
+ s.save({
+ onComplete: function(){
+ setTimeout(function(){
+ dojo.publish("dojox/grid/rearrange/copy/" + g.id, ["cell", {
+ "from": cellsToMove,
+ "to": target
+ }]);
+ }, 0);
+ }
+ });
+ }
+ },
+ changeCells: function(sourceGrid, cellsToMove, target){
+ var g = this.grid,
+ s = g.store;
+ if(s.getFeatures()["dojo.data.api.Write"]){
+ var srcg = sourceGrid,
+ cells = g.layout.cells,
+ srccells = srcg.layout.cells,
+ cnt = cellsToMove.max.row - cellsToMove.min.row + 1,
+ r, c, tr, tc, targets = [];
+ for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){
+ for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){
+ while(srccells[c] && srccells[c].hidden){
+ ++c;
+ }
+ while(cells[tc] && cells[tc].hidden){
+ ++tc;
+ }
+ targets.push({
+ "r": tr,
+ "c": tc,
+ "v": srccells[c].get(r, srcg._by_idx[r].item)
+ });
+ }
+ }
+ if(this._hasIdentity(targets)){
+ console.warn("Can not write to identity!");
+ return;
+ }
+ dojo.forEach(targets, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v);
+ });
+ s.save({
+ onComplete: function(){
+ dojo.publish("dojox/grid/rearrange/change/" + g.id, ["cell", target]);
+ }
+ });
+ }
+ },
+ clearCells: function(cellsToClear){
+ var g = this.grid,
+ s = g.store;
+ if(s.getFeatures()["dojo.data.api.Write"]){
+ var cells = g.layout.cells,
+ cnt = cellsToClear.max.row - cellsToClear.min.row + 1,
+ r, c, targets = [];
+ for(r = cellsToClear.min.row; r <= cellsToClear.max.row; ++r){
+ for(c = cellsToClear.min.col; c <= cellsToClear.max.col; ++c){
+ while(cells[c] && cells[c].hidden){
+ ++c;
+ }
+ targets.push({
+ "r": r,
+ "c": c
+ });
+ }
+ }
+ if(this._hasIdentity(targets)){
+ console.warn("Can not write to identity!");
+ return;
+ }
+ dojo.forEach(targets, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, "");
+ });
+ s.save({
+ onComplete: function(){
+ dojo.publish("dojox/grid/rearrange/change/" + g.id, ["cell", cellsToClear]);
+ }
+ });
+ }
+ },
+ insertRows: function(sourceGrid, rowsToMove, targetPos){
+ try{
+ var g = this.grid,
+ s = g.store,
+ rowCnt = g.rowCount,
+ mapping = {},
+ obj = {idx: 0},
+ newRows = [], i,
+ _this = this;
+ var len = rowsToMove.length;
+ for(i = targetPos; i < g.rowCount; ++i){
+ mapping[i] = i + len;
+ }
+ if(s.getFeatures()['dojo.data.api.Write']){
+ if(sourceGrid){
+ var srcg = sourceGrid,
+ srcs = srcg.store,
+ thisItem;
+ for(i = 0; !thisItem; ++i){
+ thisItem = g._by_idx[i];
+ }
+ var attrs = s.getAttributes(thisItem.item);
+ var rowsToFetch = [];
+ dojo.forEach(rowsToMove, function(rowIndex, i){
+ var item = {};
+ var srcItem = srcg._by_idx[rowIndex];
+ if(srcItem){
+ dojo.forEach(attrs, function(attr){
+ item[attr] = srcs.getValue(srcItem.item, attr);
+ });
+ item = _this.args.setIdentifierForNewItem(item, s, rowCnt + obj.idx) || item;
+ try{
+ s.newItem(item);
+ newRows.push(targetPos + i);
+ mapping[rowCnt + obj.idx] = targetPos + i;
+ ++obj.idx;
+ }catch(e){
+ console.log("insertRows newItem:",e,item);
+ }
+ }else{
+ rowsToFetch.push(rowIndex);
+ }
+ });
+ }else if(rowsToMove.length && dojo.isObject(rowsToMove[0])){
+ dojo.forEach(rowsToMove, function(rowData, i){
+ var item = _this.args.setIdentifierForNewItem(rowData, s, rowCnt + obj.idx) || rowData;
+ try{
+ s.newItem(item);
+ newRows.push(targetPos + i);
+ mapping[rowCnt + obj.idx] = targetPos + i;
+ ++obj.idx;
+ }catch(e){
+ console.log("insertRows newItem:",e,item);
+ }
+ });
+ }else{
+ return;
+ }
+ g.layer("rowmap").setMapping(mapping);
+ s.save({
+ onComplete: function(){
+ g._refresh();
+ setTimeout(function(){
+ dojo.publish("dojox/grid/rearrange/insert/" + g.id, ["row", newRows]);
+ }, 0);
+ }
+ });
+ }
+ }catch(e){
+ console.log("insertRows:",e);
+ }
+ },
+ removeRows: function(rowsToRemove){
+ var g = this.grid;
+ var s = g.store;
+ try{
+ dojo.forEach(dojo.map(rowsToRemove, function(rowIndex){
+ return g._by_idx[rowIndex];
+ }), function(row){
+ if(row){
+ s.deleteItem(row.item);
+ }
+ });
+ s.save({
+ onComplete: function(){
+ dojo.publish("dojox/grid/rearrange/remove/" + g.id, ["row", rowsToRemove]);
+ }
+ });
+ }catch(e){
+ console.log("removeRows:",e);
+ }
+ },
+ _getPageInfo: function(){
+ // summary:
+ // Find pages that contain visible rows
+ // return: Object
+ // {topPage: xx, bottomPage: xx, invalidPages: [xx,xx,...]}
+ var scroller = this.grid.scroller,
+ topPage = scroller.page,
+ bottomPage = scroller.page,
+ firstVisibleRow = scroller.firstVisibleRow,
+ lastVisibleRow = scroller.lastVisibleRow,
+ rowsPerPage = scroller.rowsPerPage,
+ renderedPages = scroller.pageNodes[0],
+ topRow, bottomRow, matched,
+ invalidPages = [];
+
+ dojo.forEach(renderedPages, function(page, pageIndex){
+ if(!page){ return; }
+ matched = false;
+ topRow = pageIndex * rowsPerPage;
+ bottomRow = (pageIndex + 1) * rowsPerPage - 1;
+ if(firstVisibleRow >= topRow && firstVisibleRow <= bottomRow){
+ topPage = pageIndex;
+ matched = true;
+ }
+ if(lastVisibleRow >= topRow && lastVisibleRow <= bottomRow){
+ bottomPage = pageIndex;
+ matched = true;
+ }
+ if(!matched && (topRow > lastVisibleRow || bottomRow < firstVisibleRow)){
+ invalidPages.push(pageIndex);
+ }
+ });
+ return {topPage: topPage, bottomPage: bottomPage, invalidPages: invalidPages};
+ }
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Rearrange/*name:'rearrange'*/);
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Rearrange.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Rearrange.xd.js
new file mode 100644
index 0000000..92a434a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Rearrange.xd.js
@@ -0,0 +1,498 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.Rearrange"],
+["require", "dojox.grid.enhanced._Plugin"],
+["require", "dojox.grid.enhanced.plugins._RowMapLayer"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.Rearrange"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Rearrange"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Rearrange");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid.enhanced.plugins._RowMapLayer");
+
+dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provides a set of method to re-arrange the structure of grid.
+
+ // name: String
+ // plugin name
+ name: "rearrange",
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ this.setArgs(args);
+ var rowMapLayer = new dojox.grid.enhanced.plugins._RowMapLayer(grid);
+ dojox.grid.enhanced.plugins.wrap(grid, "_storeLayerFetch", rowMapLayer);
+ },
+ setArgs: function(args){
+ this.args = dojo.mixin(this.args || {}, args || {});
+ this.args.setIdentifierForNewItem = this.args.setIdentifierForNewItem || function(v){return v;};
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ this.grid.unwrap("rowmap");
+ },
+ onSetStore: function(store){
+ this.grid.layer("rowmap").clearMapping();
+ },
+ _hasIdentity: function(points){
+ var g = this.grid, s = g.store, cells = g.layout.cells;
+ if(s.getFeatures()["dojo.data.api.Identity"]){
+ if(dojo.some(points, function(point){
+ return s.getIdentityAttributes(g._by_idx[point.r].item) == cells[point.c].field;
+ })){
+ return true;
+ }
+ }
+ return false;
+ },
+ moveColumns: function(colsToMove, targetPos){
+ // summary:
+ // Move a set of columns to a given position.
+ // tag:
+ // public
+ // colsToMove: Integer[]
+ // Array of column indexes.
+ // targetPos: Integer
+ // The target position
+ var g = this.grid,
+ layout = g.layout,
+ cells = layout.cells,
+ colIndex, i, delta = 0,
+ before = true, tmp = {}, mapping = {};
+ colsToMove.sort(function(a, b){
+ return a - b;
+ });
+ for(i = 0; i < colsToMove.length; ++i){
+ tmp[colsToMove[i]] = i;
+ if(colsToMove[i] < targetPos){
+ ++delta;
+ }
+ }
+ var leftCount = 0;
+ var rightCount = 0;
+ var maxCol = Math.max(colsToMove[colsToMove.length - 1], targetPos);
+ if(maxCol == cells.length){
+ --maxCol;
+ }
+ for(i = colsToMove[0]; i <= maxCol; ++i){
+ var j = tmp[i];
+ if(j >= 0){
+ if(i != targetPos - delta + j){
+ mapping[i] = targetPos - delta + j;
+ }
+ leftCount = j + 1;
+ rightCount = colsToMove.length - j - 1;
+ }else if(i < targetPos && leftCount > 0){
+ mapping[i] = i - leftCount;
+ }else if(i >= targetPos && rightCount > 0){
+ mapping[i] = i + rightCount;
+ }
+ }
+ //console.log("mapping:", mapping, ", colsToMove:", colsToMove,", target:", targetPos);
+ delta = 0;
+ if(targetPos == cells.length){
+ --targetPos;
+ before = false;
+ }
+ g._notRefreshSelection = true;
+ for(i = 0; i < colsToMove.length; ++i){
+ colIndex = colsToMove[i];
+ if(colIndex < targetPos){
+ colIndex -= delta;
+ }
+ ++delta;
+ if(colIndex != targetPos){
+ layout.moveColumn(cells[colIndex].view.idx, cells[targetPos].view.idx, colIndex, targetPos, before);
+ cells = layout.cells;
+ }
+ if(targetPos <= colIndex){
+ ++targetPos;
+ }
+ }
+ delete g._notRefreshSelection;
+ dojo.publish("dojox/grid/rearrange/move/" + g.id, ["col", mapping]);
+ },
+ moveRows: function(rowsToMove, targetPos){
+ // summary:
+ // Move a set of rows to a given position
+ // tag:
+ // public
+ // rowsToMove: Integer[]
+ // Array of row indexes.
+ // targetPos: Integer
+ // The target position
+ var g = this.grid,
+ mapping = {},
+ preRowsToMove = [],
+ postRowsToMove = [],
+ len = rowsToMove.length,
+ i, r, k, arr, rowMap, lastPos;
+
+ for(i = 0; i < len; ++i){
+ r = rowsToMove[i];
+ if(r >= targetPos){
+ break;
+ }
+ preRowsToMove.push(r);
+ }
+ postRowsToMove = rowsToMove.slice(i);
+
+ arr = preRowsToMove;
+ len = arr.length;
+ if(len){
+ rowMap = {};
+ dojo.forEach(arr, function(r){
+ rowMap[r] = true;
+ });
+ mapping[arr[0]] = targetPos - len;
+ for(k = 0, i = arr[k] + 1, lastPos = i - 1; i < targetPos; ++i){
+ if(!rowMap[i]){
+ mapping[i] = lastPos;
+ ++lastPos;
+ }else{
+ ++k;
+ mapping[i] = targetPos - len + k;
+ }
+ }
+ }
+ arr = postRowsToMove;
+ len = arr.length;
+ if(len){
+ rowMap = {};
+ dojo.forEach(arr, function(r){
+ rowMap[r] = true;
+ });
+ mapping[arr[len - 1]] = targetPos + len - 1;
+ for(k = len - 1, i = arr[k] - 1, lastPos = i + 1; i >= targetPos; --i){
+ if(!rowMap[i]){
+ mapping[i] = lastPos;
+ --lastPos;
+ }else{
+ --k;
+ mapping[i] = targetPos + k;
+ }
+ }
+ }
+ var tmpMapping = dojo.clone(mapping);
+ g.layer("rowmap").setMapping(mapping);
+ g.forEachLayer(function(layer){
+ if(layer.name() != "rowmap"){
+ layer.invalidate();
+ return true;
+ }else{
+ return false;
+ }
+ }, false);
+ g.selection.selected = [];
+ g._noInternalMapping = true;
+ g._refresh();
+ setTimeout(function(){
+ dojo.publish("dojox/grid/rearrange/move/" + g.id, ["row", tmpMapping]);
+ g._noInternalMapping = false;
+ }, 0);
+ },
+ moveCells: function(cellsToMove, target){
+ var g = this.grid,
+ s = g.store;
+ if(s.getFeatures()["dojo.data.api.Write"]){
+ if(cellsToMove.min.row == target.min.row && cellsToMove.min.col == target.min.col){
+ //Same position, no need to move
+ return;
+ }
+ var cells = g.layout.cells,
+ cnt = cellsToMove.max.row - cellsToMove.min.row + 1,
+ r, c, tr, tc,
+ sources = [], targets = [];
+ for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){
+ for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){
+ while(cells[c] && cells[c].hidden){
+ ++c;
+ }
+ while(cells[tc] && cells[tc].hidden){
+ ++tc;
+ }
+ sources.push({
+ "r": r,
+ "c": c
+ });
+ targets.push({
+ "r": tr,
+ "c": tc,
+ "v": cells[c].get(r, g._by_idx[r].item)
+ });
+ }
+ }
+ if(this._hasIdentity(sources.concat(targets))){
+ console.warn("Can not write to identity!");
+ return;
+ }
+ dojo.forEach(sources, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, "");
+ });
+ dojo.forEach(targets, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v);
+ });
+ s.save({
+ onComplete: function(){
+ dojo.publish("dojox/grid/rearrange/move/" + g.id, ["cell", {
+ "from": cellsToMove,
+ "to": target
+ }]);
+ }
+ });
+ }
+ },
+ copyCells: function(cellsToMove, target){
+ var g = this.grid,
+ s = g.store;
+ if(s.getFeatures()["dojo.data.api.Write"]){
+ if(cellsToMove.min.row == target.min.row && cellsToMove.min.col == target.min.col){
+ return;
+ }
+ var cells = g.layout.cells,
+ cnt = cellsToMove.max.row - cellsToMove.min.row + 1,
+ r, c, tr, tc,
+ targets = [];
+ for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){
+ for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){
+ while(cells[c] && cells[c].hidden){
+ ++c;
+ }
+ while(cells[tc] && cells[tc].hidden){
+ ++tc;
+ }
+ targets.push({
+ "r": tr,
+ "c": tc,
+ "v": cells[c].get(r, g._by_idx[r].item)
+ });
+ }
+ }
+ if(this._hasIdentity(targets)){
+ console.warn("Can not write to identity!");
+ return;
+ }
+ dojo.forEach(targets, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v);
+ });
+ s.save({
+ onComplete: function(){
+ setTimeout(function(){
+ dojo.publish("dojox/grid/rearrange/copy/" + g.id, ["cell", {
+ "from": cellsToMove,
+ "to": target
+ }]);
+ }, 0);
+ }
+ });
+ }
+ },
+ changeCells: function(sourceGrid, cellsToMove, target){
+ var g = this.grid,
+ s = g.store;
+ if(s.getFeatures()["dojo.data.api.Write"]){
+ var srcg = sourceGrid,
+ cells = g.layout.cells,
+ srccells = srcg.layout.cells,
+ cnt = cellsToMove.max.row - cellsToMove.min.row + 1,
+ r, c, tr, tc, targets = [];
+ for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){
+ for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){
+ while(srccells[c] && srccells[c].hidden){
+ ++c;
+ }
+ while(cells[tc] && cells[tc].hidden){
+ ++tc;
+ }
+ targets.push({
+ "r": tr,
+ "c": tc,
+ "v": srccells[c].get(r, srcg._by_idx[r].item)
+ });
+ }
+ }
+ if(this._hasIdentity(targets)){
+ console.warn("Can not write to identity!");
+ return;
+ }
+ dojo.forEach(targets, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v);
+ });
+ s.save({
+ onComplete: function(){
+ dojo.publish("dojox/grid/rearrange/change/" + g.id, ["cell", target]);
+ }
+ });
+ }
+ },
+ clearCells: function(cellsToClear){
+ var g = this.grid,
+ s = g.store;
+ if(s.getFeatures()["dojo.data.api.Write"]){
+ var cells = g.layout.cells,
+ cnt = cellsToClear.max.row - cellsToClear.min.row + 1,
+ r, c, targets = [];
+ for(r = cellsToClear.min.row; r <= cellsToClear.max.row; ++r){
+ for(c = cellsToClear.min.col; c <= cellsToClear.max.col; ++c){
+ while(cells[c] && cells[c].hidden){
+ ++c;
+ }
+ targets.push({
+ "r": r,
+ "c": c
+ });
+ }
+ }
+ if(this._hasIdentity(targets)){
+ console.warn("Can not write to identity!");
+ return;
+ }
+ dojo.forEach(targets, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, "");
+ });
+ s.save({
+ onComplete: function(){
+ dojo.publish("dojox/grid/rearrange/change/" + g.id, ["cell", cellsToClear]);
+ }
+ });
+ }
+ },
+ insertRows: function(sourceGrid, rowsToMove, targetPos){
+ try{
+ var g = this.grid,
+ s = g.store,
+ rowCnt = g.rowCount,
+ mapping = {},
+ obj = {idx: 0},
+ newRows = [], i,
+ _this = this;
+ var len = rowsToMove.length;
+ for(i = targetPos; i < g.rowCount; ++i){
+ mapping[i] = i + len;
+ }
+ if(s.getFeatures()['dojo.data.api.Write']){
+ if(sourceGrid){
+ var srcg = sourceGrid,
+ srcs = srcg.store,
+ thisItem;
+ for(i = 0; !thisItem; ++i){
+ thisItem = g._by_idx[i];
+ }
+ var attrs = s.getAttributes(thisItem.item);
+ var rowsToFetch = [];
+ dojo.forEach(rowsToMove, function(rowIndex, i){
+ var item = {};
+ var srcItem = srcg._by_idx[rowIndex];
+ if(srcItem){
+ dojo.forEach(attrs, function(attr){
+ item[attr] = srcs.getValue(srcItem.item, attr);
+ });
+ item = _this.args.setIdentifierForNewItem(item, s, rowCnt + obj.idx) || item;
+ try{
+ s.newItem(item);
+ newRows.push(targetPos + i);
+ mapping[rowCnt + obj.idx] = targetPos + i;
+ ++obj.idx;
+ }catch(e){
+ console.log("insertRows newItem:",e,item);
+ }
+ }else{
+ rowsToFetch.push(rowIndex);
+ }
+ });
+ }else if(rowsToMove.length && dojo.isObject(rowsToMove[0])){
+ dojo.forEach(rowsToMove, function(rowData, i){
+ var item = _this.args.setIdentifierForNewItem(rowData, s, rowCnt + obj.idx) || rowData;
+ try{
+ s.newItem(item);
+ newRows.push(targetPos + i);
+ mapping[rowCnt + obj.idx] = targetPos + i;
+ ++obj.idx;
+ }catch(e){
+ console.log("insertRows newItem:",e,item);
+ }
+ });
+ }else{
+ return;
+ }
+ g.layer("rowmap").setMapping(mapping);
+ s.save({
+ onComplete: function(){
+ g._refresh();
+ setTimeout(function(){
+ dojo.publish("dojox/grid/rearrange/insert/" + g.id, ["row", newRows]);
+ }, 0);
+ }
+ });
+ }
+ }catch(e){
+ console.log("insertRows:",e);
+ }
+ },
+ removeRows: function(rowsToRemove){
+ var g = this.grid;
+ var s = g.store;
+ try{
+ dojo.forEach(dojo.map(rowsToRemove, function(rowIndex){
+ return g._by_idx[rowIndex];
+ }), function(row){
+ if(row){
+ s.deleteItem(row.item);
+ }
+ });
+ s.save({
+ onComplete: function(){
+ dojo.publish("dojox/grid/rearrange/remove/" + g.id, ["row", rowsToRemove]);
+ }
+ });
+ }catch(e){
+ console.log("removeRows:",e);
+ }
+ },
+ _getPageInfo: function(){
+ // summary:
+ // Find pages that contain visible rows
+ // return: Object
+ // {topPage: xx, bottomPage: xx, invalidPages: [xx,xx,...]}
+ var scroller = this.grid.scroller,
+ topPage = scroller.page,
+ bottomPage = scroller.page,
+ firstVisibleRow = scroller.firstVisibleRow,
+ lastVisibleRow = scroller.lastVisibleRow,
+ rowsPerPage = scroller.rowsPerPage,
+ renderedPages = scroller.pageNodes[0],
+ topRow, bottomRow, matched,
+ invalidPages = [];
+
+ dojo.forEach(renderedPages, function(page, pageIndex){
+ if(!page){ return; }
+ matched = false;
+ topRow = pageIndex * rowsPerPage;
+ bottomRow = (pageIndex + 1) * rowsPerPage - 1;
+ if(firstVisibleRow >= topRow && firstVisibleRow <= bottomRow){
+ topPage = pageIndex;
+ matched = true;
+ }
+ if(lastVisibleRow >= topRow && lastVisibleRow <= bottomRow){
+ bottomPage = pageIndex;
+ matched = true;
+ }
+ if(!matched && (topRow > lastVisibleRow || bottomRow < firstVisibleRow)){
+ invalidPages.push(pageIndex);
+ }
+ });
+ return {topPage: topPage, bottomPage: bottomPage, invalidPages: invalidPages};
+ }
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Rearrange/*name:'rearrange'*/);
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Search.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Search.js
new file mode 100644
index 0000000..c4f6420
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Search.js
@@ -0,0 +1,120 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.Search"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Search"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Search");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojo.data.util.filter");
+
+dojo.declare("dojox.grid.enhanced.plugins.Search", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Search the grid using wildcard string or Regular Expression.
+
+ // name: String
+ // plugin name
+ name: "search",
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ args = (args && dojo.isObject(args)) ? args : {};
+ this._cacheSize = args.cacheSize || -1;
+ grid.searchRow = dojo.hitch(this, "searchRow");
+ },
+ searchRow: function(/* Object|RegExp|String */searchArgs, /* function(Integer, item) */onSearched){
+ if(!dojo.isFunction(onSearched)){ return; }
+ if(dojo.isString(searchArgs)){
+ searchArgs = dojo.data.util.filter.patternToRegExp(searchArgs);
+ }
+ var isGlobal = false;
+ if(searchArgs instanceof RegExp){
+ isGlobal = true;
+ }else if(dojo.isObject(searchArgs)){
+ var isEmpty = true;
+ for(var field in searchArgs){
+ if(dojo.isString(searchArgs[field])){
+ searchArgs[field] = dojo.data.util.filter.patternToRegExp(searchArgs[field]);
+ }
+ isEmpty = false;
+ }
+ if(isEmpty){ return; }
+ }else{
+ return;
+ }
+ this._search(searchArgs, 0, onSearched, isGlobal);
+ },
+ _search: function(/* Object|RegExp */searchArgs, /* Integer */start, /* function(Integer, item) */onSearched, /* Boolean */isGlobal){
+ var _this = this,
+ cnt = this._cacheSize,
+ args = {
+ "start": start,
+ "onBegin": function(size){
+ _this._storeSize = size;
+ },
+ "onComplete": function(items){
+ if(!dojo.some(items, function(item, i){
+ if(_this._checkRow(item, searchArgs, isGlobal)){
+ onSearched(start + i, item);
+ return true;
+ }
+ return false;
+ })){
+ if(cnt > 0 && start + cnt < _this._storeSize){
+ _this._search(searchArgs, start + cnt, onSearched, isGlobal);
+ }else{
+ onSearched(-1, null);
+ }
+ }
+ }
+ };
+ if(cnt > 0){
+ args.count = cnt;
+ }
+ this.grid._storeLayerFetch(args);
+ },
+ _checkRow: function(/* store item */item, /* Object|RegExp */searchArgs, /* Boolean */isGlobal){
+ var g = this.grid, s = g.store, i, field,
+ cells = dojo.filter(g.layout.cells, function(cell){
+ return !cell.hidden;
+ });
+ if(isGlobal){
+ return dojo.some(cells, function(cell){
+ try{
+ if(cell.field){
+ return String(s.getValue(item, cell.field)).search(searchArgs) >= 0;
+ }
+ }catch(e){
+ console.log("Search._checkRow() error: ", e);
+ }
+ return false;
+ });
+ }else{
+ for(field in searchArgs){
+ if(searchArgs[field] instanceof RegExp){
+ for(i = cells.length - 1; i >= 0; --i){
+ if(cells[i].field == field){
+ try{
+ if(String(s.getValue(item, field)).search(searchArgs[field]) < 0){
+ return false;
+ }
+ break;
+ }catch(e){
+ return false;
+ }
+ }
+ }
+ if(i < 0){ return false; }
+ }
+ }
+ return true;
+ }
+ }
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Search/*name:'search'*/);
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Search.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Search.xd.js
new file mode 100644
index 0000000..6e19301
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Search.xd.js
@@ -0,0 +1,126 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.Search"],
+["require", "dojox.grid.enhanced._Plugin"],
+["require", "dojo.data.util.filter"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.Search"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Search"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Search");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojo.data.util.filter");
+
+dojo.declare("dojox.grid.enhanced.plugins.Search", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Search the grid using wildcard string or Regular Expression.
+
+ // name: String
+ // plugin name
+ name: "search",
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ args = (args && dojo.isObject(args)) ? args : {};
+ this._cacheSize = args.cacheSize || -1;
+ grid.searchRow = dojo.hitch(this, "searchRow");
+ },
+ searchRow: function(/* Object|RegExp|String */searchArgs, /* function(Integer, item) */onSearched){
+ if(!dojo.isFunction(onSearched)){ return; }
+ if(dojo.isString(searchArgs)){
+ searchArgs = dojo.data.util.filter.patternToRegExp(searchArgs);
+ }
+ var isGlobal = false;
+ if(searchArgs instanceof RegExp){
+ isGlobal = true;
+ }else if(dojo.isObject(searchArgs)){
+ var isEmpty = true;
+ for(var field in searchArgs){
+ if(dojo.isString(searchArgs[field])){
+ searchArgs[field] = dojo.data.util.filter.patternToRegExp(searchArgs[field]);
+ }
+ isEmpty = false;
+ }
+ if(isEmpty){ return; }
+ }else{
+ return;
+ }
+ this._search(searchArgs, 0, onSearched, isGlobal);
+ },
+ _search: function(/* Object|RegExp */searchArgs, /* Integer */start, /* function(Integer, item) */onSearched, /* Boolean */isGlobal){
+ var _this = this,
+ cnt = this._cacheSize,
+ args = {
+ "start": start,
+ "onBegin": function(size){
+ _this._storeSize = size;
+ },
+ "onComplete": function(items){
+ if(!dojo.some(items, function(item, i){
+ if(_this._checkRow(item, searchArgs, isGlobal)){
+ onSearched(start + i, item);
+ return true;
+ }
+ return false;
+ })){
+ if(cnt > 0 && start + cnt < _this._storeSize){
+ _this._search(searchArgs, start + cnt, onSearched, isGlobal);
+ }else{
+ onSearched(-1, null);
+ }
+ }
+ }
+ };
+ if(cnt > 0){
+ args.count = cnt;
+ }
+ this.grid._storeLayerFetch(args);
+ },
+ _checkRow: function(/* store item */item, /* Object|RegExp */searchArgs, /* Boolean */isGlobal){
+ var g = this.grid, s = g.store, i, field,
+ cells = dojo.filter(g.layout.cells, function(cell){
+ return !cell.hidden;
+ });
+ if(isGlobal){
+ return dojo.some(cells, function(cell){
+ try{
+ if(cell.field){
+ return String(s.getValue(item, cell.field)).search(searchArgs) >= 0;
+ }
+ }catch(e){
+ console.log("Search._checkRow() error: ", e);
+ }
+ return false;
+ });
+ }else{
+ for(field in searchArgs){
+ if(searchArgs[field] instanceof RegExp){
+ for(i = cells.length - 1; i >= 0; --i){
+ if(cells[i].field == field){
+ try{
+ if(String(s.getValue(item, field)).search(searchArgs[field]) < 0){
+ return false;
+ }
+ break;
+ }catch(e){
+ return false;
+ }
+ }
+ }
+ if(i < 0){ return false; }
+ }
+ }
+ return true;
+ }
+ }
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Search/*name:'search'*/);
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Selector.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Selector.js
new file mode 100644
index 0000000..2511ce1
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Selector.js
@@ -0,0 +1,1456 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.Selector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Selector"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Selector");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid.enhanced.plugins.AutoScroll");
+dojo.require("dojox.grid.cells._base");
+
+(function(){
+/*=====
+dojo.declare("__SelectItem", null,{
+ // summary:
+ // An abstract representation of an item.
+});
+dojo.declare("__SelectCellItem", __SelectItem,{
+ // summary:
+ // An abstract representation of a cell.
+
+ // row: Integer
+ // Row index of this cell
+ row: 0,
+
+ // col: Integer
+ // Column index of this cell
+ col: 0
+});
+dojo.declare("__SelectRowItem", __SelectItem,{
+ // summary:
+ // An abstract representation of a row.
+
+ // row: Integer
+ // Row index of this row
+ row: 0,
+
+ // except: Integer[]
+ // An array of column indexes of all the unselected cells in this row.
+ except: []
+});
+dojo.declare("__SelectColItem", __SelectItem,{
+ // summary:
+ // An abstract representation of a column.
+
+ // col: Integer
+ // Column index of this column
+ col: 0,
+
+ // except: Integer[]
+ // An array of row indexes of all the unselected cells in this column.
+ except: []
+});
+=====*/
+
+var DISABLED = 0, SINGLE = 1, MULTI = 2,
+ _theOther = { col: "row", row: "col" },
+ _inRange = function(type, value, start, end, halfClose){
+ if(type !== "cell"){
+ value = value[type];
+ start = start[type];
+ end = end[type];
+ if(typeof value !== "number" || typeof start !== "number" || typeof end !== "number"){
+ return false;
+ }
+ return halfClose ? ((value >= start && value < end) || (value > end && value <= start))
+ : ((value >= start && value <= end) || (value >= end && value <= start));
+ }else{
+ return _inRange("col", value, start, end, halfClose) && _inRange("row", value, start, end, halfClose);
+ }
+ },
+ _isEqual = function(type, v1, v2){
+ try{
+ if(v1 && v2){
+ switch(type){
+ case "col": case "row":
+ return v1[type] == v2[type] && typeof v1[type] == "number" &&
+ !(_theOther[type] in v1) && !(_theOther[type] in v2);
+ case "cell":
+ return v1.col == v2.col && v1.row == v2.row && typeof v1.col == "number" && typeof v1.row == "number";
+ }
+ }
+ }catch(e){}
+ return false;
+ },
+ _stopEvent = function(evt){
+ try{
+ if(evt && evt.preventDefault){
+ dojo.stopEvent(evt);
+ }
+ }catch(e){}
+ },
+ _createItem = function(type, rowIndex, colIndex){
+ switch(type){
+ case "col":
+ return {
+ "col": typeof colIndex == "undefined" ? rowIndex : colIndex,
+ "except": []
+ };
+ case "row":
+ return {
+ "row": rowIndex,
+ "except": []
+ };
+ case "cell":
+ return {
+ "row": rowIndex,
+ "col": colIndex
+ };
+ }
+ return null;
+ };
+dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provides standard extended selection for grid.
+ // Supports mouse/keyboard selection, multi-selection, and de-selection.
+ // Acceptable plugin parameters:
+ // The whole plugin parameter object is a config object passed to the setupConfig function.
+ //
+ // Acceptable cell parameters defined in layout:
+ // 1. notselectable: boolean
+ // Whether this column is (and all the cells in it are) selectable.
+
+ // name: String
+ // plugin name
+ name: "selector",
+/*
+ // _config: null,
+ // _enabled: true,
+ // _selecting: {
+ // row: false,
+ // col: false,
+ // cell: false
+ // },
+ // _selected: {
+ // row: [],
+ // col: [],
+ // cell: []
+ // },
+ // _startPoint: {},
+ // _currentPoint: {},
+ // _lastAnchorPoint: {},
+ // _lastEndPoint: {},
+ // _lastSelectedAnchorPoint: {},
+ // _lastSelectedEndPoint: {},
+ // _keyboardSelect: {
+ // row: 0,
+ // col: 0,
+ // cell: 0
+ // },
+ // _curType: null,
+ // _lastType: null,
+ // _usingKeyboard: false,
+ // _toSelect: true,
+*/
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ this._config = {
+ row: MULTI,
+ col: MULTI,
+ cell: MULTI
+ };
+ this.setupConfig(args);
+ if(grid.selectionMode === "single"){
+ this._config.row = SINGLE;
+ }
+ this._enabled = true;
+ this._selecting = {};
+ this._selected = {
+ "col": [],
+ "row": [],
+ "cell": []
+ };
+ this._startPoint = {};
+ this._currentPoint = {};
+ this._lastAnchorPoint = {};
+ this._lastEndPoint = {};
+ this._lastSelectedAnchorPoint = {};
+ this._lastSelectedEndPoint = {};
+ this._keyboardSelect = {};
+ this._lastType = null;
+ this._selectedRowModified = {};
+ this._hacks();
+ this._initEvents();
+ this._initAreas();
+ this._mixinGrid();
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ },
+ //------------public--------------------
+ setupConfig: function(config){
+ // summary:
+ // Set selection mode for row/col/cell.
+ // config: Object
+ // An object with the following structure (all properties are optional):
+ // {
+ // //Default is "multi", all other values are same as "multi".
+ // row: false|"disabled"|"single",
+ // col: false|"disabled"|"single",
+ // cell: false|"disabled"|"single"
+ // }
+ if(!config || !dojo.isObject(config)){
+ return;
+ }
+ var types = ["row", "col", "cell"];
+ for(var type in config){
+ if(dojo.indexOf(types, type) >= 0){
+ if(!config[type] || config[type] == "disabled"){
+ this._config[type] = DISABLED;
+ }else if(config[type] == "single"){
+ this._config[type] = SINGLE;
+ }else{
+ this._config[type] = MULTI;
+ }
+ }
+ }
+
+ //Have to set mode to default grid selection.
+ var mode = ["none","single","extended"][this._config.row];
+ this.grid.selection.setMode(mode);
+ },
+ isSelected: function(type, rowIndex, colIndex){
+ // summary:
+ // Check whether a location (a cell, a column or a row) is selected.
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // rowIndex: Integer
+ // If type is "row" or "cell", this is the row index.
+ // If type if "col", this is the column index.
+ // colIndex: Integer?
+ // Only valid when type is "cell"
+ // return: Boolean
+ // true if selected, false if not. If cell is covered by a selected column, it's selected.
+ return this._isSelected(type, _createItem(type, rowIndex, colIndex));
+ },
+ toggleSelect: function(type, rowIndex, colIndex){
+ this._startSelect(type, _createItem(type, rowIndex, colIndex), this._config[type] === MULTI, false);
+ this._endSelect(type);
+ },
+ select: function(type, rowIndex, colIndex){
+ // summary:
+ // Select a location (a cell, a column or a row).
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // rowIndex: Integer
+ // If type is "row" or "cell", this is the row index.
+ // If type if "col", this is the column index.
+ // colIndex: Integer?
+ // Only valid when type is "cell"
+ if(!this.isSelected(type, rowIndex, colIndex)){
+ this.toggleSelect(type, rowIndex, colIndex);
+ }
+ },
+ deselect: function(type, rowIndex, colIndex){
+ if(this.isSelected(type, rowIndex, colIndex)){
+ this.toggleSelect(type, rowIndex, colIndex);
+ }
+ },
+ selectRange: function(type, start, end, toSelect){
+ // summary:
+ // Select a continuous range (a block of cells, a set of continuous columns or rows)
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // start: Integer | Object
+ // If type is "row" or "col", this is the index of the starting row or column.
+ // If type if "cell", this is the left-top cell of the range.
+ // end: Integer | Object
+ // If type is "row" or "col", this is the index of the ending row or column.
+ // If type if "cell", this is the right-bottom cell of the range.
+ this.grid._selectingRange = true;
+ var startPoint = type == "cell" ? _createItem(type, start.row, start.col) : _createItem(type, start),
+ endPoint = type == "cell" ? _createItem(type, end.row, end.col) : _createItem(type, end);
+ this._startSelect(type, startPoint, false, false, false, toSelect);
+ this._highlight(type, endPoint, toSelect === undefined ? true : toSelect);
+ this._endSelect(type);
+ this.grid._selectingRange = false;
+ },
+ clear: function(type){
+ // summary:
+ // Clear all selections.
+ // tag:
+ // public
+ // type: String?
+ // "row" or "col" or "cell". If omitted, clear all.
+ this._clearSelection(type || "all");
+ },
+ isSelecting: function(type){
+ // summary:
+ // Check whether the user is currently selecting something.
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // return: Boolean
+ // true if is selection, false otherwise.
+ if(typeof type == "undefined"){
+ return this._selecting.col || this._selecting.row || this._selecting.cell;
+ }
+ return this._selecting[type];
+ },
+ selectEnabled: function(toEnable){
+ // summary:
+ // Turn on/off this selection functionality if *toEnable* is provided.
+ // Check whether this selection functionality is enabled if nothing is passed in.
+ // tag:
+ // public
+ // toEnable: Boolean?
+ // To enable or not. Optional.
+ // return: Boolean | undefined
+ // Enabled or not.
+ if(typeof toEnable != "undefined" && !this.isSelecting()){
+ this._enabled = !!toEnable;
+ }
+ return this._enabled;
+ },
+ getSelected: function(type, includeExceptions){
+ // summary:
+ // Get an array of selected locations.
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // includeExceptions: Boolean
+ // Only meaningful for rows/columns. If true, all selected rows/cols, even they are partly selected, are all returned.
+ // return: __SelectItem[]
+ switch(type){
+ case "cell":
+ return dojo.map(this._selected[type], function(item){ return item; });
+ case "col": case "row":
+ return dojo.map(includeExceptions ? this._selected[type]
+ : dojo.filter(this._selected[type], function(item){
+ return item.except.length === 0;
+ }), function(item){
+ return includeExceptions ? item : item[type];
+ });
+ }
+ return [];
+ },
+ getSelectedCount: function(type, includeExceptions){
+ // summary:
+ // Get the number of selected items.
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // includeExceptions: Boolean
+ // Only meaningful for rows/columns. If true, all selected rows/cols, even they are partly selected, are all returned.
+ // return: Integer
+ // The number of selected items.
+ switch(type){
+ case "cell":
+ return this._selected[type].length;
+ case "col": case "row":
+ return (includeExceptions ? this._selected[type]
+ : dojo.filter(this._selected[type], function(item){
+ return item.except.length === 0;
+ })).length;
+ }
+ return 0;
+ },
+ getSelectedType: function(){
+ // summary:
+ // Get the type of selected items.
+ // tag:
+ // public
+ // return: String
+ // "row" or "col" or "cell", or any mix of these (separator is | ).
+ var s = this._selected;
+ return ["", "cell", "row", "row|cell",
+ "col", "col|cell", "col|row", "col|row|cell"
+ ][(!!s.cell.length) | (!!s.row.length << 1) | (!!s.col.length << 2)];
+ },
+ getLastSelectedRange: function(type){
+ // summary:
+ // Get last selected range of the given type.
+ // tag:
+ // public
+ // return: Object
+ // {start: __SelectItem, end: __SelectItem}
+ // return null if nothing is selected.
+ return this._lastAnchorPoint[type] ? {
+ "start": this._lastAnchorPoint[type],
+ "end": this._lastEndPoint[type]
+ } : null;
+ },
+
+ //--------------------------private----------------------------
+ _hacks: function(){
+ // summary:
+ // Complete the event system of grid, hack some grid functions to prevent default behavior.
+ var g = this.grid;
+ var doContentMouseUp = function(e){
+ if(e.cellNode){
+ g.onMouseUp(e);
+ }
+ g.onMouseUpRow(e);
+ };
+ var mouseUp = dojo.hitch(g, "onMouseUp");
+ var mouseDown = dojo.hitch(g, "onMouseDown");
+ var doRowSelectorFocus = function(e){
+ e.cellNode.style.border = "solid 1px";
+ };
+ dojo.forEach(g.views.views, function(view){
+ view.content.domouseup = doContentMouseUp;
+ view.header.domouseup = mouseUp;
+ if(view.declaredClass == "dojox.grid._RowSelector"){
+ view.domousedown = mouseDown;
+ view.domouseup = mouseUp;
+ view.dofocus = doRowSelectorFocus;
+ }
+ });
+ //Disable default selection.
+ g.selection.clickSelect = function(){};
+
+ this._oldDeselectAll = g.selection.deselectAll;
+ var _this = this;
+ g.selection.selectRange = function(from, to){
+ _this.selectRange("row", from, to, true);
+ if(g.selection.preserver){
+ g.selection.preserver._updateMapping(true, true, false, from, to);
+ }
+ g.selection.onChanged();
+ };
+ g.selection.deselectRange = function(from, to){
+ _this.selectRange("row", from, to, false);
+ if(g.selection.preserver){
+ g.selection.preserver._updateMapping(true, false, false, from, to);
+ }
+ g.selection.onChanged();
+ };
+ g.selection.deselectAll = function(){
+ g._selectingRange = true;
+ _this._oldDeselectAll.apply(g.selection, arguments);
+ _this._clearSelection("row");
+ g._selectingRange = false;
+ if(g.selection.preserver){
+ g.selection.preserver._updateMapping(true, false, true);
+ }
+ g.selection.onChanged();
+ };
+
+ var rowSelector = g.views.views[0];
+ //The default function re-write the whole className, so can not insert any other classes.
+ if(rowSelector instanceof dojox.grid._RowSelector){
+ rowSelector.doStyleRowNode = function(inRowIndex, inRowNode){
+ dojo.removeClass(inRowNode, "dojoxGridRow");
+ dojo.addClass(inRowNode, "dojoxGridRowbar");
+ dojo.addClass(inRowNode, "dojoxGridNonNormalizedCell");
+ dojo.toggleClass(inRowNode, "dojoxGridRowbarOver", g.rows.isOver(inRowIndex));
+ dojo.toggleClass(inRowNode, "dojoxGridRowbarSelected", !!g.selection.isSelected(inRowIndex));
+ };
+ }
+ this.connect(g, "updateRow", function(rowIndex){
+ dojo.forEach(g.layout.cells, function(cell){
+ if(this.isSelected("cell", rowIndex, cell.index)){
+ this._highlightNode(cell.getNode(rowIndex), true);
+ }
+ }, this);
+ });
+ },
+ _mixinGrid: function(){
+ // summary:
+ // Expose events to grid.
+ var g = this.grid;
+ g.setupSelectorConfig = dojo.hitch(this, this.setupConfig);
+ g.onStartSelect = function(){};
+ g.onEndSelect = function(){};
+ g.onStartDeselect = function(){};
+ g.onEndDeselect = function(){};
+ g.onSelectCleared = function(){};
+ },
+ _initEvents: function(){
+ // summary:
+ // Connect events, create event handlers.
+ var g = this.grid,
+ _this = this,
+ dp = dojo.partial,
+ starter = function(type, e){
+ if(type === "row"){
+ _this._isUsingRowSelector = true;
+ }
+ //only left mouse button can select.
+ if(_this.selectEnabled() && _this._config[type] && e.button != 2){
+ if(_this._keyboardSelect.col || _this._keyboardSelect.row || _this._keyboardSelect.cell){
+ _this._endSelect("all");
+ _this._keyboardSelect.col = _this._keyboardSelect.row = _this._keyboardSelect.cell = 0;
+ }
+ if(_this._usingKeyboard){
+ _this._usingKeyboard = false;
+ }
+ var target = _createItem(type, e.rowIndex, e.cell && e.cell.index);
+ _this._startSelect(type, target, e.ctrlKey, e.shiftKey);
+ }
+ },
+ ender = dojo.hitch(this, "_endSelect");
+ this.connect(g, "onHeaderCellMouseDown", dp(starter, "col"));
+ this.connect(g, "onHeaderCellMouseUp", dp(ender, "col"));
+
+ this.connect(g, "onRowSelectorMouseDown", dp(starter, "row"));
+ this.connect(g, "onRowSelectorMouseUp", dp(ender, "row"));
+
+ this.connect(g, "onCellMouseDown", function(e){
+ if(e.cell && e.cell.isRowSelector){ return; }
+ if(g.singleClickEdit){
+ _this._singleClickEdit = true;
+ g.singleClickEdit = false;
+ }
+ starter(_this._config["cell"] == DISABLED ? "row" : "cell", e);
+ });
+ this.connect(g, "onCellMouseUp", function(e){
+ if(_this._singleClickEdit){
+ delete _this._singleClickEdit;
+ g.singleClickEdit = true;
+ }
+ ender("all", e);
+ });
+
+ this.connect(g, "onCellMouseOver", function(e){
+ if(_this._curType != "row" && _this._selecting[_this._curType] && _this._config[_this._curType] == MULTI){
+ _this._highlight("col", _createItem("col", e.cell.index), _this._toSelect);
+ if(!_this._keyboardSelect.cell){
+ _this._highlight("cell", _createItem("cell", e.rowIndex, e.cell.index), _this._toSelect);
+ }
+ }
+ });
+ this.connect(g, "onHeaderCellMouseOver", function(e){
+ if(_this._selecting.col && _this._config.col == MULTI){
+ _this._highlight("col", _createItem("col", e.cell.index), _this._toSelect);
+ }
+ });
+ this.connect(g, "onRowMouseOver", function(e){
+ if(_this._selecting.row && _this._config.row == MULTI){
+ _this._highlight("row", _createItem("row", e.rowIndex), _this._toSelect);
+ }
+ });
+
+ //When row order has changed in a unpredictable way (sorted or filtered), map the new rowindex.
+ this.connect(g, "onSelectedById", "_onSelectedById");
+
+ //When the grid refreshes, all those selected should still appear selected.
+ this.connect(g, "_onFetchComplete", function(){
+ //console.debug("refresh after buildPage:", g._notRefreshSelection);
+ if(!g._notRefreshSelection){
+ this._refreshSelected(true);
+ }
+ });
+
+ //Small scroll might not refresh the grid.
+ this.connect(g.scroller, "buildPage", function(){
+ //console.debug("refresh after buildPage:", g._notRefreshSelection);
+ if(!g._notRefreshSelection){
+ this._refreshSelected(true);
+ }
+ });
+
+ //Whenever the mouse is up, end selecting.
+ this.connect(dojo.doc, "onmouseup", dp(ender, "all"));
+
+ //If autoscroll is enabled, connect to it.
+ this.connect(g, "onEndAutoScroll", function(isVertical, isForward, view, target){
+ var selectCell = _this._selecting.cell,
+ type, current, dir = isForward ? 1 : -1;
+ if(isVertical && (selectCell || _this._selecting.row)){
+ type = selectCell ? "cell" : "row";
+ current = _this._currentPoint[type];
+ _this._highlight(type, _createItem(type, current.row + dir, current.col), _this._toSelect);
+ }else if(!isVertical && (selectCell || _this._selecting.col)){
+ type = selectCell ? "cell" : "col";
+ current = _this._currentPoint[type];
+ _this._highlight(type, _createItem(type, current.row, target), _this._toSelect);
+ }
+ });
+ //If the grid is changed, selection should be consistent.
+ this.subscribe("dojox/grid/rearrange/move/" + g.id, "_onInternalRearrange");
+ this.subscribe("dojox/grid/rearrange/copy/" + g.id, "_onInternalRearrange");
+ this.subscribe("dojox/grid/rearrange/change/" + g.id, "_onExternalChange");
+ this.subscribe("dojox/grid/rearrange/insert/" + g.id, "_onExternalChange");
+ this.subscribe("dojox/grid/rearrange/remove/" + g.id, "clear");
+
+ //have to also select when the grid's default select is used.
+ this.connect(g, "onSelected", function(rowIndex){
+ if(this._selectedRowModified && this._isUsingRowSelector){
+ delete this._selectedRowModified;
+ }else if(!this.grid._selectingRange){
+ this.select("row", rowIndex);
+ }
+ });
+ this.connect(g, "onDeselected", function(rowIndex){
+ if(this._selectedRowModified && this._isUsingRowSelector){
+ delete this._selectedRowModified;
+ }else if(!this.grid._selectingRange){
+ this.deselect("row", rowIndex);
+ }
+ });
+ },
+ _onSelectedById: function(id, newIndex, isSelected){
+ if(this.grid._noInternalMapping){
+ return;
+ }
+ var pointSet = [this._lastAnchorPoint.row, this._lastEndPoint.row,
+ this._lastSelectedAnchorPoint.row, this._lastSelectedEndPoint.row];
+ pointSet = pointSet.concat(this._selected.row);
+ var found = false;
+ dojo.forEach(pointSet, function(item){
+ if(item){
+ if(item.id === id){
+ found = true;
+ item.row = newIndex;
+ }else if(item.row === newIndex && item.id){
+ item.row = -1;
+ }
+ }
+ });
+ if(!found && isSelected){
+ dojo.some(this._selected.row, function(item){
+ if(item && !item.id && !item.except.length){
+ item.id = id;
+ item.row = newIndex;
+ return true;
+ }
+ return false;
+ });
+ }
+ found = false;
+ pointSet = [this._lastAnchorPoint.cell, this._lastEndPoint.cell,
+ this._lastSelectedAnchorPoint.cell, this._lastSelectedEndPoint.cell];
+ pointSet = pointSet.concat(this._selected.cell);
+ dojo.forEach(pointSet, function(item){
+ if(item){
+ if(item.id === id){
+ found = true;
+ item.row = newIndex;
+ }else if(item.row === newIndex && item.id){
+ item.row = -1;
+ }
+ }
+ });
+ },
+ onSetStore: function(){
+ this._clearSelection("all");
+ },
+ _onInternalRearrange: function(type, mapping){
+ try{
+ //The column can not refresh it self!
+ this._refresh("col", false);
+
+ dojo.forEach(this._selected.row, function(item){
+ dojo.forEach(this.grid.layout.cells, function(cell){
+ this._highlightNode(cell.getNode(item.row), false);
+ }, this);
+ }, this);
+ //The rowbar must be cleaned manually
+ dojo.query(".dojoxGridRowSelectorSelected").forEach(function(node){
+ dojo.removeClass(node, "dojoxGridRowSelectorSelected");
+ dojo.removeClass(node, "dojoxGridRowSelectorSelectedUp");
+ dojo.removeClass(node, "dojoxGridRowSelectorSelectedDown");
+ });
+
+ var cleanUp = function(item){
+ if(item){
+ delete item.converted;
+ }
+ },
+ pointSet = [this._lastAnchorPoint[type], this._lastEndPoint[type],
+ this._lastSelectedAnchorPoint[type], this._lastSelectedEndPoint[type]];
+
+ if(type === "cell"){
+ this.selectRange("cell", mapping.to.min, mapping.to.max);
+ var cells = this.grid.layout.cells;
+ dojo.forEach(pointSet, function(item){
+ if(item.converted){ return; }
+ for(var r = mapping.from.min.row, tr = mapping.to.min.row; r <= mapping.from.max.row; ++r, ++tr){
+ for(var c = mapping.from.min.col, tc = mapping.to.min.col; c <= mapping.from.max.col; ++c, ++tc){
+ while(cells[c].hidden){ ++c; }
+ while(cells[tc].hidden){ ++tc; }
+ if(item.row == r && item.col == c){
+ //console.log('mapping found: (', item.row, ",",item.col,") to (", tr, ",", tc,")");
+ item.row = tr;
+ item.col = tc;
+ item.converted = true;
+ return;
+ }
+ }
+ }
+ });
+ }else{
+ pointSet = this._selected.cell.concat(this._selected[type]).concat(pointSet).concat(
+ [this._lastAnchorPoint.cell, this._lastEndPoint.cell,
+ this._lastSelectedAnchorPoint.cell, this._lastSelectedEndPoint.cell]);
+ dojo.forEach(pointSet, function(item){
+ if(item && !item.converted){
+ var from = item[type];
+ if(from in mapping){
+ item[type] = mapping[from];
+ }
+ item.converted = true;
+ }
+ });
+ dojo.forEach(this._selected[_theOther[type]], function(item){
+ for(var i = 0, len = item.except.length; i < len; ++i){
+ var from = item.except[i];
+ if(from in mapping){
+ item.except[i] = mapping[from];
+ }
+ }
+ });
+ }
+
+ dojo.forEach(pointSet, cleanUp);
+
+ this._refreshSelected(true);
+ this._focusPoint(type, this._lastEndPoint);
+ }catch(e){
+ console.warn("Selector._onInternalRearrange() error",e);
+ }
+ },
+ _onExternalChange: function(type, target){
+ var start = type == "cell" ? target.min : target[0],
+ end = type == "cell" ? target.max : target[target.length - 1];
+ this.selectRange(type, start, end);
+ },
+ _refresh: function(type, toHighlight){
+ if(!this._keyboardSelect[type]){
+ dojo.forEach(this._selected[type], function(item){
+ this._highlightSingle(type, toHighlight, item, undefined, true);
+ }, this);
+ }
+ },
+ _refreshSelected: function(){
+ this._refresh("col", true);
+ this._refresh("row", true);
+ this._refresh("cell", true);
+ },
+ _initAreas: function(){
+ var g = this.grid, f = g.focus, _this = this, dk = dojo.keys,
+ keyboardSelectReady = 1, duringKeyboardSelect = 2,
+ onmove = function(type, createNewEnd, rowStep, colStep, evt){
+ //Keyboard swipe selection is SHIFT + Direction Keys.
+ var ks = _this._keyboardSelect;
+ //Tricky, rely on valid status not being 0.
+ if(evt.shiftKey && ks[type]){
+ if(ks[type] === keyboardSelectReady){
+ if(type === "cell"){
+ var item = _this._lastEndPoint[type];
+ if(f.cell != g.layout.cells[item.col + colStep] || f.rowIndex != item.row + rowStep){
+ ks[type] = 0;
+ return;
+ }
+ }
+ //If selecting is not started, start it
+ _this._startSelect(type, _this._lastAnchorPoint[type], true, false, true);
+ _this._highlight(type, _this._lastEndPoint[type], _this._toSelect);
+ ks[type] = duringKeyboardSelect;
+ }
+ //Highlight to the new end point.
+ var newEnd = createNewEnd(type, rowStep, colStep, evt);
+ if(_this._isValid(type, newEnd, g)){
+ _this._highlight(type, newEnd, _this._toSelect);
+ }
+ _stopEvent(evt);
+ }
+ },
+ onkeydown = function(type, getTarget, evt, isBubble){
+ if(isBubble && _this.selectEnabled() && _this._config[type] != DISABLED){
+ switch(evt.keyCode){
+ case dk.SPACE:
+ //Keyboard single point selection is SPACE.
+ _this._startSelect(type, getTarget(), evt.ctrlKey, evt.shiftKey);
+ _this._endSelect(type);
+ break;
+ case dk.SHIFT:
+ //Keyboard swipe selection starts with SHIFT.
+ if(_this._config[type] == MULTI && _this._isValid(type, _this._lastAnchorPoint[type], g)){
+ //End last selection if any.
+ _this._endSelect(type);
+ _this._keyboardSelect[type] = keyboardSelectReady;
+ _this._usingKeyboard = true;
+ }
+ }
+ }
+ },
+ onkeyup = function(type, evt, isBubble){
+ if(isBubble && evt.keyCode == dojo.keys.SHIFT && _this._keyboardSelect[type]){
+ _this._endSelect(type);
+ _this._keyboardSelect[type] = 0;
+ }
+ };
+ //TODO: this area "rowHeader" should be put outside, same level as header/content.
+ if(g.views.views[0] instanceof dojox.grid._RowSelector){
+ this._lastFocusedRowBarIdx = 0;
+ f.addArea({
+ name:"rowHeader",
+ onFocus: function(evt, step){
+ var view = g.views.views[0];
+ if(view instanceof dojox.grid._RowSelector){
+ var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
+ if(rowBarNode){
+ dojo.toggleClass(rowBarNode, f.focusClass, false);
+ }
+ //evt might not be real event, it may be a mock object instead.
+ if(evt && "rowIndex" in evt){
+ if(evt.rowIndex >= 0){
+ _this._lastFocusedRowBarIdx = evt.rowIndex;
+ }else if(!_this._lastFocusedRowBarIdx){
+ _this._lastFocusedRowBarIdx = 0;
+ }
+ }
+ rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
+ if(rowBarNode){
+ dijit.focus(rowBarNode);
+ dojo.toggleClass(rowBarNode, f.focusClass, true);
+ }
+ f.rowIndex = _this._lastFocusedRowBarIdx;
+ _stopEvent(evt);
+ return true;
+ }
+ return false;
+ },
+ onBlur: function(evt, step){
+ var view = g.views.views[0];
+ if(view instanceof dojox.grid._RowSelector){
+ var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
+ dojo.toggleClass(rowBarNode, f.focusClass, false);
+ _stopEvent(evt);
+ }
+ return true;
+ },
+ onMove: function(rowStep, colStep, evt){
+ var view = g.views.views[0];
+ if(rowStep && view instanceof dojox.grid._RowSelector){
+ var next = _this._lastFocusedRowBarIdx + rowStep;
+ if(next >= 0 && next < g.rowCount){
+ //TODO: these logic require a better Scroller.
+ _stopEvent(evt);
+ var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
+ dojo.toggleClass(rowBarNode, f.focusClass, false);
+ //If the row is not fetched, fetch it.
+ var sc = g.scroller;
+ var lastPageRow = sc.getLastPageRow(sc.page);
+ var rc = g.rowCount - 1, row = Math.min(rc, next);
+ if(next > lastPageRow){
+ g.setScrollTop(g.scrollTop + sc.findScrollTop(row) - sc.findScrollTop(_this._lastFocusedRowBarIdx));
+ }
+ //Now we have fetched the row.
+ rowBarNode = view.getCellNode(next, 0);
+ dijit.focus(rowBarNode);
+ dojo.toggleClass(rowBarNode, f.focusClass, true);
+ _this._lastFocusedRowBarIdx = next;
+ //If the row is out of view, scroll to it.
+ f.cell = rowBarNode;
+ f.cell.view = view;
+ f.cell.getNode = function(index){
+ return f.cell;
+ };
+ f.rowIndex = _this._lastFocusedRowBarIdx;
+ f.scrollIntoView();
+ f.cell = null;
+ }
+ }
+ }
+ });
+ f.placeArea("rowHeader","before","content");
+ }
+ //Support keyboard selection.
+ f.addArea({
+ name:"cellselect",
+ onMove: dojo.partial(onmove, "cell", function(type, rowStep, colStep, evt){
+ var current = _this._currentPoint[type];
+ return _createItem("cell", current.row + rowStep, current.col + colStep);
+ }),
+ onKeyDown: dojo.partial(onkeydown, "cell", function(){
+ return _createItem("cell", f.rowIndex, f.cell.index);
+ }),
+ onKeyUp: dojo.partial(onkeyup, "cell")
+ });
+ f.placeArea("cellselect","below","content");
+ f.addArea({
+ name:"colselect",
+ onMove: dojo.partial(onmove, "col", function(type, rowStep, colStep, evt){
+ var current = _this._currentPoint[type];
+ return _createItem("col", current.col + colStep);
+ }),
+ onKeyDown: dojo.partial(onkeydown, "col", function(){
+ return _createItem("col", f.getHeaderIndex());
+ }),
+ onKeyUp: dojo.partial(onkeyup, "col")
+ });
+ f.placeArea("colselect","below","header");
+ f.addArea({
+ name:"rowselect",
+ onMove: dojo.partial(onmove, "row", function(type, rowStep, colStep, evt){
+ return _createItem("row", f.rowIndex);
+ }),
+ onKeyDown: dojo.partial(onkeydown, "row", function(){
+ return _createItem("row", f.rowIndex);
+ }),
+ onKeyUp: dojo.partial(onkeyup, "row")
+ });
+ f.placeArea("rowselect","below","rowHeader");
+ },
+ _clearSelection: function(type, reservedItem){
+ // summary:
+ // Clear selection for given type and fire events, but retain the highlight for *reservedItem*,
+ // thus avoid "flashing".
+ // tag:
+ // private
+ // type: String
+ // "row", "col", or "cell
+ // reservedItem: __SelectItem
+ // The item to retain highlight.
+ if(type == "all"){
+ this._clearSelection("cell", reservedItem);
+ this._clearSelection("col", reservedItem);
+ this._clearSelection("row", reservedItem);
+ return;
+ }
+ this._isUsingRowSelector = true;
+ dojo.forEach(this._selected[type], function(item){
+ if(!_isEqual(type, reservedItem, item)){
+ this._highlightSingle(type, false, item);
+ }
+ }, this);
+ this._blurPoint(type, this._currentPoint);
+ this._selecting[type] = false;
+ this._startPoint[type] = this._currentPoint[type] = null;
+ this._selected[type] = [];
+
+ //Have to also deselect default grid selection.
+ if(type == "row" && !this.grid._selectingRange){
+ this._oldDeselectAll.call(this.grid.selection);
+ this.grid.selection._selectedById = {};
+ }
+
+ //Fire events.
+ this.grid.onEndDeselect(type, null, null, this._selected);
+ this.grid.onSelectCleared(type);
+ },
+ _startSelect: function(type, start, extending, isRange, mandatarySelect, toSelect){
+ // summary:
+ // Start selection, setup start point and current point, fire events.
+ // tag:
+ // private
+ // type: String
+ // "row", "col", or "cell"
+ // extending: Boolean
+ // Whether this is a multi selection
+ // isRange: Boolean
+ // Whether this is a range selection (i.e. select from the last end point to this point)
+ // start: __SelectItem
+ // The start point
+ // mandatarySelect: Boolean
+ // If true, toSelect will be same as the original selection status.
+ if(!this._isValid(type, start)){
+ return;
+ }
+ var lastIsSelected = this._isSelected(type, this._lastEndPoint[type]),
+ isSelected = this._isSelected(type, start);
+
+ //If we are modifying the selection using keyboard, retain the old status.
+ this._toSelect = mandatarySelect ? isSelected : !isSelected;
+
+ //If CTRL is not pressed or it's SINGLE mode, this is a brand new selection.
+ if(!extending || (!isSelected && this._config[type] == SINGLE)){
+ this._clearSelection("all", start);
+ this._toSelect = toSelect === undefined ? true : toSelect;
+ }
+
+ this._selecting[type] = true;
+ this._currentPoint[type] = null;
+
+ //We're holding SHIFT while clicking, it's a Click-Range selection.
+ if(isRange && this._lastType == type && lastIsSelected == this._toSelect){
+ if(type === "row"){
+ this._isUsingRowSelector = true;
+ }
+ this._startPoint[type] = this._lastEndPoint[type];
+ this._highlight(type, this._startPoint[type]);
+ this._isUsingRowSelector = false;
+ }else{
+ this._startPoint[type] = start;
+ }
+ //Now start selection
+ this._curType = type;
+ this._fireEvent("start", type);
+ this._isStartFocus = true;
+ this._isUsingRowSelector = true;
+ this._highlight(type, start, this._toSelect);
+ this._isStartFocus = false;
+ },
+ _endSelect: function(type){
+ // summary:
+ // End selection. Keep records, fire events and cleanup status.
+ // tag:
+ // private
+ // type: String
+ // "row", "col", or "cell"
+ if(type === "row"){
+ delete this._isUsingRowSelector;
+ }
+ if(type == "all"){
+ this._endSelect("col");
+ this._endSelect("row");
+ this._endSelect("cell");
+ }else if(this._selecting[type]){
+ this._addToSelected(type);
+ this._lastAnchorPoint[type] = this._startPoint[type];
+ this._lastEndPoint[type] = this._currentPoint[type];
+ if(this._toSelect){
+ this._lastSelectedAnchorPoint[type] = this._lastAnchorPoint[type];
+ this._lastSelectedEndPoint[type] = this._lastEndPoint[type];
+ }
+ this._startPoint[type] = this._currentPoint[type] = null;
+ this._selecting[type] = false;
+ this._lastType = type;
+ this._fireEvent("end", type);
+ }
+ },
+ _fireEvent: function(evtName, type){
+ switch(evtName){
+ case "start":
+ this.grid[this._toSelect ? "onStartSelect" : "onStartDeselect"](type, this._startPoint[type], this._selected);
+ break;
+ case "end":
+ this.grid[this._toSelect ? "onEndSelect" : "onEndDeselect"](type, this._lastAnchorPoint[type], this._lastEndPoint[type], this._selected);
+ break;
+ }
+ },
+ _calcToHighlight: function(type, target, toHighlight, toSelect){
+ // summary:
+ // Calculate what status should *target* have.
+ // If *toSelect* is not provided, this is a no op.
+ // This function is time-critical!!
+ if(toSelect !== undefined){
+ var sltd;
+ if(this._usingKeyboard && !toHighlight){
+ var last = this._isInLastRange(this._lastType, target);
+ if(last){
+ sltd = this._isSelected(type, target);
+ //This 2 cases makes the keyboard swipe selection valid!
+ if(toSelect && sltd){
+ return false;
+ }
+ if(!toSelect && !sltd && this._isInLastRange(this._lastType, target, true)){
+ return true;
+ }
+ }
+ }
+ return toHighlight ? toSelect : (sltd || this._isSelected(type, target));
+ }
+ return toHighlight;
+ },
+ _highlightNode: function(node, toHighlight){
+ // summary:
+ // Do the actual highlight work.
+ if(node){
+ var selectCSSClass = "dojoxGridRowSelected";
+ var selectCellClass = "dojoxGridCellSelected";
+ dojo.toggleClass(node, selectCSSClass, toHighlight);
+ dojo.toggleClass(node, selectCellClass, toHighlight);
+ }
+ },
+ _highlightHeader: function(colIdx, toHighlight){
+ var cells = this.grid.layout.cells;
+ var node = cells[colIdx].getHeaderNode();
+ var selectedClass = "dojoxGridHeaderSelected";
+ dojo.toggleClass(node, selectedClass, toHighlight);
+ },
+ _highlightRowSelector: function(rowIdx, toHighlight){
+ //var t1 = (new Date()).getTime();
+ var rowSelector = this.grid.views.views[0];
+ if(rowSelector instanceof dojox.grid._RowSelector){
+ var node = rowSelector.getRowNode(rowIdx);
+ if(node){
+ var selectedClass = "dojoxGridRowSelectorSelected";
+ dojo.toggleClass(node, selectedClass, toHighlight);
+ }
+ }
+ //console.log((new Date()).getTime() - t1);
+ },
+ _highlightSingle: function(type, toHighlight, target, toSelect, isRefresh){
+ // summary:
+ // Highlight a single item.
+ // This function is time critical!!
+ var _this = this, toHL, g = _this.grid, cells = g.layout.cells;
+ switch(type){
+ case "cell":
+ toHL = this._calcToHighlight(type, target, toHighlight, toSelect);
+ var c = cells[target.col];
+ if(!c.hidden && !c.notselectable){
+ this._highlightNode(target.node || c.getNode(target.row), toHL);
+ }
+ break;
+ case "col":
+ toHL = this._calcToHighlight(type, target, toHighlight, toSelect);
+ this._highlightHeader(target.col, toHL);
+ dojo.query("td[idx='" + target.col + "']", g.domNode).forEach(function(cellNode){
+ var rowNode = cells[target.col].view.content.findRowTarget(cellNode);
+ if(rowNode){
+ var rowIndex = rowNode[dojox.grid.util.rowIndexTag];
+ _this._highlightSingle("cell", toHL, {
+ "row": rowIndex,
+ "col": target.col,
+ "node": cellNode
+ });
+ }
+ });
+ break;
+ case "row":
+ toHL = this._calcToHighlight(type, target, toHighlight, toSelect);
+ this._highlightRowSelector(target.row, toHL);
+ dojo.forEach(cells, function(cell){
+ _this._highlightSingle("cell", toHL, {
+ "row": target.row,
+ "col": cell.index,
+ "node": cell.getNode(target.row)
+ });
+ });
+ //To avoid dead lock
+ this._selectedRowModified = true;
+ if(!isRefresh){
+ g.selection.setSelected(target.row, toHL);
+ }
+ }
+ },
+ _highlight: function(type, target, toSelect){
+ // summary:
+ // Highlight from start point to target.
+ // toSelect: Boolean
+ // Whether we are selecting or deselecting.
+ // This function is time critical!!
+ if(this._selecting[type] && target !== null){
+ var start = this._startPoint[type],
+ current = this._currentPoint[type],
+ _this = this,
+ highlight = function(from, to, toHL){
+ _this._forEach(type, from, to, function(item){
+ _this._highlightSingle(type, toHL, item, toSelect);
+ }, true);
+ };
+ switch(type){
+ case "col": case "row":
+ if(current !== null){
+ if(_inRange(type, target, start, current, true)){
+ //target is between start and current, some selected should be deselected.
+ highlight(current, target, false);
+ }else{
+ if(_inRange(type, start, target, current, true)){
+ //selection has jumped to different direction, all should be deselected.
+ highlight(current, start, false);
+ current = start;
+ }
+ highlight(target, current, true);
+ }
+ }else{
+ //First time select.
+ this._highlightSingle(type, true, target, toSelect);
+ }
+ break;
+ case "cell":
+ if(current !== null){
+ if(_inRange("row", target, start, current, true) ||
+ _inRange("col", target, start, current, true) ||
+ _inRange("row", start, target, current, true) ||
+ _inRange("col", start, target, current, true)){
+ highlight(start, current, false);
+ }
+ }
+ highlight(start, target, true);
+ }
+ this._currentPoint[type] = target;
+ this._focusPoint(type, this._currentPoint);
+ }
+ },
+ _focusPoint: function(type, point){
+ // summary:
+ // Focus the current point, so when you move mouse, the focus indicator follows you.
+ if(!this._isStartFocus){
+ var current = point[type],
+ f = this.grid.focus;
+ if(type == "col"){
+ f._colHeadFocusIdx = current.col;
+ f.focusArea("header");
+ }else if(type == "row"){
+ f.focusArea("rowHeader", {
+ "rowIndex": current.row
+ });
+ }else if(type == "cell"){
+ f.setFocusIndex(current.row, current.col);
+ }
+ }
+ },
+ _blurPoint: function(type, point){
+ // summary:
+ // Blur the current point.
+ var f = this.grid.focus;
+ if(type == "col"){
+ f._blurHeader();
+ }else if(type == "cell"){
+ f._blurContent();
+ }
+ },
+ _addToSelected: function(type){
+ // summary:
+ // Record the selected items.
+ var toSelect = this._toSelect, _this = this,
+ toAdd = [], toRemove = [],
+ start = this._startPoint[type],
+ end = this._currentPoint[type];
+ if(this._usingKeyboard){
+ //If using keyboard, selection will be ended after every move. But we have to remember the original selection status,
+ //so as to return to correct status when we shrink the selection region.
+ this._forEach(type, this._lastAnchorPoint[type], this._lastEndPoint[type], function(item){
+ //If the original selected item is not in current range, change its status.
+ if(!_inRange(type, item, start, end)){
+ (toSelect ? toRemove : toAdd).push(item);
+ }
+ });
+ }
+ this._forEach(type, start, end, function(item){
+ var isSelected = _this._isSelected(type, item);
+ if(toSelect && !isSelected){
+ //Add new selected items
+ toAdd.push(item);
+ }else if(!toSelect){
+ //Remove deselected items.
+ toRemove.push(item);
+ }
+ });
+ this._add(type, toAdd);
+ this._remove(type, toRemove);
+
+ // have to keep record in original grid selection
+ dojo.forEach(this._selected.row, function(item){
+ if(item.except.length > 0){
+ //to avoid dead lock
+ this._selectedRowModified = true;
+ this.grid.selection.setSelected(item.row, false);
+ }
+ }, this);
+ },
+ _forEach: function(type, start, end, func, halfClose){
+ // summary:
+ // Go through items from *start* point to *end* point.
+ // This function is time critical!!
+ if(!this._isValid(type, start, true) || !this._isValid(type, end, true)){
+ return;
+ }
+ switch(type){
+ case "col": case "row":
+ start = start[type];
+ end = end[type];
+ var dir = end > start ? 1 : -1;
+ if(!halfClose){
+ end += dir;
+ }
+ for(; start != end; start += dir){
+ func(_createItem(type, start));
+ }
+ break;
+ case "cell":
+ var colDir = end.col > start.col ? 1 : -1,
+ rowDir = end.row > start.row ? 1 : -1;
+ for(var i = start.row, p = end.row + rowDir; i != p; i += rowDir){
+ for(var j = start.col, q = end.col + colDir; j != q; j += colDir){
+ func(_createItem(type, i, j));
+ }
+ }
+ }
+ },
+ _makeupForExceptions: function(type, newCellItems){
+ // summary:
+ // When new cells is selected, maybe they will fill in the "holes" in selected rows and columns.
+ var makedUps = [];
+ dojo.forEach(this._selected[type], function(v1){
+ dojo.forEach(newCellItems, function(v2){
+ if(v1[type] == v2[type]){
+ var pos = dojo.indexOf(v1.except, v2[_theOther[type]]);
+ if(pos >= 0){
+ v1.except.splice(pos, 1);
+ }
+ makedUps.push(v2);
+ }
+ });
+ });
+ return makedUps;
+ },
+ _makeupForCells: function(type, newItems){
+ // summary:
+ // When some rows/cols are selected, maybe they can cover some of the selected cells,
+ // and fill some of the "holes" in the selected cols/rows.
+ var toRemove = [];
+ dojo.forEach(this._selected.cell, function(v1){
+ dojo.some(newItems, function(v2){
+ if(v1[type] == v2[type]){
+ toRemove.push(v1);
+ return true;
+ }
+ return false;
+ });
+ });
+ this._remove("cell", toRemove);
+ dojo.forEach(this._selected[_theOther[type]], function(v1){
+ dojo.forEach(newItems, function(v2){
+ var pos = dojo.indexOf(v1.except, v2[type]);
+ if(pos >= 0){
+ v1.except.splice(pos, 1);
+ }
+ });
+ });
+ },
+ _addException: function(type, items){
+ // summary:
+ // If some rows/cols are deselected, maybe they have created "holes" in selected cols/rows.
+ dojo.forEach(this._selected[type], function(v1){
+ dojo.forEach(items, function(v2){
+ v1.except.push(v2[_theOther[type]]);
+ });
+ });
+ },
+ _addCellException: function(type, items){
+ // summary:
+ // If some cells are deselected, maybe they have created "holes" in selected rows/cols.
+ dojo.forEach(this._selected[type], function(v1){
+ dojo.forEach(items, function(v2){
+ if(v1[type] == v2[type]){
+ v1.except.push(v2[_theOther[type]]);
+ }
+ });
+ });
+ },
+ _add: function(type, items){
+ // summary:
+ // Add to the selection record.
+ var cells = this.grid.layout.cells;
+ if(type == "cell"){
+ var colMakedup = this._makeupForExceptions("col", items);
+ var rowMakedup = this._makeupForExceptions("row", items);
+ //Step over hidden columns.
+ items = dojo.filter(items, function(item){
+ return dojo.indexOf(colMakedup, item) < 0 && dojo.indexOf(rowMakedup, item) < 0 &&
+ !cells[item.col].hidden && !cells[item.col].notselectable;
+ });
+ }else{
+ if(type == "col"){
+ //Step over hidden columns.
+ items = dojo.filter(items, function(item){
+ return !cells[item.col].hidden && !cells[item.col].notselectable;
+ });
+ }
+ this._makeupForCells(type, items);
+ this._selected[type] = dojo.filter(this._selected[type], function(v){
+ return dojo.every(items, function(item){
+ return v[type] !== item[type];
+ });
+ });
+ }
+ if(type != "col" && this.grid._hasIdentity){
+ dojo.forEach(items, function(item){
+ var record = this.grid._by_idx[item.row];
+ if(record){
+ item.id = record.idty;
+ }
+ }, this);
+ }
+ this._selected[type] = this._selected[type].concat(items);
+ },
+ _remove: function(type, items){
+ // summary:
+ // Remove from the selection record.
+ var comp = dojo.partial(_isEqual, type);
+ this._selected[type] = dojo.filter(this._selected[type], function(v1){
+ return !dojo.some(items, function(v2){
+ return comp(v1, v2);
+ });
+ });
+ if(type == "cell"){
+ this._addCellException("col", items);
+ this._addCellException("row", items);
+ }else{
+ this._addException(_theOther[type], items);
+ }
+ },
+ _isCellNotInExcept: function(type, item){
+ // summary:
+ // Return true only when a cell is covered by selected row/col, and its not a "hole".
+ var attr = item[type], corres = item[_theOther[type]];
+ return dojo.some(this._selected[type], function(v){
+ return v[type] == attr && dojo.indexOf(v.except, corres) < 0;
+ });
+ },
+ _isSelected: function(type, item){
+ // summary:
+ // Return true when the item is selected. (or logically selected, i.e, covered by a row/col).
+ if(!item){ return false; }
+ var res = dojo.some(this._selected[type], function(v){
+ var ret = _isEqual(type, item, v);
+ if(ret && type !== "cell"){
+ return v.except.length === 0;
+ }
+ return ret;
+ });
+ if(!res && type === "cell"){
+ res = (this._isCellNotInExcept("col", item) || this._isCellNotInExcept("row", item));
+ if(type === "cell"){
+ res = res && !this.grid.layout.cells[item.col].notselectable;
+ }
+ }
+ return res;
+ },
+ _isInLastRange: function(type, item, isSelected){
+ // summary:
+ // Return true only when the item is in the last seletion/deseletion range.
+ var start = this[isSelected ? "_lastSelectedAnchorPoint" : "_lastAnchorPoint"][type],
+ end = this[isSelected ? "_lastSelectedEndPoint" : "_lastEndPoint"][type];
+ if(!item || !start || !end){ return false; }
+ return _inRange(type, item, start, end);
+ },
+ _isValid: function(type, item, allowNotSelectable){
+ // summary:
+ // Check whether the item is a valid __SelectItem for the given type.
+ if(!item){ return false; }
+ try{
+ var g = this.grid, index = item[type];
+ switch(type){
+ case "col":
+ return index >= 0 && index < g.layout.cells.length && dojo.isArray(item.except) &&
+ (allowNotSelectable || !g.layout.cells[index].notselectable);
+ case "row":
+ return index >= 0 && index < g.rowCount && dojo.isArray(item.except);
+ case "cell":
+ return item.col >= 0 && item.col < g.layout.cells.length &&
+ item.row >= 0 && item.row < g.rowCount &&
+ (allowNotSelectable || !g.layout.cells[item.col].notselectable);
+ }
+ }catch(e){}
+ return false;
+ }
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Selector/*name:'selector'*/, {
+ "dependency": ["autoScroll"]
+});
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/Selector.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/Selector.xd.js
new file mode 100644
index 0000000..694c36f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/Selector.xd.js
@@ -0,0 +1,1463 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.Selector"],
+["require", "dojox.grid.enhanced._Plugin"],
+["require", "dojox.grid.enhanced.plugins.AutoScroll"],
+["require", "dojox.grid.cells._base"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.Selector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.Selector"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.Selector");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid.enhanced.plugins.AutoScroll");
+dojo.require("dojox.grid.cells._base");
+
+(function(){
+/*=====
+dojo.declare("__SelectItem", null,{
+ // summary:
+ // An abstract representation of an item.
+});
+dojo.declare("__SelectCellItem", __SelectItem,{
+ // summary:
+ // An abstract representation of a cell.
+
+ // row: Integer
+ // Row index of this cell
+ row: 0,
+
+ // col: Integer
+ // Column index of this cell
+ col: 0
+});
+dojo.declare("__SelectRowItem", __SelectItem,{
+ // summary:
+ // An abstract representation of a row.
+
+ // row: Integer
+ // Row index of this row
+ row: 0,
+
+ // except: Integer[]
+ // An array of column indexes of all the unselected cells in this row.
+ except: []
+});
+dojo.declare("__SelectColItem", __SelectItem,{
+ // summary:
+ // An abstract representation of a column.
+
+ // col: Integer
+ // Column index of this column
+ col: 0,
+
+ // except: Integer[]
+ // An array of row indexes of all the unselected cells in this column.
+ except: []
+});
+=====*/
+
+var DISABLED = 0, SINGLE = 1, MULTI = 2,
+ _theOther = { col: "row", row: "col" },
+ _inRange = function(type, value, start, end, halfClose){
+ if(type !== "cell"){
+ value = value[type];
+ start = start[type];
+ end = end[type];
+ if(typeof value !== "number" || typeof start !== "number" || typeof end !== "number"){
+ return false;
+ }
+ return halfClose ? ((value >= start && value < end) || (value > end && value <= start))
+ : ((value >= start && value <= end) || (value >= end && value <= start));
+ }else{
+ return _inRange("col", value, start, end, halfClose) && _inRange("row", value, start, end, halfClose);
+ }
+ },
+ _isEqual = function(type, v1, v2){
+ try{
+ if(v1 && v2){
+ switch(type){
+ case "col": case "row":
+ return v1[type] == v2[type] && typeof v1[type] == "number" &&
+ !(_theOther[type] in v1) && !(_theOther[type] in v2);
+ case "cell":
+ return v1.col == v2.col && v1.row == v2.row && typeof v1.col == "number" && typeof v1.row == "number";
+ }
+ }
+ }catch(e){}
+ return false;
+ },
+ _stopEvent = function(evt){
+ try{
+ if(evt && evt.preventDefault){
+ dojo.stopEvent(evt);
+ }
+ }catch(e){}
+ },
+ _createItem = function(type, rowIndex, colIndex){
+ switch(type){
+ case "col":
+ return {
+ "col": typeof colIndex == "undefined" ? rowIndex : colIndex,
+ "except": []
+ };
+ case "row":
+ return {
+ "row": rowIndex,
+ "except": []
+ };
+ case "cell":
+ return {
+ "row": rowIndex,
+ "col": colIndex
+ };
+ }
+ return null;
+ };
+dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin, {
+ // summary:
+ // Provides standard extended selection for grid.
+ // Supports mouse/keyboard selection, multi-selection, and de-selection.
+ // Acceptable plugin parameters:
+ // The whole plugin parameter object is a config object passed to the setupConfig function.
+ //
+ // Acceptable cell parameters defined in layout:
+ // 1. notselectable: boolean
+ // Whether this column is (and all the cells in it are) selectable.
+
+ // name: String
+ // plugin name
+ name: "selector",
+/*
+ // _config: null,
+ // _enabled: true,
+ // _selecting: {
+ // row: false,
+ // col: false,
+ // cell: false
+ // },
+ // _selected: {
+ // row: [],
+ // col: [],
+ // cell: []
+ // },
+ // _startPoint: {},
+ // _currentPoint: {},
+ // _lastAnchorPoint: {},
+ // _lastEndPoint: {},
+ // _lastSelectedAnchorPoint: {},
+ // _lastSelectedEndPoint: {},
+ // _keyboardSelect: {
+ // row: 0,
+ // col: 0,
+ // cell: 0
+ // },
+ // _curType: null,
+ // _lastType: null,
+ // _usingKeyboard: false,
+ // _toSelect: true,
+*/
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ this._config = {
+ row: MULTI,
+ col: MULTI,
+ cell: MULTI
+ };
+ this.setupConfig(args);
+ if(grid.selectionMode === "single"){
+ this._config.row = SINGLE;
+ }
+ this._enabled = true;
+ this._selecting = {};
+ this._selected = {
+ "col": [],
+ "row": [],
+ "cell": []
+ };
+ this._startPoint = {};
+ this._currentPoint = {};
+ this._lastAnchorPoint = {};
+ this._lastEndPoint = {};
+ this._lastSelectedAnchorPoint = {};
+ this._lastSelectedEndPoint = {};
+ this._keyboardSelect = {};
+ this._lastType = null;
+ this._selectedRowModified = {};
+ this._hacks();
+ this._initEvents();
+ this._initAreas();
+ this._mixinGrid();
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ },
+ //------------public--------------------
+ setupConfig: function(config){
+ // summary:
+ // Set selection mode for row/col/cell.
+ // config: Object
+ // An object with the following structure (all properties are optional):
+ // {
+ // //Default is "multi", all other values are same as "multi".
+ // row: false|"disabled"|"single",
+ // col: false|"disabled"|"single",
+ // cell: false|"disabled"|"single"
+ // }
+ if(!config || !dojo.isObject(config)){
+ return;
+ }
+ var types = ["row", "col", "cell"];
+ for(var type in config){
+ if(dojo.indexOf(types, type) >= 0){
+ if(!config[type] || config[type] == "disabled"){
+ this._config[type] = DISABLED;
+ }else if(config[type] == "single"){
+ this._config[type] = SINGLE;
+ }else{
+ this._config[type] = MULTI;
+ }
+ }
+ }
+
+ //Have to set mode to default grid selection.
+ var mode = ["none","single","extended"][this._config.row];
+ this.grid.selection.setMode(mode);
+ },
+ isSelected: function(type, rowIndex, colIndex){
+ // summary:
+ // Check whether a location (a cell, a column or a row) is selected.
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // rowIndex: Integer
+ // If type is "row" or "cell", this is the row index.
+ // If type if "col", this is the column index.
+ // colIndex: Integer?
+ // Only valid when type is "cell"
+ // return: Boolean
+ // true if selected, false if not. If cell is covered by a selected column, it's selected.
+ return this._isSelected(type, _createItem(type, rowIndex, colIndex));
+ },
+ toggleSelect: function(type, rowIndex, colIndex){
+ this._startSelect(type, _createItem(type, rowIndex, colIndex), this._config[type] === MULTI, false);
+ this._endSelect(type);
+ },
+ select: function(type, rowIndex, colIndex){
+ // summary:
+ // Select a location (a cell, a column or a row).
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // rowIndex: Integer
+ // If type is "row" or "cell", this is the row index.
+ // If type if "col", this is the column index.
+ // colIndex: Integer?
+ // Only valid when type is "cell"
+ if(!this.isSelected(type, rowIndex, colIndex)){
+ this.toggleSelect(type, rowIndex, colIndex);
+ }
+ },
+ deselect: function(type, rowIndex, colIndex){
+ if(this.isSelected(type, rowIndex, colIndex)){
+ this.toggleSelect(type, rowIndex, colIndex);
+ }
+ },
+ selectRange: function(type, start, end, toSelect){
+ // summary:
+ // Select a continuous range (a block of cells, a set of continuous columns or rows)
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // start: Integer | Object
+ // If type is "row" or "col", this is the index of the starting row or column.
+ // If type if "cell", this is the left-top cell of the range.
+ // end: Integer | Object
+ // If type is "row" or "col", this is the index of the ending row or column.
+ // If type if "cell", this is the right-bottom cell of the range.
+ this.grid._selectingRange = true;
+ var startPoint = type == "cell" ? _createItem(type, start.row, start.col) : _createItem(type, start),
+ endPoint = type == "cell" ? _createItem(type, end.row, end.col) : _createItem(type, end);
+ this._startSelect(type, startPoint, false, false, false, toSelect);
+ this._highlight(type, endPoint, toSelect === undefined ? true : toSelect);
+ this._endSelect(type);
+ this.grid._selectingRange = false;
+ },
+ clear: function(type){
+ // summary:
+ // Clear all selections.
+ // tag:
+ // public
+ // type: String?
+ // "row" or "col" or "cell". If omitted, clear all.
+ this._clearSelection(type || "all");
+ },
+ isSelecting: function(type){
+ // summary:
+ // Check whether the user is currently selecting something.
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // return: Boolean
+ // true if is selection, false otherwise.
+ if(typeof type == "undefined"){
+ return this._selecting.col || this._selecting.row || this._selecting.cell;
+ }
+ return this._selecting[type];
+ },
+ selectEnabled: function(toEnable){
+ // summary:
+ // Turn on/off this selection functionality if *toEnable* is provided.
+ // Check whether this selection functionality is enabled if nothing is passed in.
+ // tag:
+ // public
+ // toEnable: Boolean?
+ // To enable or not. Optional.
+ // return: Boolean | undefined
+ // Enabled or not.
+ if(typeof toEnable != "undefined" && !this.isSelecting()){
+ this._enabled = !!toEnable;
+ }
+ return this._enabled;
+ },
+ getSelected: function(type, includeExceptions){
+ // summary:
+ // Get an array of selected locations.
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // includeExceptions: Boolean
+ // Only meaningful for rows/columns. If true, all selected rows/cols, even they are partly selected, are all returned.
+ // return: __SelectItem[]
+ switch(type){
+ case "cell":
+ return dojo.map(this._selected[type], function(item){ return item; });
+ case "col": case "row":
+ return dojo.map(includeExceptions ? this._selected[type]
+ : dojo.filter(this._selected[type], function(item){
+ return item.except.length === 0;
+ }), function(item){
+ return includeExceptions ? item : item[type];
+ });
+ }
+ return [];
+ },
+ getSelectedCount: function(type, includeExceptions){
+ // summary:
+ // Get the number of selected items.
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // includeExceptions: Boolean
+ // Only meaningful for rows/columns. If true, all selected rows/cols, even they are partly selected, are all returned.
+ // return: Integer
+ // The number of selected items.
+ switch(type){
+ case "cell":
+ return this._selected[type].length;
+ case "col": case "row":
+ return (includeExceptions ? this._selected[type]
+ : dojo.filter(this._selected[type], function(item){
+ return item.except.length === 0;
+ })).length;
+ }
+ return 0;
+ },
+ getSelectedType: function(){
+ // summary:
+ // Get the type of selected items.
+ // tag:
+ // public
+ // return: String
+ // "row" or "col" or "cell", or any mix of these (separator is | ).
+ var s = this._selected;
+ return ["", "cell", "row", "row|cell",
+ "col", "col|cell", "col|row", "col|row|cell"
+ ][(!!s.cell.length) | (!!s.row.length << 1) | (!!s.col.length << 2)];
+ },
+ getLastSelectedRange: function(type){
+ // summary:
+ // Get last selected range of the given type.
+ // tag:
+ // public
+ // return: Object
+ // {start: __SelectItem, end: __SelectItem}
+ // return null if nothing is selected.
+ return this._lastAnchorPoint[type] ? {
+ "start": this._lastAnchorPoint[type],
+ "end": this._lastEndPoint[type]
+ } : null;
+ },
+
+ //--------------------------private----------------------------
+ _hacks: function(){
+ // summary:
+ // Complete the event system of grid, hack some grid functions to prevent default behavior.
+ var g = this.grid;
+ var doContentMouseUp = function(e){
+ if(e.cellNode){
+ g.onMouseUp(e);
+ }
+ g.onMouseUpRow(e);
+ };
+ var mouseUp = dojo.hitch(g, "onMouseUp");
+ var mouseDown = dojo.hitch(g, "onMouseDown");
+ var doRowSelectorFocus = function(e){
+ e.cellNode.style.border = "solid 1px";
+ };
+ dojo.forEach(g.views.views, function(view){
+ view.content.domouseup = doContentMouseUp;
+ view.header.domouseup = mouseUp;
+ if(view.declaredClass == "dojox.grid._RowSelector"){
+ view.domousedown = mouseDown;
+ view.domouseup = mouseUp;
+ view.dofocus = doRowSelectorFocus;
+ }
+ });
+ //Disable default selection.
+ g.selection.clickSelect = function(){};
+
+ this._oldDeselectAll = g.selection.deselectAll;
+ var _this = this;
+ g.selection.selectRange = function(from, to){
+ _this.selectRange("row", from, to, true);
+ if(g.selection.preserver){
+ g.selection.preserver._updateMapping(true, true, false, from, to);
+ }
+ g.selection.onChanged();
+ };
+ g.selection.deselectRange = function(from, to){
+ _this.selectRange("row", from, to, false);
+ if(g.selection.preserver){
+ g.selection.preserver._updateMapping(true, false, false, from, to);
+ }
+ g.selection.onChanged();
+ };
+ g.selection.deselectAll = function(){
+ g._selectingRange = true;
+ _this._oldDeselectAll.apply(g.selection, arguments);
+ _this._clearSelection("row");
+ g._selectingRange = false;
+ if(g.selection.preserver){
+ g.selection.preserver._updateMapping(true, false, true);
+ }
+ g.selection.onChanged();
+ };
+
+ var rowSelector = g.views.views[0];
+ //The default function re-write the whole className, so can not insert any other classes.
+ if(rowSelector instanceof dojox.grid._RowSelector){
+ rowSelector.doStyleRowNode = function(inRowIndex, inRowNode){
+ dojo.removeClass(inRowNode, "dojoxGridRow");
+ dojo.addClass(inRowNode, "dojoxGridRowbar");
+ dojo.addClass(inRowNode, "dojoxGridNonNormalizedCell");
+ dojo.toggleClass(inRowNode, "dojoxGridRowbarOver", g.rows.isOver(inRowIndex));
+ dojo.toggleClass(inRowNode, "dojoxGridRowbarSelected", !!g.selection.isSelected(inRowIndex));
+ };
+ }
+ this.connect(g, "updateRow", function(rowIndex){
+ dojo.forEach(g.layout.cells, function(cell){
+ if(this.isSelected("cell", rowIndex, cell.index)){
+ this._highlightNode(cell.getNode(rowIndex), true);
+ }
+ }, this);
+ });
+ },
+ _mixinGrid: function(){
+ // summary:
+ // Expose events to grid.
+ var g = this.grid;
+ g.setupSelectorConfig = dojo.hitch(this, this.setupConfig);
+ g.onStartSelect = function(){};
+ g.onEndSelect = function(){};
+ g.onStartDeselect = function(){};
+ g.onEndDeselect = function(){};
+ g.onSelectCleared = function(){};
+ },
+ _initEvents: function(){
+ // summary:
+ // Connect events, create event handlers.
+ var g = this.grid,
+ _this = this,
+ dp = dojo.partial,
+ starter = function(type, e){
+ if(type === "row"){
+ _this._isUsingRowSelector = true;
+ }
+ //only left mouse button can select.
+ if(_this.selectEnabled() && _this._config[type] && e.button != 2){
+ if(_this._keyboardSelect.col || _this._keyboardSelect.row || _this._keyboardSelect.cell){
+ _this._endSelect("all");
+ _this._keyboardSelect.col = _this._keyboardSelect.row = _this._keyboardSelect.cell = 0;
+ }
+ if(_this._usingKeyboard){
+ _this._usingKeyboard = false;
+ }
+ var target = _createItem(type, e.rowIndex, e.cell && e.cell.index);
+ _this._startSelect(type, target, e.ctrlKey, e.shiftKey);
+ }
+ },
+ ender = dojo.hitch(this, "_endSelect");
+ this.connect(g, "onHeaderCellMouseDown", dp(starter, "col"));
+ this.connect(g, "onHeaderCellMouseUp", dp(ender, "col"));
+
+ this.connect(g, "onRowSelectorMouseDown", dp(starter, "row"));
+ this.connect(g, "onRowSelectorMouseUp", dp(ender, "row"));
+
+ this.connect(g, "onCellMouseDown", function(e){
+ if(e.cell && e.cell.isRowSelector){ return; }
+ if(g.singleClickEdit){
+ _this._singleClickEdit = true;
+ g.singleClickEdit = false;
+ }
+ starter(_this._config["cell"] == DISABLED ? "row" : "cell", e);
+ });
+ this.connect(g, "onCellMouseUp", function(e){
+ if(_this._singleClickEdit){
+ delete _this._singleClickEdit;
+ g.singleClickEdit = true;
+ }
+ ender("all", e);
+ });
+
+ this.connect(g, "onCellMouseOver", function(e){
+ if(_this._curType != "row" && _this._selecting[_this._curType] && _this._config[_this._curType] == MULTI){
+ _this._highlight("col", _createItem("col", e.cell.index), _this._toSelect);
+ if(!_this._keyboardSelect.cell){
+ _this._highlight("cell", _createItem("cell", e.rowIndex, e.cell.index), _this._toSelect);
+ }
+ }
+ });
+ this.connect(g, "onHeaderCellMouseOver", function(e){
+ if(_this._selecting.col && _this._config.col == MULTI){
+ _this._highlight("col", _createItem("col", e.cell.index), _this._toSelect);
+ }
+ });
+ this.connect(g, "onRowMouseOver", function(e){
+ if(_this._selecting.row && _this._config.row == MULTI){
+ _this._highlight("row", _createItem("row", e.rowIndex), _this._toSelect);
+ }
+ });
+
+ //When row order has changed in a unpredictable way (sorted or filtered), map the new rowindex.
+ this.connect(g, "onSelectedById", "_onSelectedById");
+
+ //When the grid refreshes, all those selected should still appear selected.
+ this.connect(g, "_onFetchComplete", function(){
+ //console.debug("refresh after buildPage:", g._notRefreshSelection);
+ if(!g._notRefreshSelection){
+ this._refreshSelected(true);
+ }
+ });
+
+ //Small scroll might not refresh the grid.
+ this.connect(g.scroller, "buildPage", function(){
+ //console.debug("refresh after buildPage:", g._notRefreshSelection);
+ if(!g._notRefreshSelection){
+ this._refreshSelected(true);
+ }
+ });
+
+ //Whenever the mouse is up, end selecting.
+ this.connect(dojo.doc, "onmouseup", dp(ender, "all"));
+
+ //If autoscroll is enabled, connect to it.
+ this.connect(g, "onEndAutoScroll", function(isVertical, isForward, view, target){
+ var selectCell = _this._selecting.cell,
+ type, current, dir = isForward ? 1 : -1;
+ if(isVertical && (selectCell || _this._selecting.row)){
+ type = selectCell ? "cell" : "row";
+ current = _this._currentPoint[type];
+ _this._highlight(type, _createItem(type, current.row + dir, current.col), _this._toSelect);
+ }else if(!isVertical && (selectCell || _this._selecting.col)){
+ type = selectCell ? "cell" : "col";
+ current = _this._currentPoint[type];
+ _this._highlight(type, _createItem(type, current.row, target), _this._toSelect);
+ }
+ });
+ //If the grid is changed, selection should be consistent.
+ this.subscribe("dojox/grid/rearrange/move/" + g.id, "_onInternalRearrange");
+ this.subscribe("dojox/grid/rearrange/copy/" + g.id, "_onInternalRearrange");
+ this.subscribe("dojox/grid/rearrange/change/" + g.id, "_onExternalChange");
+ this.subscribe("dojox/grid/rearrange/insert/" + g.id, "_onExternalChange");
+ this.subscribe("dojox/grid/rearrange/remove/" + g.id, "clear");
+
+ //have to also select when the grid's default select is used.
+ this.connect(g, "onSelected", function(rowIndex){
+ if(this._selectedRowModified && this._isUsingRowSelector){
+ delete this._selectedRowModified;
+ }else if(!this.grid._selectingRange){
+ this.select("row", rowIndex);
+ }
+ });
+ this.connect(g, "onDeselected", function(rowIndex){
+ if(this._selectedRowModified && this._isUsingRowSelector){
+ delete this._selectedRowModified;
+ }else if(!this.grid._selectingRange){
+ this.deselect("row", rowIndex);
+ }
+ });
+ },
+ _onSelectedById: function(id, newIndex, isSelected){
+ if(this.grid._noInternalMapping){
+ return;
+ }
+ var pointSet = [this._lastAnchorPoint.row, this._lastEndPoint.row,
+ this._lastSelectedAnchorPoint.row, this._lastSelectedEndPoint.row];
+ pointSet = pointSet.concat(this._selected.row);
+ var found = false;
+ dojo.forEach(pointSet, function(item){
+ if(item){
+ if(item.id === id){
+ found = true;
+ item.row = newIndex;
+ }else if(item.row === newIndex && item.id){
+ item.row = -1;
+ }
+ }
+ });
+ if(!found && isSelected){
+ dojo.some(this._selected.row, function(item){
+ if(item && !item.id && !item.except.length){
+ item.id = id;
+ item.row = newIndex;
+ return true;
+ }
+ return false;
+ });
+ }
+ found = false;
+ pointSet = [this._lastAnchorPoint.cell, this._lastEndPoint.cell,
+ this._lastSelectedAnchorPoint.cell, this._lastSelectedEndPoint.cell];
+ pointSet = pointSet.concat(this._selected.cell);
+ dojo.forEach(pointSet, function(item){
+ if(item){
+ if(item.id === id){
+ found = true;
+ item.row = newIndex;
+ }else if(item.row === newIndex && item.id){
+ item.row = -1;
+ }
+ }
+ });
+ },
+ onSetStore: function(){
+ this._clearSelection("all");
+ },
+ _onInternalRearrange: function(type, mapping){
+ try{
+ //The column can not refresh it self!
+ this._refresh("col", false);
+
+ dojo.forEach(this._selected.row, function(item){
+ dojo.forEach(this.grid.layout.cells, function(cell){
+ this._highlightNode(cell.getNode(item.row), false);
+ }, this);
+ }, this);
+ //The rowbar must be cleaned manually
+ dojo.query(".dojoxGridRowSelectorSelected").forEach(function(node){
+ dojo.removeClass(node, "dojoxGridRowSelectorSelected");
+ dojo.removeClass(node, "dojoxGridRowSelectorSelectedUp");
+ dojo.removeClass(node, "dojoxGridRowSelectorSelectedDown");
+ });
+
+ var cleanUp = function(item){
+ if(item){
+ delete item.converted;
+ }
+ },
+ pointSet = [this._lastAnchorPoint[type], this._lastEndPoint[type],
+ this._lastSelectedAnchorPoint[type], this._lastSelectedEndPoint[type]];
+
+ if(type === "cell"){
+ this.selectRange("cell", mapping.to.min, mapping.to.max);
+ var cells = this.grid.layout.cells;
+ dojo.forEach(pointSet, function(item){
+ if(item.converted){ return; }
+ for(var r = mapping.from.min.row, tr = mapping.to.min.row; r <= mapping.from.max.row; ++r, ++tr){
+ for(var c = mapping.from.min.col, tc = mapping.to.min.col; c <= mapping.from.max.col; ++c, ++tc){
+ while(cells[c].hidden){ ++c; }
+ while(cells[tc].hidden){ ++tc; }
+ if(item.row == r && item.col == c){
+ //console.log('mapping found: (', item.row, ",",item.col,") to (", tr, ",", tc,")");
+ item.row = tr;
+ item.col = tc;
+ item.converted = true;
+ return;
+ }
+ }
+ }
+ });
+ }else{
+ pointSet = this._selected.cell.concat(this._selected[type]).concat(pointSet).concat(
+ [this._lastAnchorPoint.cell, this._lastEndPoint.cell,
+ this._lastSelectedAnchorPoint.cell, this._lastSelectedEndPoint.cell]);
+ dojo.forEach(pointSet, function(item){
+ if(item && !item.converted){
+ var from = item[type];
+ if(from in mapping){
+ item[type] = mapping[from];
+ }
+ item.converted = true;
+ }
+ });
+ dojo.forEach(this._selected[_theOther[type]], function(item){
+ for(var i = 0, len = item.except.length; i < len; ++i){
+ var from = item.except[i];
+ if(from in mapping){
+ item.except[i] = mapping[from];
+ }
+ }
+ });
+ }
+
+ dojo.forEach(pointSet, cleanUp);
+
+ this._refreshSelected(true);
+ this._focusPoint(type, this._lastEndPoint);
+ }catch(e){
+ console.warn("Selector._onInternalRearrange() error",e);
+ }
+ },
+ _onExternalChange: function(type, target){
+ var start = type == "cell" ? target.min : target[0],
+ end = type == "cell" ? target.max : target[target.length - 1];
+ this.selectRange(type, start, end);
+ },
+ _refresh: function(type, toHighlight){
+ if(!this._keyboardSelect[type]){
+ dojo.forEach(this._selected[type], function(item){
+ this._highlightSingle(type, toHighlight, item, undefined, true);
+ }, this);
+ }
+ },
+ _refreshSelected: function(){
+ this._refresh("col", true);
+ this._refresh("row", true);
+ this._refresh("cell", true);
+ },
+ _initAreas: function(){
+ var g = this.grid, f = g.focus, _this = this, dk = dojo.keys,
+ keyboardSelectReady = 1, duringKeyboardSelect = 2,
+ onmove = function(type, createNewEnd, rowStep, colStep, evt){
+ //Keyboard swipe selection is SHIFT + Direction Keys.
+ var ks = _this._keyboardSelect;
+ //Tricky, rely on valid status not being 0.
+ if(evt.shiftKey && ks[type]){
+ if(ks[type] === keyboardSelectReady){
+ if(type === "cell"){
+ var item = _this._lastEndPoint[type];
+ if(f.cell != g.layout.cells[item.col + colStep] || f.rowIndex != item.row + rowStep){
+ ks[type] = 0;
+ return;
+ }
+ }
+ //If selecting is not started, start it
+ _this._startSelect(type, _this._lastAnchorPoint[type], true, false, true);
+ _this._highlight(type, _this._lastEndPoint[type], _this._toSelect);
+ ks[type] = duringKeyboardSelect;
+ }
+ //Highlight to the new end point.
+ var newEnd = createNewEnd(type, rowStep, colStep, evt);
+ if(_this._isValid(type, newEnd, g)){
+ _this._highlight(type, newEnd, _this._toSelect);
+ }
+ _stopEvent(evt);
+ }
+ },
+ onkeydown = function(type, getTarget, evt, isBubble){
+ if(isBubble && _this.selectEnabled() && _this._config[type] != DISABLED){
+ switch(evt.keyCode){
+ case dk.SPACE:
+ //Keyboard single point selection is SPACE.
+ _this._startSelect(type, getTarget(), evt.ctrlKey, evt.shiftKey);
+ _this._endSelect(type);
+ break;
+ case dk.SHIFT:
+ //Keyboard swipe selection starts with SHIFT.
+ if(_this._config[type] == MULTI && _this._isValid(type, _this._lastAnchorPoint[type], g)){
+ //End last selection if any.
+ _this._endSelect(type);
+ _this._keyboardSelect[type] = keyboardSelectReady;
+ _this._usingKeyboard = true;
+ }
+ }
+ }
+ },
+ onkeyup = function(type, evt, isBubble){
+ if(isBubble && evt.keyCode == dojo.keys.SHIFT && _this._keyboardSelect[type]){
+ _this._endSelect(type);
+ _this._keyboardSelect[type] = 0;
+ }
+ };
+ //TODO: this area "rowHeader" should be put outside, same level as header/content.
+ if(g.views.views[0] instanceof dojox.grid._RowSelector){
+ this._lastFocusedRowBarIdx = 0;
+ f.addArea({
+ name:"rowHeader",
+ onFocus: function(evt, step){
+ var view = g.views.views[0];
+ if(view instanceof dojox.grid._RowSelector){
+ var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
+ if(rowBarNode){
+ dojo.toggleClass(rowBarNode, f.focusClass, false);
+ }
+ //evt might not be real event, it may be a mock object instead.
+ if(evt && "rowIndex" in evt){
+ if(evt.rowIndex >= 0){
+ _this._lastFocusedRowBarIdx = evt.rowIndex;
+ }else if(!_this._lastFocusedRowBarIdx){
+ _this._lastFocusedRowBarIdx = 0;
+ }
+ }
+ rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
+ if(rowBarNode){
+ dijit.focus(rowBarNode);
+ dojo.toggleClass(rowBarNode, f.focusClass, true);
+ }
+ f.rowIndex = _this._lastFocusedRowBarIdx;
+ _stopEvent(evt);
+ return true;
+ }
+ return false;
+ },
+ onBlur: function(evt, step){
+ var view = g.views.views[0];
+ if(view instanceof dojox.grid._RowSelector){
+ var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
+ dojo.toggleClass(rowBarNode, f.focusClass, false);
+ _stopEvent(evt);
+ }
+ return true;
+ },
+ onMove: function(rowStep, colStep, evt){
+ var view = g.views.views[0];
+ if(rowStep && view instanceof dojox.grid._RowSelector){
+ var next = _this._lastFocusedRowBarIdx + rowStep;
+ if(next >= 0 && next < g.rowCount){
+ //TODO: these logic require a better Scroller.
+ _stopEvent(evt);
+ var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
+ dojo.toggleClass(rowBarNode, f.focusClass, false);
+ //If the row is not fetched, fetch it.
+ var sc = g.scroller;
+ var lastPageRow = sc.getLastPageRow(sc.page);
+ var rc = g.rowCount - 1, row = Math.min(rc, next);
+ if(next > lastPageRow){
+ g.setScrollTop(g.scrollTop + sc.findScrollTop(row) - sc.findScrollTop(_this._lastFocusedRowBarIdx));
+ }
+ //Now we have fetched the row.
+ rowBarNode = view.getCellNode(next, 0);
+ dijit.focus(rowBarNode);
+ dojo.toggleClass(rowBarNode, f.focusClass, true);
+ _this._lastFocusedRowBarIdx = next;
+ //If the row is out of view, scroll to it.
+ f.cell = rowBarNode;
+ f.cell.view = view;
+ f.cell.getNode = function(index){
+ return f.cell;
+ };
+ f.rowIndex = _this._lastFocusedRowBarIdx;
+ f.scrollIntoView();
+ f.cell = null;
+ }
+ }
+ }
+ });
+ f.placeArea("rowHeader","before","content");
+ }
+ //Support keyboard selection.
+ f.addArea({
+ name:"cellselect",
+ onMove: dojo.partial(onmove, "cell", function(type, rowStep, colStep, evt){
+ var current = _this._currentPoint[type];
+ return _createItem("cell", current.row + rowStep, current.col + colStep);
+ }),
+ onKeyDown: dojo.partial(onkeydown, "cell", function(){
+ return _createItem("cell", f.rowIndex, f.cell.index);
+ }),
+ onKeyUp: dojo.partial(onkeyup, "cell")
+ });
+ f.placeArea("cellselect","below","content");
+ f.addArea({
+ name:"colselect",
+ onMove: dojo.partial(onmove, "col", function(type, rowStep, colStep, evt){
+ var current = _this._currentPoint[type];
+ return _createItem("col", current.col + colStep);
+ }),
+ onKeyDown: dojo.partial(onkeydown, "col", function(){
+ return _createItem("col", f.getHeaderIndex());
+ }),
+ onKeyUp: dojo.partial(onkeyup, "col")
+ });
+ f.placeArea("colselect","below","header");
+ f.addArea({
+ name:"rowselect",
+ onMove: dojo.partial(onmove, "row", function(type, rowStep, colStep, evt){
+ return _createItem("row", f.rowIndex);
+ }),
+ onKeyDown: dojo.partial(onkeydown, "row", function(){
+ return _createItem("row", f.rowIndex);
+ }),
+ onKeyUp: dojo.partial(onkeyup, "row")
+ });
+ f.placeArea("rowselect","below","rowHeader");
+ },
+ _clearSelection: function(type, reservedItem){
+ // summary:
+ // Clear selection for given type and fire events, but retain the highlight for *reservedItem*,
+ // thus avoid "flashing".
+ // tag:
+ // private
+ // type: String
+ // "row", "col", or "cell
+ // reservedItem: __SelectItem
+ // The item to retain highlight.
+ if(type == "all"){
+ this._clearSelection("cell", reservedItem);
+ this._clearSelection("col", reservedItem);
+ this._clearSelection("row", reservedItem);
+ return;
+ }
+ this._isUsingRowSelector = true;
+ dojo.forEach(this._selected[type], function(item){
+ if(!_isEqual(type, reservedItem, item)){
+ this._highlightSingle(type, false, item);
+ }
+ }, this);
+ this._blurPoint(type, this._currentPoint);
+ this._selecting[type] = false;
+ this._startPoint[type] = this._currentPoint[type] = null;
+ this._selected[type] = [];
+
+ //Have to also deselect default grid selection.
+ if(type == "row" && !this.grid._selectingRange){
+ this._oldDeselectAll.call(this.grid.selection);
+ this.grid.selection._selectedById = {};
+ }
+
+ //Fire events.
+ this.grid.onEndDeselect(type, null, null, this._selected);
+ this.grid.onSelectCleared(type);
+ },
+ _startSelect: function(type, start, extending, isRange, mandatarySelect, toSelect){
+ // summary:
+ // Start selection, setup start point and current point, fire events.
+ // tag:
+ // private
+ // type: String
+ // "row", "col", or "cell"
+ // extending: Boolean
+ // Whether this is a multi selection
+ // isRange: Boolean
+ // Whether this is a range selection (i.e. select from the last end point to this point)
+ // start: __SelectItem
+ // The start point
+ // mandatarySelect: Boolean
+ // If true, toSelect will be same as the original selection status.
+ if(!this._isValid(type, start)){
+ return;
+ }
+ var lastIsSelected = this._isSelected(type, this._lastEndPoint[type]),
+ isSelected = this._isSelected(type, start);
+
+ //If we are modifying the selection using keyboard, retain the old status.
+ this._toSelect = mandatarySelect ? isSelected : !isSelected;
+
+ //If CTRL is not pressed or it's SINGLE mode, this is a brand new selection.
+ if(!extending || (!isSelected && this._config[type] == SINGLE)){
+ this._clearSelection("all", start);
+ this._toSelect = toSelect === undefined ? true : toSelect;
+ }
+
+ this._selecting[type] = true;
+ this._currentPoint[type] = null;
+
+ //We're holding SHIFT while clicking, it's a Click-Range selection.
+ if(isRange && this._lastType == type && lastIsSelected == this._toSelect){
+ if(type === "row"){
+ this._isUsingRowSelector = true;
+ }
+ this._startPoint[type] = this._lastEndPoint[type];
+ this._highlight(type, this._startPoint[type]);
+ this._isUsingRowSelector = false;
+ }else{
+ this._startPoint[type] = start;
+ }
+ //Now start selection
+ this._curType = type;
+ this._fireEvent("start", type);
+ this._isStartFocus = true;
+ this._isUsingRowSelector = true;
+ this._highlight(type, start, this._toSelect);
+ this._isStartFocus = false;
+ },
+ _endSelect: function(type){
+ // summary:
+ // End selection. Keep records, fire events and cleanup status.
+ // tag:
+ // private
+ // type: String
+ // "row", "col", or "cell"
+ if(type === "row"){
+ delete this._isUsingRowSelector;
+ }
+ if(type == "all"){
+ this._endSelect("col");
+ this._endSelect("row");
+ this._endSelect("cell");
+ }else if(this._selecting[type]){
+ this._addToSelected(type);
+ this._lastAnchorPoint[type] = this._startPoint[type];
+ this._lastEndPoint[type] = this._currentPoint[type];
+ if(this._toSelect){
+ this._lastSelectedAnchorPoint[type] = this._lastAnchorPoint[type];
+ this._lastSelectedEndPoint[type] = this._lastEndPoint[type];
+ }
+ this._startPoint[type] = this._currentPoint[type] = null;
+ this._selecting[type] = false;
+ this._lastType = type;
+ this._fireEvent("end", type);
+ }
+ },
+ _fireEvent: function(evtName, type){
+ switch(evtName){
+ case "start":
+ this.grid[this._toSelect ? "onStartSelect" : "onStartDeselect"](type, this._startPoint[type], this._selected);
+ break;
+ case "end":
+ this.grid[this._toSelect ? "onEndSelect" : "onEndDeselect"](type, this._lastAnchorPoint[type], this._lastEndPoint[type], this._selected);
+ break;
+ }
+ },
+ _calcToHighlight: function(type, target, toHighlight, toSelect){
+ // summary:
+ // Calculate what status should *target* have.
+ // If *toSelect* is not provided, this is a no op.
+ // This function is time-critical!!
+ if(toSelect !== undefined){
+ var sltd;
+ if(this._usingKeyboard && !toHighlight){
+ var last = this._isInLastRange(this._lastType, target);
+ if(last){
+ sltd = this._isSelected(type, target);
+ //This 2 cases makes the keyboard swipe selection valid!
+ if(toSelect && sltd){
+ return false;
+ }
+ if(!toSelect && !sltd && this._isInLastRange(this._lastType, target, true)){
+ return true;
+ }
+ }
+ }
+ return toHighlight ? toSelect : (sltd || this._isSelected(type, target));
+ }
+ return toHighlight;
+ },
+ _highlightNode: function(node, toHighlight){
+ // summary:
+ // Do the actual highlight work.
+ if(node){
+ var selectCSSClass = "dojoxGridRowSelected";
+ var selectCellClass = "dojoxGridCellSelected";
+ dojo.toggleClass(node, selectCSSClass, toHighlight);
+ dojo.toggleClass(node, selectCellClass, toHighlight);
+ }
+ },
+ _highlightHeader: function(colIdx, toHighlight){
+ var cells = this.grid.layout.cells;
+ var node = cells[colIdx].getHeaderNode();
+ var selectedClass = "dojoxGridHeaderSelected";
+ dojo.toggleClass(node, selectedClass, toHighlight);
+ },
+ _highlightRowSelector: function(rowIdx, toHighlight){
+ //var t1 = (new Date()).getTime();
+ var rowSelector = this.grid.views.views[0];
+ if(rowSelector instanceof dojox.grid._RowSelector){
+ var node = rowSelector.getRowNode(rowIdx);
+ if(node){
+ var selectedClass = "dojoxGridRowSelectorSelected";
+ dojo.toggleClass(node, selectedClass, toHighlight);
+ }
+ }
+ //console.log((new Date()).getTime() - t1);
+ },
+ _highlightSingle: function(type, toHighlight, target, toSelect, isRefresh){
+ // summary:
+ // Highlight a single item.
+ // This function is time critical!!
+ var _this = this, toHL, g = _this.grid, cells = g.layout.cells;
+ switch(type){
+ case "cell":
+ toHL = this._calcToHighlight(type, target, toHighlight, toSelect);
+ var c = cells[target.col];
+ if(!c.hidden && !c.notselectable){
+ this._highlightNode(target.node || c.getNode(target.row), toHL);
+ }
+ break;
+ case "col":
+ toHL = this._calcToHighlight(type, target, toHighlight, toSelect);
+ this._highlightHeader(target.col, toHL);
+ dojo.query("td[idx='" + target.col + "']", g.domNode).forEach(function(cellNode){
+ var rowNode = cells[target.col].view.content.findRowTarget(cellNode);
+ if(rowNode){
+ var rowIndex = rowNode[dojox.grid.util.rowIndexTag];
+ _this._highlightSingle("cell", toHL, {
+ "row": rowIndex,
+ "col": target.col,
+ "node": cellNode
+ });
+ }
+ });
+ break;
+ case "row":
+ toHL = this._calcToHighlight(type, target, toHighlight, toSelect);
+ this._highlightRowSelector(target.row, toHL);
+ dojo.forEach(cells, function(cell){
+ _this._highlightSingle("cell", toHL, {
+ "row": target.row,
+ "col": cell.index,
+ "node": cell.getNode(target.row)
+ });
+ });
+ //To avoid dead lock
+ this._selectedRowModified = true;
+ if(!isRefresh){
+ g.selection.setSelected(target.row, toHL);
+ }
+ }
+ },
+ _highlight: function(type, target, toSelect){
+ // summary:
+ // Highlight from start point to target.
+ // toSelect: Boolean
+ // Whether we are selecting or deselecting.
+ // This function is time critical!!
+ if(this._selecting[type] && target !== null){
+ var start = this._startPoint[type],
+ current = this._currentPoint[type],
+ _this = this,
+ highlight = function(from, to, toHL){
+ _this._forEach(type, from, to, function(item){
+ _this._highlightSingle(type, toHL, item, toSelect);
+ }, true);
+ };
+ switch(type){
+ case "col": case "row":
+ if(current !== null){
+ if(_inRange(type, target, start, current, true)){
+ //target is between start and current, some selected should be deselected.
+ highlight(current, target, false);
+ }else{
+ if(_inRange(type, start, target, current, true)){
+ //selection has jumped to different direction, all should be deselected.
+ highlight(current, start, false);
+ current = start;
+ }
+ highlight(target, current, true);
+ }
+ }else{
+ //First time select.
+ this._highlightSingle(type, true, target, toSelect);
+ }
+ break;
+ case "cell":
+ if(current !== null){
+ if(_inRange("row", target, start, current, true) ||
+ _inRange("col", target, start, current, true) ||
+ _inRange("row", start, target, current, true) ||
+ _inRange("col", start, target, current, true)){
+ highlight(start, current, false);
+ }
+ }
+ highlight(start, target, true);
+ }
+ this._currentPoint[type] = target;
+ this._focusPoint(type, this._currentPoint);
+ }
+ },
+ _focusPoint: function(type, point){
+ // summary:
+ // Focus the current point, so when you move mouse, the focus indicator follows you.
+ if(!this._isStartFocus){
+ var current = point[type],
+ f = this.grid.focus;
+ if(type == "col"){
+ f._colHeadFocusIdx = current.col;
+ f.focusArea("header");
+ }else if(type == "row"){
+ f.focusArea("rowHeader", {
+ "rowIndex": current.row
+ });
+ }else if(type == "cell"){
+ f.setFocusIndex(current.row, current.col);
+ }
+ }
+ },
+ _blurPoint: function(type, point){
+ // summary:
+ // Blur the current point.
+ var f = this.grid.focus;
+ if(type == "col"){
+ f._blurHeader();
+ }else if(type == "cell"){
+ f._blurContent();
+ }
+ },
+ _addToSelected: function(type){
+ // summary:
+ // Record the selected items.
+ var toSelect = this._toSelect, _this = this,
+ toAdd = [], toRemove = [],
+ start = this._startPoint[type],
+ end = this._currentPoint[type];
+ if(this._usingKeyboard){
+ //If using keyboard, selection will be ended after every move. But we have to remember the original selection status,
+ //so as to return to correct status when we shrink the selection region.
+ this._forEach(type, this._lastAnchorPoint[type], this._lastEndPoint[type], function(item){
+ //If the original selected item is not in current range, change its status.
+ if(!_inRange(type, item, start, end)){
+ (toSelect ? toRemove : toAdd).push(item);
+ }
+ });
+ }
+ this._forEach(type, start, end, function(item){
+ var isSelected = _this._isSelected(type, item);
+ if(toSelect && !isSelected){
+ //Add new selected items
+ toAdd.push(item);
+ }else if(!toSelect){
+ //Remove deselected items.
+ toRemove.push(item);
+ }
+ });
+ this._add(type, toAdd);
+ this._remove(type, toRemove);
+
+ // have to keep record in original grid selection
+ dojo.forEach(this._selected.row, function(item){
+ if(item.except.length > 0){
+ //to avoid dead lock
+ this._selectedRowModified = true;
+ this.grid.selection.setSelected(item.row, false);
+ }
+ }, this);
+ },
+ _forEach: function(type, start, end, func, halfClose){
+ // summary:
+ // Go through items from *start* point to *end* point.
+ // This function is time critical!!
+ if(!this._isValid(type, start, true) || !this._isValid(type, end, true)){
+ return;
+ }
+ switch(type){
+ case "col": case "row":
+ start = start[type];
+ end = end[type];
+ var dir = end > start ? 1 : -1;
+ if(!halfClose){
+ end += dir;
+ }
+ for(; start != end; start += dir){
+ func(_createItem(type, start));
+ }
+ break;
+ case "cell":
+ var colDir = end.col > start.col ? 1 : -1,
+ rowDir = end.row > start.row ? 1 : -1;
+ for(var i = start.row, p = end.row + rowDir; i != p; i += rowDir){
+ for(var j = start.col, q = end.col + colDir; j != q; j += colDir){
+ func(_createItem(type, i, j));
+ }
+ }
+ }
+ },
+ _makeupForExceptions: function(type, newCellItems){
+ // summary:
+ // When new cells is selected, maybe they will fill in the "holes" in selected rows and columns.
+ var makedUps = [];
+ dojo.forEach(this._selected[type], function(v1){
+ dojo.forEach(newCellItems, function(v2){
+ if(v1[type] == v2[type]){
+ var pos = dojo.indexOf(v1.except, v2[_theOther[type]]);
+ if(pos >= 0){
+ v1.except.splice(pos, 1);
+ }
+ makedUps.push(v2);
+ }
+ });
+ });
+ return makedUps;
+ },
+ _makeupForCells: function(type, newItems){
+ // summary:
+ // When some rows/cols are selected, maybe they can cover some of the selected cells,
+ // and fill some of the "holes" in the selected cols/rows.
+ var toRemove = [];
+ dojo.forEach(this._selected.cell, function(v1){
+ dojo.some(newItems, function(v2){
+ if(v1[type] == v2[type]){
+ toRemove.push(v1);
+ return true;
+ }
+ return false;
+ });
+ });
+ this._remove("cell", toRemove);
+ dojo.forEach(this._selected[_theOther[type]], function(v1){
+ dojo.forEach(newItems, function(v2){
+ var pos = dojo.indexOf(v1.except, v2[type]);
+ if(pos >= 0){
+ v1.except.splice(pos, 1);
+ }
+ });
+ });
+ },
+ _addException: function(type, items){
+ // summary:
+ // If some rows/cols are deselected, maybe they have created "holes" in selected cols/rows.
+ dojo.forEach(this._selected[type], function(v1){
+ dojo.forEach(items, function(v2){
+ v1.except.push(v2[_theOther[type]]);
+ });
+ });
+ },
+ _addCellException: function(type, items){
+ // summary:
+ // If some cells are deselected, maybe they have created "holes" in selected rows/cols.
+ dojo.forEach(this._selected[type], function(v1){
+ dojo.forEach(items, function(v2){
+ if(v1[type] == v2[type]){
+ v1.except.push(v2[_theOther[type]]);
+ }
+ });
+ });
+ },
+ _add: function(type, items){
+ // summary:
+ // Add to the selection record.
+ var cells = this.grid.layout.cells;
+ if(type == "cell"){
+ var colMakedup = this._makeupForExceptions("col", items);
+ var rowMakedup = this._makeupForExceptions("row", items);
+ //Step over hidden columns.
+ items = dojo.filter(items, function(item){
+ return dojo.indexOf(colMakedup, item) < 0 && dojo.indexOf(rowMakedup, item) < 0 &&
+ !cells[item.col].hidden && !cells[item.col].notselectable;
+ });
+ }else{
+ if(type == "col"){
+ //Step over hidden columns.
+ items = dojo.filter(items, function(item){
+ return !cells[item.col].hidden && !cells[item.col].notselectable;
+ });
+ }
+ this._makeupForCells(type, items);
+ this._selected[type] = dojo.filter(this._selected[type], function(v){
+ return dojo.every(items, function(item){
+ return v[type] !== item[type];
+ });
+ });
+ }
+ if(type != "col" && this.grid._hasIdentity){
+ dojo.forEach(items, function(item){
+ var record = this.grid._by_idx[item.row];
+ if(record){
+ item.id = record.idty;
+ }
+ }, this);
+ }
+ this._selected[type] = this._selected[type].concat(items);
+ },
+ _remove: function(type, items){
+ // summary:
+ // Remove from the selection record.
+ var comp = dojo.partial(_isEqual, type);
+ this._selected[type] = dojo.filter(this._selected[type], function(v1){
+ return !dojo.some(items, function(v2){
+ return comp(v1, v2);
+ });
+ });
+ if(type == "cell"){
+ this._addCellException("col", items);
+ this._addCellException("row", items);
+ }else{
+ this._addException(_theOther[type], items);
+ }
+ },
+ _isCellNotInExcept: function(type, item){
+ // summary:
+ // Return true only when a cell is covered by selected row/col, and its not a "hole".
+ var attr = item[type], corres = item[_theOther[type]];
+ return dojo.some(this._selected[type], function(v){
+ return v[type] == attr && dojo.indexOf(v.except, corres) < 0;
+ });
+ },
+ _isSelected: function(type, item){
+ // summary:
+ // Return true when the item is selected. (or logically selected, i.e, covered by a row/col).
+ if(!item){ return false; }
+ var res = dojo.some(this._selected[type], function(v){
+ var ret = _isEqual(type, item, v);
+ if(ret && type !== "cell"){
+ return v.except.length === 0;
+ }
+ return ret;
+ });
+ if(!res && type === "cell"){
+ res = (this._isCellNotInExcept("col", item) || this._isCellNotInExcept("row", item));
+ if(type === "cell"){
+ res = res && !this.grid.layout.cells[item.col].notselectable;
+ }
+ }
+ return res;
+ },
+ _isInLastRange: function(type, item, isSelected){
+ // summary:
+ // Return true only when the item is in the last seletion/deseletion range.
+ var start = this[isSelected ? "_lastSelectedAnchorPoint" : "_lastAnchorPoint"][type],
+ end = this[isSelected ? "_lastSelectedEndPoint" : "_lastEndPoint"][type];
+ if(!item || !start || !end){ return false; }
+ return _inRange(type, item, start, end);
+ },
+ _isValid: function(type, item, allowNotSelectable){
+ // summary:
+ // Check whether the item is a valid __SelectItem for the given type.
+ if(!item){ return false; }
+ try{
+ var g = this.grid, index = item[type];
+ switch(type){
+ case "col":
+ return index >= 0 && index < g.layout.cells.length && dojo.isArray(item.except) &&
+ (allowNotSelectable || !g.layout.cells[index].notselectable);
+ case "row":
+ return index >= 0 && index < g.rowCount && dojo.isArray(item.except);
+ case "cell":
+ return item.col >= 0 && item.col < g.layout.cells.length &&
+ item.row >= 0 && item.row < g.rowCount &&
+ (allowNotSelectable || !g.layout.cells[item.col].notselectable);
+ }
+ }catch(e){}
+ return false;
+ }
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Selector/*name:'selector'*/, {
+ "dependency": ["autoScroll"]
+});
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/_RowMapLayer.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/_RowMapLayer.js
new file mode 100644
index 0000000..6b0347f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/_RowMapLayer.js
@@ -0,0 +1,215 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins._RowMapLayer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins._RowMapLayer"] = true;
+dojo.provide("dojox.grid.enhanced.plugins._RowMapLayer");
+
+dojo.require("dojox.grid.enhanced.plugins._StoreLayer");
+
+(function(){
+var _devideToArrays = function(a){
+ a.sort(function(v1, v2){
+ return v1 - v2;
+ });
+ var arr = [[a[0]]];
+ for(var i = 1, j = 0; i < a.length; ++i){
+ if(a[i] == a[i-1] + 1){
+ arr[j].push(a[i]);
+ }else{
+ arr[++j] = [a[i]];
+ }
+ }
+ return arr;
+},
+hitchIfCan = function(scope, func){
+ return func ? dojo.hitch(scope || dojo.global, func) : function(){};
+};
+
+dojo.declare("dojox.grid.enhanced.plugins._RowMapLayer", dojox.grid.enhanced.plugins._StoreLayer, {
+ tags: ["reorder"],
+ constructor: function(grid){
+ this._map = {};
+ this._revMap = {};
+ this.grid = grid;
+ this._oldOnDelete = grid._onDelete;
+ var _this = this;
+ grid._onDelete = function(item){
+ _this._onDelete(item);
+ _this._oldOnDelete.call(grid, item);
+ };
+ this._oldSort = grid.sort;
+ grid.sort = function(){
+ _this.clearMapping();
+ _this._oldSort.apply(grid, arguments);
+ };
+ },
+ uninitialize: function(){
+ this.grid._onDelete = this._oldOnDelete;
+ this.grid.sort = this._oldSort;
+ },
+ setMapping: function(mapping){
+ // summary:
+ // Remember the row mapping.
+ // mapping: Object
+ // keys are original rowIndexes, values are new rowIndexes.
+ this._store.forEachLayer(function(layer){
+ if(layer.name() === "rowmap"){
+ return false;
+ }else if(layer.onRowMappingChange){
+ layer.onRowMappingChange(mapping);
+ }
+ return true;
+ }, false);
+ var from, to, origin, revmap = {};
+ for(from in mapping){
+ from = parseInt(from, 10);
+ to = mapping[from];
+ if(typeof to == "number"){
+ if(from in this._revMap){
+ origin = this._revMap[from];
+ delete this._revMap[from];
+ }else{
+ origin = from;
+ }
+ if(origin == to){
+ delete this._map[origin];
+ revmap[to] = "eq";
+ }else{
+ this._map[origin] = to;
+ revmap[to] = origin;
+ }
+ }
+ }
+ for(to in revmap){
+ if(revmap[to] === "eq"){
+ delete this._revMap[parseInt(to, 10)];
+ }else{
+ this._revMap[parseInt(to, 10)] = revmap[to];
+ }
+ }
+ },
+ clearMapping: function(){
+ this._map = {};
+ this._revMap = {};
+ },
+ _onDelete: function(item){
+ var idx = this.grid._getItemIndex(item, true);
+ if(idx in this._revMap){
+ var rowIdxArr = [], r, i, origin = this._revMap[idx];
+ delete this._map[origin];
+ delete this._revMap[idx];
+ for(r in this._revMap){
+ r = parseInt(r, 10);
+ if(this._revMap[r] > origin){
+ --this._revMap[r];
+ }
+ }
+ for(r in this._revMap){
+ r = parseInt(r, 10);
+ if(r > idx){
+ rowIdxArr.push(r);
+ }
+ }
+ rowIdxArr.sort(function(a, b){
+ return b - a;
+ });
+ for(i = rowIdxArr.length - 1; i >= 0; --i){
+ r = rowIdxArr[i];
+ this._revMap[r - 1] = this._revMap[r];
+ delete this._revMap[r];
+ }
+ this._map = {};
+ for(r in this._revMap){
+ this._map[this._revMap[r]] = r;
+ }
+ }
+ },
+ _fetch: function(userRequest){
+ var mapCount = 0, r;
+ var start = userRequest.start || 0;
+ for(r in this._revMap){
+ r = parseInt(r, 10);
+ if(r >= start){
+ ++mapCount;
+ }
+ }
+ if(mapCount > 0){
+ //Row mapping is in use.
+ var rows = [], i, map = {},
+ count = userRequest.count > 0 ? userRequest.count : -1;
+ if(count > 0){
+ for(i = 0; i < count; ++i){
+ r = start + i;
+ r = r in this._revMap ? this._revMap[r] : r;
+ map[r] = i;
+ rows.push(r);
+ }
+ }else{
+ //We don't have a count, must create our own.
+ for(i = 0;; ++i){
+ r = start + i;
+ if(r in this._revMap){
+ --mapCount;
+ r = this._revMap[r];
+ }
+ map[r] = i;
+ rows.push(r);
+ if(mapCount <= 0){
+ break;
+ }
+ }
+ }
+ this._subFetch(userRequest, this._getRowArrays(rows), 0, [], map, userRequest.onComplete, start, count);
+ return userRequest;
+ }else{
+ //No row mapping at all.
+ return dojo.hitch(this._store, this._originFetch)(userRequest);
+ }
+ },
+ _getRowArrays: function(rows){
+ return _devideToArrays(rows);
+ },
+ _subFetch: function(userRequest, rowArrays, index, result, map, oldOnComplete, start, count){
+ var arr = rowArrays[index], _this = this;
+ var urstart = userRequest.start = arr[0];
+ userRequest.count = arr[arr.length - 1] - arr[0] + 1;
+ userRequest.onComplete = function(items){
+ dojo.forEach(items, function(item, i){
+ var r = urstart + i;
+ if(r in map){
+ result[map[r]] = item;
+ }
+ });
+ if(++index == rowArrays.length){
+ //mapped rows are all fetched.
+ if(count > 0){
+ userRequest.start = start;
+ userRequest.count = count;
+ userRequest.onComplete = oldOnComplete;
+ hitchIfCan(userRequest.scope, oldOnComplete)(result, userRequest);
+ }else{
+ userRequest.start = userRequest.start + items.length;
+ delete userRequest.count;
+ userRequest.onComplete = function(items){
+ result = result.concat(items);
+ userRequest.start = start;
+ userRequest.onComplete = oldOnComplete;
+ hitchIfCan(userRequest.scope, oldOnComplete)(result, userRequest);
+ };
+ _this.originFetch(userRequest);
+ }
+ }else{
+ _this._subFetch(userRequest, rowArrays, index, result, map, oldOnComplete, start, count);
+ }
+ };
+ _this.originFetch(userRequest);
+ }
+});
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/_RowMapLayer.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/_RowMapLayer.xd.js
new file mode 100644
index 0000000..3483c0f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/_RowMapLayer.xd.js
@@ -0,0 +1,220 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins._RowMapLayer"],
+["require", "dojox.grid.enhanced.plugins._StoreLayer"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins._RowMapLayer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins._RowMapLayer"] = true;
+dojo.provide("dojox.grid.enhanced.plugins._RowMapLayer");
+
+dojo.require("dojox.grid.enhanced.plugins._StoreLayer");
+
+(function(){
+var _devideToArrays = function(a){
+ a.sort(function(v1, v2){
+ return v1 - v2;
+ });
+ var arr = [[a[0]]];
+ for(var i = 1, j = 0; i < a.length; ++i){
+ if(a[i] == a[i-1] + 1){
+ arr[j].push(a[i]);
+ }else{
+ arr[++j] = [a[i]];
+ }
+ }
+ return arr;
+},
+hitchIfCan = function(scope, func){
+ return func ? dojo.hitch(scope || dojo.global, func) : function(){};
+};
+
+dojo.declare("dojox.grid.enhanced.plugins._RowMapLayer", dojox.grid.enhanced.plugins._StoreLayer, {
+ tags: ["reorder"],
+ constructor: function(grid){
+ this._map = {};
+ this._revMap = {};
+ this.grid = grid;
+ this._oldOnDelete = grid._onDelete;
+ var _this = this;
+ grid._onDelete = function(item){
+ _this._onDelete(item);
+ _this._oldOnDelete.call(grid, item);
+ };
+ this._oldSort = grid.sort;
+ grid.sort = function(){
+ _this.clearMapping();
+ _this._oldSort.apply(grid, arguments);
+ };
+ },
+ uninitialize: function(){
+ this.grid._onDelete = this._oldOnDelete;
+ this.grid.sort = this._oldSort;
+ },
+ setMapping: function(mapping){
+ // summary:
+ // Remember the row mapping.
+ // mapping: Object
+ // keys are original rowIndexes, values are new rowIndexes.
+ this._store.forEachLayer(function(layer){
+ if(layer.name() === "rowmap"){
+ return false;
+ }else if(layer.onRowMappingChange){
+ layer.onRowMappingChange(mapping);
+ }
+ return true;
+ }, false);
+ var from, to, origin, revmap = {};
+ for(from in mapping){
+ from = parseInt(from, 10);
+ to = mapping[from];
+ if(typeof to == "number"){
+ if(from in this._revMap){
+ origin = this._revMap[from];
+ delete this._revMap[from];
+ }else{
+ origin = from;
+ }
+ if(origin == to){
+ delete this._map[origin];
+ revmap[to] = "eq";
+ }else{
+ this._map[origin] = to;
+ revmap[to] = origin;
+ }
+ }
+ }
+ for(to in revmap){
+ if(revmap[to] === "eq"){
+ delete this._revMap[parseInt(to, 10)];
+ }else{
+ this._revMap[parseInt(to, 10)] = revmap[to];
+ }
+ }
+ },
+ clearMapping: function(){
+ this._map = {};
+ this._revMap = {};
+ },
+ _onDelete: function(item){
+ var idx = this.grid._getItemIndex(item, true);
+ if(idx in this._revMap){
+ var rowIdxArr = [], r, i, origin = this._revMap[idx];
+ delete this._map[origin];
+ delete this._revMap[idx];
+ for(r in this._revMap){
+ r = parseInt(r, 10);
+ if(this._revMap[r] > origin){
+ --this._revMap[r];
+ }
+ }
+ for(r in this._revMap){
+ r = parseInt(r, 10);
+ if(r > idx){
+ rowIdxArr.push(r);
+ }
+ }
+ rowIdxArr.sort(function(a, b){
+ return b - a;
+ });
+ for(i = rowIdxArr.length - 1; i >= 0; --i){
+ r = rowIdxArr[i];
+ this._revMap[r - 1] = this._revMap[r];
+ delete this._revMap[r];
+ }
+ this._map = {};
+ for(r in this._revMap){
+ this._map[this._revMap[r]] = r;
+ }
+ }
+ },
+ _fetch: function(userRequest){
+ var mapCount = 0, r;
+ var start = userRequest.start || 0;
+ for(r in this._revMap){
+ r = parseInt(r, 10);
+ if(r >= start){
+ ++mapCount;
+ }
+ }
+ if(mapCount > 0){
+ //Row mapping is in use.
+ var rows = [], i, map = {},
+ count = userRequest.count > 0 ? userRequest.count : -1;
+ if(count > 0){
+ for(i = 0; i < count; ++i){
+ r = start + i;
+ r = r in this._revMap ? this._revMap[r] : r;
+ map[r] = i;
+ rows.push(r);
+ }
+ }else{
+ //We don't have a count, must create our own.
+ for(i = 0;; ++i){
+ r = start + i;
+ if(r in this._revMap){
+ --mapCount;
+ r = this._revMap[r];
+ }
+ map[r] = i;
+ rows.push(r);
+ if(mapCount <= 0){
+ break;
+ }
+ }
+ }
+ this._subFetch(userRequest, this._getRowArrays(rows), 0, [], map, userRequest.onComplete, start, count);
+ return userRequest;
+ }else{
+ //No row mapping at all.
+ return dojo.hitch(this._store, this._originFetch)(userRequest);
+ }
+ },
+ _getRowArrays: function(rows){
+ return _devideToArrays(rows);
+ },
+ _subFetch: function(userRequest, rowArrays, index, result, map, oldOnComplete, start, count){
+ var arr = rowArrays[index], _this = this;
+ var urstart = userRequest.start = arr[0];
+ userRequest.count = arr[arr.length - 1] - arr[0] + 1;
+ userRequest.onComplete = function(items){
+ dojo.forEach(items, function(item, i){
+ var r = urstart + i;
+ if(r in map){
+ result[map[r]] = item;
+ }
+ });
+ if(++index == rowArrays.length){
+ //mapped rows are all fetched.
+ if(count > 0){
+ userRequest.start = start;
+ userRequest.count = count;
+ userRequest.onComplete = oldOnComplete;
+ hitchIfCan(userRequest.scope, oldOnComplete)(result, userRequest);
+ }else{
+ userRequest.start = userRequest.start + items.length;
+ delete userRequest.count;
+ userRequest.onComplete = function(items){
+ result = result.concat(items);
+ userRequest.start = start;
+ userRequest.onComplete = oldOnComplete;
+ hitchIfCan(userRequest.scope, oldOnComplete)(result, userRequest);
+ };
+ _this.originFetch(userRequest);
+ }
+ }else{
+ _this._subFetch(userRequest, rowArrays, index, result, map, oldOnComplete, start, count);
+ }
+ };
+ _this.originFetch(userRequest);
+ }
+});
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/_SelectionPreserver.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/_SelectionPreserver.js
new file mode 100644
index 0000000..65c95ad
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/_SelectionPreserver.js
@@ -0,0 +1,138 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins._SelectionPreserver"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins._SelectionPreserver"] = true;
+dojo.provide("dojox.grid.enhanced.plugins._SelectionPreserver");
+
+dojo.declare("dojox.grid.enhanced.plugins._SelectionPreserver", null, {
+ // summary:
+ // Preserve selections across various user actions.
+ //
+ // description:
+ // When this feature turned on, Grid will try to preserve selections across various user actions, e.g. sorting, filtering etc.
+ // Precondition - Identifier(id) is required for store, as id is used for differentiating row items.
+ // Known issue - The preserved selections might be inaccurate if some unloaded rows are selected by range previously(e.g.SHIFT + click)
+ //
+ // example:
+ // | //To turn on this - set 'keepSelection' attribute to true
+ // | <div dojoType="dojox.grid.EnhancedGrid" keepSelection = true .../>
+
+ //_connects: Array
+ // List of all connections.
+ _connects: [],
+
+ constructor: function(selection){
+ this.selection = selection;
+ var grid = this.grid = selection.grid;
+ grid.onSelectedById = this.onSelectedById;
+ this.reset();
+
+ var oldClearData = grid._clearData;
+ var _this = this;
+ grid._clearData = function(){
+ _this._updateMapping(!grid._noInternalMapping);
+ _this._trustSelection = [];
+ oldClearData.apply(grid, arguments);
+ };
+ this.connect(grid, '_setStore', 'reset');
+ this.connect(grid, '_addItem', '_reSelectById');
+ this.connect(selection, 'addToSelection', dojo.hitch(this, '_selectById', true));
+ this.connect(selection, 'deselect', dojo.hitch(this, '_selectById', false));
+ this.connect(selection, 'selectRange', dojo.hitch(this, '_updateMapping', true, true, false));
+ this.connect(selection, 'deselectRange', dojo.hitch(this, '_updateMapping', true, false, false));
+ this.connect(selection, 'deselectAll', dojo.hitch(this, '_updateMapping', true, false, true));
+ },
+ destroy: function(){
+ this.reset();
+ dojo.forEach(this._connects, dojo.disconnect);
+ delete this._connects;
+ },
+ connect: function(obj, event, method){
+ // summary:
+ // Connects specified obj/event to specified method of this object.
+ var conn = dojo.connect(obj, event, this, method);
+ this._connects.push(conn);
+ return conn;
+ },
+ reset: function(){
+ this._idMap = [];
+ this._selectedById = {};
+ this._trustSelection = [];
+ this._defaultSelected = false;
+ },
+ _reSelectById: function(item, index){
+ // summary:
+ // When some rows is fetched, determine whether it should be selected.
+ // When this function is called, grid.selection.selected[] is not trustable.
+ var s = this.selection, g = this.grid;
+ if(item && g._hasIdentity){
+ var id = g.store.getIdentity(item);
+ if(this._selectedById[id] === undefined){
+ if(!this._trustSelection[index]){
+ s.selected[index] = this._defaultSelected;
+ }
+ }else{
+ s.selected[index] = this._selectedById[id];
+ }
+ this._idMap.push(id);
+ g.onSelectedById(id, index, s.selected[index]);
+ }
+ },
+ _selectById: function(toSelect, inItemOrIndex){
+ // summary:
+ // Record selected rows by ID.
+ if(this.selection.mode == 'none' || !this.grid._hasIdentity){ return; }
+ var item = inItemOrIndex;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ var entry = this.grid._by_idx[inItemOrIndex];
+ item = entry && entry.item;
+ }
+ if(item){
+ var id = this.grid.store.getIdentity(item);
+ this._selectedById[id] = !!toSelect;
+ }else{
+ this._trustSelection[inItemOrIndex] = true;
+ }
+ },
+ onSelectedById: function(id, rowIndex, value){},
+
+ _updateMapping: function(trustSelection, isSelect, isForAll, from, to){
+ // summary:
+ // This function trys to keep the selection info updated when range selection is performed.
+ // 1. Calculate how many unloaded rows are there;
+ // 2. update _selectedById data if grid.selection._selected can be trusted, so loaded but unselected rows can
+ // be properly recorded.
+ var s = this.selection, g = this.grid, flag = 0, unloaded = 0, i, id;
+ for(i = g.rowCount - 1; i >= 0; --i){
+ if(!g._by_idx[i]){
+ ++unloaded;
+ flag += s.selected[i] ? 1 : -1;
+ }else{
+ id = g._by_idx[i].idty;
+ if(id && (trustSelection || this._selectedById[id] === undefined)){
+ this._selectedById[id] = !!s.selected[i];
+ }
+ }
+ }
+ if(unloaded){
+ this._defaultSelected = flag > 0;
+ }
+ if(!isForAll && from !== undefined && to !== undefined){
+ isForAll = !g.usingPagination && Math.abs(to - from + 1) === g.rowCount;
+ }
+ // When deselectAll, make sure every thing is deselected, even if it was selected but not loaded now.
+ // This occurs only when pagination's "All" is used.
+ if(isForAll && !g.usingPagination){
+ for(i = this._idMap.length; i >= 0; --i){
+ this._selectedById[this._idMap[i]] = isSelect;
+ }
+ }
+ }
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/_SelectionPreserver.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/_SelectionPreserver.xd.js
new file mode 100644
index 0000000..8167602
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/_SelectionPreserver.xd.js
@@ -0,0 +1,142 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins._SelectionPreserver"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins._SelectionPreserver"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins._SelectionPreserver"] = true;
+dojo.provide("dojox.grid.enhanced.plugins._SelectionPreserver");
+
+dojo.declare("dojox.grid.enhanced.plugins._SelectionPreserver", null, {
+ // summary:
+ // Preserve selections across various user actions.
+ //
+ // description:
+ // When this feature turned on, Grid will try to preserve selections across various user actions, e.g. sorting, filtering etc.
+ // Precondition - Identifier(id) is required for store, as id is used for differentiating row items.
+ // Known issue - The preserved selections might be inaccurate if some unloaded rows are selected by range previously(e.g.SHIFT + click)
+ //
+ // example:
+ // | //To turn on this - set 'keepSelection' attribute to true
+ // | <div dojoType="dojox.grid.EnhancedGrid" keepSelection = true .../>
+
+ //_connects: Array
+ // List of all connections.
+ _connects: [],
+
+ constructor: function(selection){
+ this.selection = selection;
+ var grid = this.grid = selection.grid;
+ grid.onSelectedById = this.onSelectedById;
+ this.reset();
+
+ var oldClearData = grid._clearData;
+ var _this = this;
+ grid._clearData = function(){
+ _this._updateMapping(!grid._noInternalMapping);
+ _this._trustSelection = [];
+ oldClearData.apply(grid, arguments);
+ };
+ this.connect(grid, '_setStore', 'reset');
+ this.connect(grid, '_addItem', '_reSelectById');
+ this.connect(selection, 'addToSelection', dojo.hitch(this, '_selectById', true));
+ this.connect(selection, 'deselect', dojo.hitch(this, '_selectById', false));
+ this.connect(selection, 'selectRange', dojo.hitch(this, '_updateMapping', true, true, false));
+ this.connect(selection, 'deselectRange', dojo.hitch(this, '_updateMapping', true, false, false));
+ this.connect(selection, 'deselectAll', dojo.hitch(this, '_updateMapping', true, false, true));
+ },
+ destroy: function(){
+ this.reset();
+ dojo.forEach(this._connects, dojo.disconnect);
+ delete this._connects;
+ },
+ connect: function(obj, event, method){
+ // summary:
+ // Connects specified obj/event to specified method of this object.
+ var conn = dojo.connect(obj, event, this, method);
+ this._connects.push(conn);
+ return conn;
+ },
+ reset: function(){
+ this._idMap = [];
+ this._selectedById = {};
+ this._trustSelection = [];
+ this._defaultSelected = false;
+ },
+ _reSelectById: function(item, index){
+ // summary:
+ // When some rows is fetched, determine whether it should be selected.
+ // When this function is called, grid.selection.selected[] is not trustable.
+ var s = this.selection, g = this.grid;
+ if(item && g._hasIdentity){
+ var id = g.store.getIdentity(item);
+ if(this._selectedById[id] === undefined){
+ if(!this._trustSelection[index]){
+ s.selected[index] = this._defaultSelected;
+ }
+ }else{
+ s.selected[index] = this._selectedById[id];
+ }
+ this._idMap.push(id);
+ g.onSelectedById(id, index, s.selected[index]);
+ }
+ },
+ _selectById: function(toSelect, inItemOrIndex){
+ // summary:
+ // Record selected rows by ID.
+ if(this.selection.mode == 'none' || !this.grid._hasIdentity){ return; }
+ var item = inItemOrIndex;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ var entry = this.grid._by_idx[inItemOrIndex];
+ item = entry && entry.item;
+ }
+ if(item){
+ var id = this.grid.store.getIdentity(item);
+ this._selectedById[id] = !!toSelect;
+ }else{
+ this._trustSelection[inItemOrIndex] = true;
+ }
+ },
+ onSelectedById: function(id, rowIndex, value){},
+
+ _updateMapping: function(trustSelection, isSelect, isForAll, from, to){
+ // summary:
+ // This function trys to keep the selection info updated when range selection is performed.
+ // 1. Calculate how many unloaded rows are there;
+ // 2. update _selectedById data if grid.selection._selected can be trusted, so loaded but unselected rows can
+ // be properly recorded.
+ var s = this.selection, g = this.grid, flag = 0, unloaded = 0, i, id;
+ for(i = g.rowCount - 1; i >= 0; --i){
+ if(!g._by_idx[i]){
+ ++unloaded;
+ flag += s.selected[i] ? 1 : -1;
+ }else{
+ id = g._by_idx[i].idty;
+ if(id && (trustSelection || this._selectedById[id] === undefined)){
+ this._selectedById[id] = !!s.selected[i];
+ }
+ }
+ }
+ if(unloaded){
+ this._defaultSelected = flag > 0;
+ }
+ if(!isForAll && from !== undefined && to !== undefined){
+ isForAll = !g.usingPagination && Math.abs(to - from + 1) === g.rowCount;
+ }
+ // When deselectAll, make sure every thing is deselected, even if it was selected but not loaded now.
+ // This occurs only when pagination's "All" is used.
+ if(isForAll && !g.usingPagination){
+ for(i = this._idMap.length; i >= 0; --i){
+ this._selectedById[this._idMap[i]] = isSelect;
+ }
+ }
+ }
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/_StoreLayer.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/_StoreLayer.js
new file mode 100644
index 0000000..153fdf3
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/_StoreLayer.js
@@ -0,0 +1,394 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins._StoreLayer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins._StoreLayer"] = true;
+dojo.provide("dojox.grid.enhanced.plugins._StoreLayer");
+// summary:
+// The dojo.data.api.Read API is powerful, but it's difficult to give the store some special commands before
+// fetch, so that the store content can be temporarily modified or transformed, and acts as another store. The
+// parameter *query* or *queryOptions* in keywordArgs for *fetch* is not enough because:
+// 1. users do not have the opportunity to response to the store actions when these options or queries are applied,
+// especially when the real store is at server side.
+// 2. the store implementation must be changed to support any new options in 'query' or 'queryOptions', so it'll be
+// difficult if this implementation is not able to or very hard to be changed, or some new options are required to
+// be valid for all stores.
+// This *StoreLayer* framework is dedicated to provide a uniform way for configuring an existing store, so that
+// it can be easily extended to have special behaviors or act like a totally different store.
+// The major approach is to wrap the *fetch* function of store, layer by layer. Every layer treats the incoming
+// store.fetch as a 'black box', thus maintaining the independence between layers.
+// *fetch* is the most important data retriever in the Read API, almost all other functions are used for a single
+// item, and require that this item is already retrieved (by and only by *fetch*). So once we've controlled this
+// *fetch* function, we've controlled almost the whole store. This fact simplifies our implementation of StoreLayer.
+// example:
+// //ns is for namespace, i.e.:dojox.grid.enhanced.plugins
+// ns.wrap(ns.wrap(ns.wrap(store, new ns.FilterLayer()), new ns.UniqueLayer()), new ns.TransformLayer());
+//
+// //every layer has a name, it should be given in the document of this layer.
+// //if you don't know it's name, you can get it by: ns.SomeLayer.prototype.name();
+// store.layer("filter").filterDef(...);
+// store.layer("unique").setUniqueColumns(...);
+// store.layer("transform").setScheme(...);
+//
+// //now use the store as usual...
+//
+// store.unwrap("transform"); //remove the transform layer but retain the other two.
+//
+// //now use the store as usual...
+//
+// store.unwrap(); //remove all the layers, get the original store back.
+(function(){
+ var ns = dojox.grid.enhanced.plugins,
+
+ getPrevTags = function(tags){
+ var tagList = ["reorder", "sizeChange", "normal", "presentation"];
+ var idx = tagList.length;
+ for(var i = tags.length - 1; i >= 0; --i){
+ var p = dojo.indexOf(tagList, tags[i]);
+ if(p >= 0 && p <= idx){
+ idx = p;
+ }
+ }
+ if(idx < tagList.length - 1){
+ return tagList.slice(0, idx + 1);
+ }else{
+ return tagList;
+ }
+ },
+
+ unwrap = function(/* string? */layerName){
+ // summary:
+ // Unwrap the layers of the store
+ // tags:
+ // public
+ // returns:
+ // The unwrapped store, for nested use only.
+ var i, layers = this._layers, len = layers.length;
+ if(layerName){
+ for(i = len-1; i >= 0; --i){
+ if(layers[i].name() == layerName){
+ layers[i]._unwrap(layers[i + 1]);
+ break;
+ }
+ }
+ layers.splice(i, 1);
+ }else{
+ for(i = len - 1; i >= 0; --i){
+ layers[i]._unwrap();
+ }
+ }
+ if(!layers.length){
+ delete this._layers;
+ delete this.layer;
+ delete this.unwrap;
+ delete this.forEachLayer;
+ }
+ //console.log("layers:",this._layers);
+ return this; //Read-store
+ },
+
+ getLayer = function(layerName){
+ // summary:
+ // Get a layer of the store, so we can configure that layer.
+ // tags:
+ // public (scope is store)
+ // layerName: string
+ // the name of the layer
+ // returns:
+ // the store layer object
+ var i, layers = this._layers;
+ if(typeof layerName == "undefined"){
+ return layers.length; //Integer
+ }
+ if(typeof layerName == "number"){
+ return layers[layerName]; //_StoreLayer
+ }
+ for(i = layers.length - 1; i >= 0; --i){
+ if(layers[i].name() == layerName){
+ return layers[i]; //_StoreLayer
+ }
+ }
+ return null; //_StoreLayer
+ },
+
+ forEachLayer = function(callback, isInnerToOuter){
+ // summary:
+ // Visit the layers one by one. From the outer most to inner most by default.
+ // callback: Function
+ // The function to callback.
+ // If return false, break the loop.
+ // isInnerToOuter: Boolean
+ // Whether visit from the inner most layer to the outer most layer.
+ var len = this._layers.length, start, end, dir;
+ if(isInnerToOuter){
+ start = 0;
+ end = len;
+ dir = 1;
+ }else{
+ start = len - 1;
+ end = -1;
+ dir = -1;
+ }
+ for(var i = start; i != end; i += dir){
+ if(callback(this._layers[i], i) === false){
+ return i;
+ }
+ }
+ return end;
+ };
+ ns.wrap = function(store, funcName, layer, layerFuncName){
+ // summary:
+ // Wrap the store with the given layer.
+ // tags:
+ // public
+ // store: Read-store
+ // The store to be wrapped.
+ // layer: _StoreLayer
+ // The layer to be used
+ // returns
+ // The wrapped store, for nested use only.
+ if(!store._layers){
+ store._layers = [];
+ store.layer = dojo.hitch(store, getLayer);
+ store.unwrap = dojo.hitch(store, unwrap);
+ store.forEachLayer = dojo.hitch(store, forEachLayer);
+ }
+ var prevTags = getPrevTags(layer.tags);
+ if(!dojo.some(store._layers, function(lyr, i){
+ if(dojo.some(lyr.tags, function(tag){
+ return dojo.indexOf(prevTags, tag) >= 0;
+ })){
+ return false;
+ }else{
+ store._layers.splice(i, 0, layer);
+ layer._wrap(store, funcName, layerFuncName, lyr);
+ return true;
+ }
+ })){
+ store._layers.push(layer);
+ layer._wrap(store, funcName, layerFuncName);
+ }
+ //console.log("wrapped layers:", dojo.map(store._layers, function(lyr){return lyr.name();}));
+ return store; //Read-store
+ };
+
+ dojo.declare("dojox.grid.enhanced.plugins._StoreLayer", null, {
+ // summary:
+ // The most abstract class of store layers, provides basic utilities and some interfaces.
+ // tags:
+ // abstract
+/*=====
+ // _store: [protected] Read-store
+ // The wrapped store.
+ _store: null,
+
+ // _originFetch: [protected] function
+ // The original fetch function of the store.
+ _originFetch: null,
+
+ // __enabled: [private] Boolean
+ // To control whether this layer is valid.
+ __enabled: true,
+=====*/
+ tags: ["normal"],
+
+ layerFuncName: "_fetch",
+
+ constructor: function(){
+ this._store = null;
+ this._originFetch = null;
+ this.__enabled = true;
+ },
+ initialize: function(store){
+ // summary:
+ //
+ },
+ uninitialize: function(store){
+ // summary:
+ //
+ },
+ invalidate: function(){
+
+ },
+ _wrap: function(store, funcName, layerFuncName, nextLayer){
+ // summary:
+ // Do the actual wrapping (or 'hacking' if you like) to the store.
+ // tags:
+ // internal
+ // store: Read-store
+ // The store to be wrapped.
+ this._store = store;
+ this._funcName = funcName;
+ var fetchFunc = dojo.hitch(this, function(){
+ return (this.enabled() ? this[layerFuncName || this.layerFuncName] : this.originFetch).apply(this, arguments);
+ });
+ if(nextLayer){
+ this._originFetch = nextLayer._originFetch;
+ nextLayer._originFetch = fetchFunc;
+ }else{
+ this._originFetch = store[funcName] || function(){};
+ store[funcName] = fetchFunc;
+ }
+ this.initialize(store);
+ },
+ _unwrap: function(nextLayer){
+ // summary:
+ // Do the actual unwrapping to the store.
+ // tags:
+ // internal
+ // store: Read-store
+ // The store to be unwrapped.
+ this.uninitialize(this._store);
+ if(nextLayer){
+ nextLayer._originFetch = this._originFetch;
+ }else{
+ this._store[this._funcName] = this._originFetch;
+ }
+ this._originFetch = null;
+ this._store = null;
+ },
+ enabled: function(/* bool? */toEnable){
+ // summary:
+ // The get/set function of the enabled status of this layer
+ // tags:
+ // public
+ // toEnable: Boolean?
+ // If given, is a setter, otherwise, it's getter.
+ if(typeof toEnable != "undefined"){
+ this.__enabled = !!toEnable;
+ }
+ return this.__enabled; //Boolean
+ },
+ name: function(){
+ // summary:
+ // Get the name of this store layer.
+ // The default name retrieved from class name, which should have a pattern of "{name}Layer".
+ // If this pattern does not exist, the whole class name will be this layer's name.
+ // It's better to override this method if your class name is too complicated.
+ // tags:
+ // public extension
+ // returns:
+ // The name of this layer.
+ if(!this.__name){
+ var m = this.declaredClass.match(/(?:\.(?:_*)([^\.]+)Layer$)|(?:\.([^\.]+)$)/i);
+ this.__name = m ? (m[1] || m[2]).toLowerCase() : this.declaredClass;
+ }
+ return this.__name;
+ },
+ originFetch: function(){
+ return (dojo.hitch(this._store, this._originFetch)).apply(this, arguments);
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins._ServerSideLayer", ns._StoreLayer, {
+ // summary:
+ // The most abstract class for all server side store layers.
+ // tags:
+ // abstract
+/*=====
+ // _url: [protected] string
+ // The url of the server
+ _url: "",
+ // __cmds [private] object
+ // The command object to be sent to server.
+ __cmds: {},
+=====*/
+ constructor: function(args){
+ args = args || {};
+ this._url = args.url || "";
+ this._isStateful = !!args.isStateful;
+ this._onUserCommandLoad = args.onCommandLoad || function(){};
+ this.__cmds = {cmdlayer:this.name(), enable:true};
+
+ //Only for stateful server, sending commands before fetch makes sense.
+ this.useCommands(this._isStateful);
+ },
+ enabled: function(/* bool? */toEnable){
+ // summary:
+ // Overrided from _StoreLayer.enabled
+ var res = this.inherited(arguments);
+ this.__cmds.enable = this.__enabled;
+ return res;
+ },
+ useCommands: function(/* bool? */toUse){
+ // summary:
+ // If you only want to modify the user request, instead of sending a separate command
+ // to server before fetch, just call:
+ // this.useCommand(false);
+ // tags:
+ // public
+ // toUse: Boolean?
+ // If provided, it's a setter, otherwise, it's a getter
+ if(typeof toUse != "undefined"){
+ this.__cmds.cmdlayer = (toUse && this._isStateful) ? this.name() : null;
+ }
+ return !!(this.__cmds.cmdlayer); //Boolean
+ },
+ _fetch: function(/* keywordArgs */userRequest){
+ // summary:
+ // Implementation of _StoreLayer._fetch
+ if(this.__cmds.cmdlayer){
+ //We're gonna send command to server before fetch.
+ dojo.xhrPost({
+ url: this._url || this._store.url,
+ content: this.__cmds,
+ load: dojo.hitch(this, function(responce){
+ this.onCommandLoad(responce, userRequest);
+ this.originFetch(userRequest);
+ }),
+ error: dojo.hitch(this, this.onCommandError)
+ });
+ }else{
+ //The user only wants to modify the request object.
+ this.onCommandLoad("", userRequest);
+ this.originFetch(userRequest);
+ }
+ return userRequest; //dojo.data.api.Request
+ },
+ command: function(/* string */cmdName,/* (string|number|bool|...)? */cmdContent){
+ // summary:
+ // get/set a command (a name-value pair)
+ // tags:
+ // public
+ // cmdName: string
+ // The name of the command
+ // cmdContent: anything
+ // The content of the command
+ // returns:
+ // The content of the command if cmdContent is undefined
+ var cmds = this.__cmds;
+ if(cmdContent === null){
+ delete cmds[cmdName];
+ }else if(typeof cmdContent !== "undefined"){
+ cmds[cmdName] = cmdContent;
+ }
+ return cmds[cmdName]; //anything
+ },
+ onCommandLoad: function(/* string */response, /* keywordArgs */userRequest){
+ // summary:
+ // When the server gives back *response* for the commands, you can do something here.
+ // tags:
+ // callback extension
+ // response: string
+ // server response
+ // userRequest: [in|out] dojo.data.api.Request
+ // The request object for *fetch*. You can modify this object according to the *response*
+ // so as to change the behavior of *fetch*
+ this._onUserCommandLoad(this.__cmds, userRequest, response);
+ },
+ onCommandError: function(error){
+ // summary:
+ // handle errors when sending commands.
+ // tags:
+ // callback extension
+ // error: Error
+ console.log(error);
+ throw error;
+ }
+ });
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/_StoreLayer.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/_StoreLayer.xd.js
new file mode 100644
index 0000000..a5dfb72
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/_StoreLayer.xd.js
@@ -0,0 +1,398 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins._StoreLayer"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins._StoreLayer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins._StoreLayer"] = true;
+dojo.provide("dojox.grid.enhanced.plugins._StoreLayer");
+// summary:
+// The dojo.data.api.Read API is powerful, but it's difficult to give the store some special commands before
+// fetch, so that the store content can be temporarily modified or transformed, and acts as another store. The
+// parameter *query* or *queryOptions* in keywordArgs for *fetch* is not enough because:
+// 1. users do not have the opportunity to response to the store actions when these options or queries are applied,
+// especially when the real store is at server side.
+// 2. the store implementation must be changed to support any new options in 'query' or 'queryOptions', so it'll be
+// difficult if this implementation is not able to or very hard to be changed, or some new options are required to
+// be valid for all stores.
+// This *StoreLayer* framework is dedicated to provide a uniform way for configuring an existing store, so that
+// it can be easily extended to have special behaviors or act like a totally different store.
+// The major approach is to wrap the *fetch* function of store, layer by layer. Every layer treats the incoming
+// store.fetch as a 'black box', thus maintaining the independence between layers.
+// *fetch* is the most important data retriever in the Read API, almost all other functions are used for a single
+// item, and require that this item is already retrieved (by and only by *fetch*). So once we've controlled this
+// *fetch* function, we've controlled almost the whole store. This fact simplifies our implementation of StoreLayer.
+// example:
+// //ns is for namespace, i.e.:dojox.grid.enhanced.plugins
+// ns.wrap(ns.wrap(ns.wrap(store, new ns.FilterLayer()), new ns.UniqueLayer()), new ns.TransformLayer());
+//
+// //every layer has a name, it should be given in the document of this layer.
+// //if you don't know it's name, you can get it by: ns.SomeLayer.prototype.name();
+// store.layer("filter").filterDef(...);
+// store.layer("unique").setUniqueColumns(...);
+// store.layer("transform").setScheme(...);
+//
+// //now use the store as usual...
+//
+// store.unwrap("transform"); //remove the transform layer but retain the other two.
+//
+// //now use the store as usual...
+//
+// store.unwrap(); //remove all the layers, get the original store back.
+(function(){
+ var ns = dojox.grid.enhanced.plugins,
+
+ getPrevTags = function(tags){
+ var tagList = ["reorder", "sizeChange", "normal", "presentation"];
+ var idx = tagList.length;
+ for(var i = tags.length - 1; i >= 0; --i){
+ var p = dojo.indexOf(tagList, tags[i]);
+ if(p >= 0 && p <= idx){
+ idx = p;
+ }
+ }
+ if(idx < tagList.length - 1){
+ return tagList.slice(0, idx + 1);
+ }else{
+ return tagList;
+ }
+ },
+
+ unwrap = function(/* string? */layerName){
+ // summary:
+ // Unwrap the layers of the store
+ // tags:
+ // public
+ // returns:
+ // The unwrapped store, for nested use only.
+ var i, layers = this._layers, len = layers.length;
+ if(layerName){
+ for(i = len-1; i >= 0; --i){
+ if(layers[i].name() == layerName){
+ layers[i]._unwrap(layers[i + 1]);
+ break;
+ }
+ }
+ layers.splice(i, 1);
+ }else{
+ for(i = len - 1; i >= 0; --i){
+ layers[i]._unwrap();
+ }
+ }
+ if(!layers.length){
+ delete this._layers;
+ delete this.layer;
+ delete this.unwrap;
+ delete this.forEachLayer;
+ }
+ //console.log("layers:",this._layers);
+ return this; //Read-store
+ },
+
+ getLayer = function(layerName){
+ // summary:
+ // Get a layer of the store, so we can configure that layer.
+ // tags:
+ // public (scope is store)
+ // layerName: string
+ // the name of the layer
+ // returns:
+ // the store layer object
+ var i, layers = this._layers;
+ if(typeof layerName == "undefined"){
+ return layers.length; //Integer
+ }
+ if(typeof layerName == "number"){
+ return layers[layerName]; //_StoreLayer
+ }
+ for(i = layers.length - 1; i >= 0; --i){
+ if(layers[i].name() == layerName){
+ return layers[i]; //_StoreLayer
+ }
+ }
+ return null; //_StoreLayer
+ },
+
+ forEachLayer = function(callback, isInnerToOuter){
+ // summary:
+ // Visit the layers one by one. From the outer most to inner most by default.
+ // callback: Function
+ // The function to callback.
+ // If return false, break the loop.
+ // isInnerToOuter: Boolean
+ // Whether visit from the inner most layer to the outer most layer.
+ var len = this._layers.length, start, end, dir;
+ if(isInnerToOuter){
+ start = 0;
+ end = len;
+ dir = 1;
+ }else{
+ start = len - 1;
+ end = -1;
+ dir = -1;
+ }
+ for(var i = start; i != end; i += dir){
+ if(callback(this._layers[i], i) === false){
+ return i;
+ }
+ }
+ return end;
+ };
+ ns.wrap = function(store, funcName, layer, layerFuncName){
+ // summary:
+ // Wrap the store with the given layer.
+ // tags:
+ // public
+ // store: Read-store
+ // The store to be wrapped.
+ // layer: _StoreLayer
+ // The layer to be used
+ // returns
+ // The wrapped store, for nested use only.
+ if(!store._layers){
+ store._layers = [];
+ store.layer = dojo.hitch(store, getLayer);
+ store.unwrap = dojo.hitch(store, unwrap);
+ store.forEachLayer = dojo.hitch(store, forEachLayer);
+ }
+ var prevTags = getPrevTags(layer.tags);
+ if(!dojo.some(store._layers, function(lyr, i){
+ if(dojo.some(lyr.tags, function(tag){
+ return dojo.indexOf(prevTags, tag) >= 0;
+ })){
+ return false;
+ }else{
+ store._layers.splice(i, 0, layer);
+ layer._wrap(store, funcName, layerFuncName, lyr);
+ return true;
+ }
+ })){
+ store._layers.push(layer);
+ layer._wrap(store, funcName, layerFuncName);
+ }
+ //console.log("wrapped layers:", dojo.map(store._layers, function(lyr){return lyr.name();}));
+ return store; //Read-store
+ };
+
+ dojo.declare("dojox.grid.enhanced.plugins._StoreLayer", null, {
+ // summary:
+ // The most abstract class of store layers, provides basic utilities and some interfaces.
+ // tags:
+ // abstract
+/*=====
+ // _store: [protected] Read-store
+ // The wrapped store.
+ _store: null,
+
+ // _originFetch: [protected] function
+ // The original fetch function of the store.
+ _originFetch: null,
+
+ // __enabled: [private] Boolean
+ // To control whether this layer is valid.
+ __enabled: true,
+=====*/
+ tags: ["normal"],
+
+ layerFuncName: "_fetch",
+
+ constructor: function(){
+ this._store = null;
+ this._originFetch = null;
+ this.__enabled = true;
+ },
+ initialize: function(store){
+ // summary:
+ //
+ },
+ uninitialize: function(store){
+ // summary:
+ //
+ },
+ invalidate: function(){
+
+ },
+ _wrap: function(store, funcName, layerFuncName, nextLayer){
+ // summary:
+ // Do the actual wrapping (or 'hacking' if you like) to the store.
+ // tags:
+ // internal
+ // store: Read-store
+ // The store to be wrapped.
+ this._store = store;
+ this._funcName = funcName;
+ var fetchFunc = dojo.hitch(this, function(){
+ return (this.enabled() ? this[layerFuncName || this.layerFuncName] : this.originFetch).apply(this, arguments);
+ });
+ if(nextLayer){
+ this._originFetch = nextLayer._originFetch;
+ nextLayer._originFetch = fetchFunc;
+ }else{
+ this._originFetch = store[funcName] || function(){};
+ store[funcName] = fetchFunc;
+ }
+ this.initialize(store);
+ },
+ _unwrap: function(nextLayer){
+ // summary:
+ // Do the actual unwrapping to the store.
+ // tags:
+ // internal
+ // store: Read-store
+ // The store to be unwrapped.
+ this.uninitialize(this._store);
+ if(nextLayer){
+ nextLayer._originFetch = this._originFetch;
+ }else{
+ this._store[this._funcName] = this._originFetch;
+ }
+ this._originFetch = null;
+ this._store = null;
+ },
+ enabled: function(/* bool? */toEnable){
+ // summary:
+ // The get/set function of the enabled status of this layer
+ // tags:
+ // public
+ // toEnable: Boolean?
+ // If given, is a setter, otherwise, it's getter.
+ if(typeof toEnable != "undefined"){
+ this.__enabled = !!toEnable;
+ }
+ return this.__enabled; //Boolean
+ },
+ name: function(){
+ // summary:
+ // Get the name of this store layer.
+ // The default name retrieved from class name, which should have a pattern of "{name}Layer".
+ // If this pattern does not exist, the whole class name will be this layer's name.
+ // It's better to override this method if your class name is too complicated.
+ // tags:
+ // public extension
+ // returns:
+ // The name of this layer.
+ if(!this.__name){
+ var m = this.declaredClass.match(/(?:\.(?:_*)([^\.]+)Layer$)|(?:\.([^\.]+)$)/i);
+ this.__name = m ? (m[1] || m[2]).toLowerCase() : this.declaredClass;
+ }
+ return this.__name;
+ },
+ originFetch: function(){
+ return (dojo.hitch(this._store, this._originFetch)).apply(this, arguments);
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins._ServerSideLayer", ns._StoreLayer, {
+ // summary:
+ // The most abstract class for all server side store layers.
+ // tags:
+ // abstract
+/*=====
+ // _url: [protected] string
+ // The url of the server
+ _url: "",
+ // __cmds [private] object
+ // The command object to be sent to server.
+ __cmds: {},
+=====*/
+ constructor: function(args){
+ args = args || {};
+ this._url = args.url || "";
+ this._isStateful = !!args.isStateful;
+ this._onUserCommandLoad = args.onCommandLoad || function(){};
+ this.__cmds = {cmdlayer:this.name(), enable:true};
+
+ //Only for stateful server, sending commands before fetch makes sense.
+ this.useCommands(this._isStateful);
+ },
+ enabled: function(/* bool? */toEnable){
+ // summary:
+ // Overrided from _StoreLayer.enabled
+ var res = this.inherited(arguments);
+ this.__cmds.enable = this.__enabled;
+ return res;
+ },
+ useCommands: function(/* bool? */toUse){
+ // summary:
+ // If you only want to modify the user request, instead of sending a separate command
+ // to server before fetch, just call:
+ // this.useCommand(false);
+ // tags:
+ // public
+ // toUse: Boolean?
+ // If provided, it's a setter, otherwise, it's a getter
+ if(typeof toUse != "undefined"){
+ this.__cmds.cmdlayer = (toUse && this._isStateful) ? this.name() : null;
+ }
+ return !!(this.__cmds.cmdlayer); //Boolean
+ },
+ _fetch: function(/* keywordArgs */userRequest){
+ // summary:
+ // Implementation of _StoreLayer._fetch
+ if(this.__cmds.cmdlayer){
+ //We're gonna send command to server before fetch.
+ dojo.xhrPost({
+ url: this._url || this._store.url,
+ content: this.__cmds,
+ load: dojo.hitch(this, function(responce){
+ this.onCommandLoad(responce, userRequest);
+ this.originFetch(userRequest);
+ }),
+ error: dojo.hitch(this, this.onCommandError)
+ });
+ }else{
+ //The user only wants to modify the request object.
+ this.onCommandLoad("", userRequest);
+ this.originFetch(userRequest);
+ }
+ return userRequest; //dojo.data.api.Request
+ },
+ command: function(/* string */cmdName,/* (string|number|bool|...)? */cmdContent){
+ // summary:
+ // get/set a command (a name-value pair)
+ // tags:
+ // public
+ // cmdName: string
+ // The name of the command
+ // cmdContent: anything
+ // The content of the command
+ // returns:
+ // The content of the command if cmdContent is undefined
+ var cmds = this.__cmds;
+ if(cmdContent === null){
+ delete cmds[cmdName];
+ }else if(typeof cmdContent !== "undefined"){
+ cmds[cmdName] = cmdContent;
+ }
+ return cmds[cmdName]; //anything
+ },
+ onCommandLoad: function(/* string */response, /* keywordArgs */userRequest){
+ // summary:
+ // When the server gives back *response* for the commands, you can do something here.
+ // tags:
+ // callback extension
+ // response: string
+ // server response
+ // userRequest: [in|out] dojo.data.api.Request
+ // The request object for *fetch*. You can modify this object according to the *response*
+ // so as to change the behavior of *fetch*
+ this._onUserCommandLoad(this.__cmds, userRequest, response);
+ },
+ onCommandError: function(error){
+ // summary:
+ // handle errors when sending commands.
+ // tags:
+ // callback extension
+ // error: Error
+ console.log(error);
+ throw error;
+ }
+ });
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/CSVWriter.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/CSVWriter.js
new file mode 100644
index 0000000..697cd94
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/CSVWriter.js
@@ -0,0 +1,90 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.exporter.CSVWriter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.exporter.CSVWriter"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.exporter.CSVWriter");
+
+dojo.require("dojox.grid.enhanced.plugins.exporter._ExportWriter");
+
+dojox.grid.enhanced.plugins.Exporter.registerWriter("csv",
+ "dojox.grid.enhanced.plugins.exporter.CSVWriter");
+
+dojo.declare("dojox.grid.enhanced.plugins.exporter.CSVWriter",
+ dojox.grid.enhanced.plugins.exporter._ExportWriter, {
+ // summary:
+ // Export grid to CSV format.
+ _separator: ',',
+ _newline: "\r\n",
+ constructor: function(/* object? */writerArgs){
+ // summary:
+ // CSV default separator is ','.
+ // But we can also use our own.
+ // writerArgs: object?
+ // {separator:'...'}
+ if(writerArgs){
+ this._separator = writerArgs.separator ? writerArgs.separator : this._separator;
+ this._newline = writerArgs.newline ? writerArgs.newline : this._newline;
+ }
+ this._headers = [];
+ this._dataRows = [];
+ },
+ _formatCSVCell: function(/* string */cellValue){
+ // summary:
+ // Format cell value to follow CSV standard.
+ // See: http://en.wikipedia.org/wiki/Comma-separated_values
+ // tags:
+ // private
+ // cellValue: string
+ // The value in a cell.
+ // returns:
+ // The formatted content of a cell
+ if(cellValue === null || cellValue === undefined){
+ return '';
+ }
+ var result = String(cellValue).replace(/"/g, '""');
+ if(result.indexOf(this._separator) >= 0 || result.search(/[" \t\r\n]/) >= 0){
+ result = '"' + result + '"';
+ }
+ return result; //String
+ },
+ beforeContentRow: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ var row = [],
+ func = this._formatCSVCell;
+ dojo.forEach(arg_obj.grid.layout.cells, function(cell){
+ //We are not interested in indirect selectors and row indexes.
+ if(!cell.hidden && dojo.indexOf(arg_obj.spCols,cell.index) < 0){
+ //We only need data here, not html
+ row.push(func(this._getExportDataForCell(arg_obj.rowIndex, arg_obj.row, cell, arg_obj.grid)));
+ }
+ }, this);
+ this._dataRows.push(row);
+ //We do not need to go into the row.
+ return false; //Boolean
+ },
+ handleCell: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ var cell = arg_obj.cell;
+ if(arg_obj.isHeader && !cell.hidden && dojo.indexOf(arg_obj.spCols,cell.index) < 0){
+ this._headers.push(cell.name || cell.field);
+ }
+ },
+ toString: function(){
+ // summary:
+ // Overrided from _ExportWriter
+ var result = this._headers.join(this._separator);
+ for(var i = this._dataRows.length - 1; i >= 0; --i){
+ this._dataRows[i] = this._dataRows[i].join(this._separator);
+ }
+ return result + this._newline + this._dataRows.join(this._newline); //String
+ }
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/CSVWriter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/CSVWriter.xd.js
new file mode 100644
index 0000000..16634fa
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/CSVWriter.xd.js
@@ -0,0 +1,95 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.exporter.CSVWriter"],
+["require", "dojox.grid.enhanced.plugins.exporter._ExportWriter"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.exporter.CSVWriter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.exporter.CSVWriter"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.exporter.CSVWriter");
+
+dojo.require("dojox.grid.enhanced.plugins.exporter._ExportWriter");
+
+dojox.grid.enhanced.plugins.Exporter.registerWriter("csv",
+ "dojox.grid.enhanced.plugins.exporter.CSVWriter");
+
+dojo.declare("dojox.grid.enhanced.plugins.exporter.CSVWriter",
+ dojox.grid.enhanced.plugins.exporter._ExportWriter, {
+ // summary:
+ // Export grid to CSV format.
+ _separator: ',',
+ _newline: "\r\n",
+ constructor: function(/* object? */writerArgs){
+ // summary:
+ // CSV default separator is ','.
+ // But we can also use our own.
+ // writerArgs: object?
+ // {separator:'...'}
+ if(writerArgs){
+ this._separator = writerArgs.separator ? writerArgs.separator : this._separator;
+ this._newline = writerArgs.newline ? writerArgs.newline : this._newline;
+ }
+ this._headers = [];
+ this._dataRows = [];
+ },
+ _formatCSVCell: function(/* string */cellValue){
+ // summary:
+ // Format cell value to follow CSV standard.
+ // See: http://en.wikipedia.org/wiki/Comma-separated_values
+ // tags:
+ // private
+ // cellValue: string
+ // The value in a cell.
+ // returns:
+ // The formatted content of a cell
+ if(cellValue === null || cellValue === undefined){
+ return '';
+ }
+ var result = String(cellValue).replace(/"/g, '""');
+ if(result.indexOf(this._separator) >= 0 || result.search(/[" \t\r\n]/) >= 0){
+ result = '"' + result + '"';
+ }
+ return result; //String
+ },
+ beforeContentRow: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ var row = [],
+ func = this._formatCSVCell;
+ dojo.forEach(arg_obj.grid.layout.cells, function(cell){
+ //We are not interested in indirect selectors and row indexes.
+ if(!cell.hidden && dojo.indexOf(arg_obj.spCols,cell.index) < 0){
+ //We only need data here, not html
+ row.push(func(this._getExportDataForCell(arg_obj.rowIndex, arg_obj.row, cell, arg_obj.grid)));
+ }
+ }, this);
+ this._dataRows.push(row);
+ //We do not need to go into the row.
+ return false; //Boolean
+ },
+ handleCell: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ var cell = arg_obj.cell;
+ if(arg_obj.isHeader && !cell.hidden && dojo.indexOf(arg_obj.spCols,cell.index) < 0){
+ this._headers.push(cell.name || cell.field);
+ }
+ },
+ toString: function(){
+ // summary:
+ // Overrided from _ExportWriter
+ var result = this._headers.join(this._separator);
+ for(var i = this._dataRows.length - 1; i >= 0; --i){
+ this._dataRows[i] = this._dataRows[i].join(this._separator);
+ }
+ return result + this._newline + this._dataRows.join(this._newline); //String
+ }
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/TableWriter.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/TableWriter.js
new file mode 100644
index 0000000..ce23a72
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/TableWriter.js
@@ -0,0 +1,156 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.exporter.TableWriter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.exporter.TableWriter"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.exporter.TableWriter");
+
+dojo.require("dojox.grid.enhanced.plugins.exporter._ExportWriter");
+
+dojox.grid.enhanced.plugins.Exporter.registerWriter("table",
+ "dojox.grid.enhanced.plugins.exporter.TableWriter");
+
+dojo.declare("dojox.grid.enhanced.plugins.exporter.TableWriter",
+ dojox.grid.enhanced.plugins.exporter._ExportWriter, {
+ // summary:
+ // Export grid to HTML table format. Primarily used by Printer plugin.
+ constructor: function(/* object? */writerArgs){
+ // summary:
+ // The generated table only defines the col/rowspan, height and width of
+ // all the cells in the style attribute, no other attributes
+ // (like border, cellspacing, etc.) are used.
+ // Users can define these attributes in the writerArgs object, like:
+ // {table:"border='border'",thead:"cellspacing='3'"}
+ this._viewTables = [];
+ this._tableAttrs = writerArgs || {};
+ },
+ _getTableAttrs: function(/* string */tagName){
+ // summary:
+ // Get html attribute string for the given kind of tag.
+ // tags:
+ // private
+ // tagName: string
+ // An html tag name
+ // returns:
+ // The well formatted attributes for the given html table.tag
+ var attrs = this._tableAttrs[tagName] || '';
+ //To ensure the attribute list starts with a space
+ if(attrs && attrs[0] != ' '){
+ attrs = ' ' + attrs;
+ }
+ return attrs; //String
+ },
+ _getRowClass: function(/* object */arg_obj){
+ // summary:
+ // Get CSS class string for a row
+ // tags:
+ // private
+ return arg_obj.isHeader ? " grid_header"//String
+ : [" grid_row grid_row_", arg_obj.rowIdx + 1,
+ arg_obj.rowIdx % 2 ? " grid_even_row" : " grid_odd_row"].join('');
+ },
+ _getColumnClass: function(/* object */arg_obj){
+ // summary:
+ // Get CSS class string for a column
+ // tags:
+ // private
+ var col_idx = arg_obj.cell.index + arg_obj.colOffset + 1;
+ return [" grid_column_", col_idx,//String
+ col_idx % 2 ? " grid_odd_column" : " grid_even_column"].join('');
+ },
+ beforeView: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ var viewIdx = arg_obj.viewIdx,
+ table = this._viewTables[viewIdx],
+ tagName, height,
+ width = dojo.marginBox(arg_obj.view.contentNode).w;
+ if(!table){
+ var left = 0;
+ for(var i = 0; i < viewIdx; ++i){
+ left += this._viewTables[i]._width;
+ }
+ table = this._viewTables[viewIdx] = ['<table class="grid_view" style="position: absolute; top: 0; left:', left,
+ 'px;"', this._getTableAttrs("table"), '>'];
+ }
+ table._width = width;
+ if(arg_obj.isHeader){
+ tagName = 'thead';
+ height = dojo.contentBox(arg_obj.view.headerContentNode).h;
+ }else{
+ tagName = 'tbody';
+ var rowNode = arg_obj.grid.getRowNode(arg_obj.rowIdx);
+ if(rowNode){
+ height = dojo.contentBox(rowNode).h;
+ }else{
+ //This row has not been loaded from store, so we should estimate it's height.
+ height = arg_obj.grid.scroller.averageRowHeight;
+ }
+ }
+ table.push('<',tagName,
+ ' style="height:', height, 'px; width:', width, 'px;"',
+ ' class="', this._getRowClass(arg_obj), '"',
+ this._getTableAttrs(tagName), '>');
+ return true; //Boolean
+ },
+ afterView: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ this._viewTables[arg_obj.viewIdx].push(arg_obj.isHeader ? '</thead>' : '</tbody>');
+ },
+ beforeSubrow: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ this._viewTables[arg_obj.viewIdx].push('<tr', this._getTableAttrs('tr'), '>');
+ return true; //Boolean
+ },
+ afterSubrow: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ this._viewTables[arg_obj.viewIdx].push('</tr>');
+ },
+ handleCell: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ var cell = arg_obj.cell;
+ if(cell.hidden || dojo.indexOf(arg_obj.spCols, cell.index) >= 0){
+ //We are not interested in indirect selectors and row indexes.
+ return;
+ }
+ var cellTagName = arg_obj.isHeader ? 'th' : 'td',
+ attrs = [cell.colSpan ? ' colspan="' + cell.colSpan + '"' : '',
+ cell.rowSpan ? ' rowspan="' + cell.rowSpan + '"' : '',
+ ' style="width: ', dojo.contentBox(cell.getHeaderNode()).w, 'px;"',
+ this._getTableAttrs(cellTagName),
+ ' class="', this._getColumnClass(arg_obj), '"'].join(''),
+ table = this._viewTables[arg_obj.viewIdx];
+ table.push('<', cellTagName, attrs, '>');
+ if(arg_obj.isHeader){
+ table.push(cell.name || cell.field);
+ } else{
+ table.push(this._getExportDataForCell(arg_obj.rowIdx, arg_obj.row, cell, arg_obj.grid));
+ }
+ table.push('</', cellTagName, '>');
+ },
+ afterContent: function(){
+ // summary:
+ // Overrided from _ExportWriter
+ dojo.forEach(this._viewTables, function(table){
+ table.push('</table>');
+ });
+ },
+ toString: function(){
+ // summary:
+ // Overrided from _ExportWriter
+ var viewsHTML = dojo.map(this._viewTables, function(table){ //String
+ return table.join('');
+ }).join('');
+ return ['<div style="position: relative;">', viewsHTML, '</div>'].join('');
+ }
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/TableWriter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/TableWriter.xd.js
new file mode 100644
index 0000000..9da1dc0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/TableWriter.xd.js
@@ -0,0 +1,161 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.exporter.TableWriter"],
+["require", "dojox.grid.enhanced.plugins.exporter._ExportWriter"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.exporter.TableWriter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.exporter.TableWriter"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.exporter.TableWriter");
+
+dojo.require("dojox.grid.enhanced.plugins.exporter._ExportWriter");
+
+dojox.grid.enhanced.plugins.Exporter.registerWriter("table",
+ "dojox.grid.enhanced.plugins.exporter.TableWriter");
+
+dojo.declare("dojox.grid.enhanced.plugins.exporter.TableWriter",
+ dojox.grid.enhanced.plugins.exporter._ExportWriter, {
+ // summary:
+ // Export grid to HTML table format. Primarily used by Printer plugin.
+ constructor: function(/* object? */writerArgs){
+ // summary:
+ // The generated table only defines the col/rowspan, height and width of
+ // all the cells in the style attribute, no other attributes
+ // (like border, cellspacing, etc.) are used.
+ // Users can define these attributes in the writerArgs object, like:
+ // {table:"border='border'",thead:"cellspacing='3'"}
+ this._viewTables = [];
+ this._tableAttrs = writerArgs || {};
+ },
+ _getTableAttrs: function(/* string */tagName){
+ // summary:
+ // Get html attribute string for the given kind of tag.
+ // tags:
+ // private
+ // tagName: string
+ // An html tag name
+ // returns:
+ // The well formatted attributes for the given html table.tag
+ var attrs = this._tableAttrs[tagName] || '';
+ //To ensure the attribute list starts with a space
+ if(attrs && attrs[0] != ' '){
+ attrs = ' ' + attrs;
+ }
+ return attrs; //String
+ },
+ _getRowClass: function(/* object */arg_obj){
+ // summary:
+ // Get CSS class string for a row
+ // tags:
+ // private
+ return arg_obj.isHeader ? " grid_header"//String
+ : [" grid_row grid_row_", arg_obj.rowIdx + 1,
+ arg_obj.rowIdx % 2 ? " grid_even_row" : " grid_odd_row"].join('');
+ },
+ _getColumnClass: function(/* object */arg_obj){
+ // summary:
+ // Get CSS class string for a column
+ // tags:
+ // private
+ var col_idx = arg_obj.cell.index + arg_obj.colOffset + 1;
+ return [" grid_column_", col_idx,//String
+ col_idx % 2 ? " grid_odd_column" : " grid_even_column"].join('');
+ },
+ beforeView: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ var viewIdx = arg_obj.viewIdx,
+ table = this._viewTables[viewIdx],
+ tagName, height,
+ width = dojo.marginBox(arg_obj.view.contentNode).w;
+ if(!table){
+ var left = 0;
+ for(var i = 0; i < viewIdx; ++i){
+ left += this._viewTables[i]._width;
+ }
+ table = this._viewTables[viewIdx] = ['<table class="grid_view" style="position: absolute; top: 0; left:', left,
+ 'px;"', this._getTableAttrs("table"), '>'];
+ }
+ table._width = width;
+ if(arg_obj.isHeader){
+ tagName = 'thead';
+ height = dojo.contentBox(arg_obj.view.headerContentNode).h;
+ }else{
+ tagName = 'tbody';
+ var rowNode = arg_obj.grid.getRowNode(arg_obj.rowIdx);
+ if(rowNode){
+ height = dojo.contentBox(rowNode).h;
+ }else{
+ //This row has not been loaded from store, so we should estimate it's height.
+ height = arg_obj.grid.scroller.averageRowHeight;
+ }
+ }
+ table.push('<',tagName,
+ ' style="height:', height, 'px; width:', width, 'px;"',
+ ' class="', this._getRowClass(arg_obj), '"',
+ this._getTableAttrs(tagName), '>');
+ return true; //Boolean
+ },
+ afterView: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ this._viewTables[arg_obj.viewIdx].push(arg_obj.isHeader ? '</thead>' : '</tbody>');
+ },
+ beforeSubrow: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ this._viewTables[arg_obj.viewIdx].push('<tr', this._getTableAttrs('tr'), '>');
+ return true; //Boolean
+ },
+ afterSubrow: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ this._viewTables[arg_obj.viewIdx].push('</tr>');
+ },
+ handleCell: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ var cell = arg_obj.cell;
+ if(cell.hidden || dojo.indexOf(arg_obj.spCols, cell.index) >= 0){
+ //We are not interested in indirect selectors and row indexes.
+ return;
+ }
+ var cellTagName = arg_obj.isHeader ? 'th' : 'td',
+ attrs = [cell.colSpan ? ' colspan="' + cell.colSpan + '"' : '',
+ cell.rowSpan ? ' rowspan="' + cell.rowSpan + '"' : '',
+ ' style="width: ', dojo.contentBox(cell.getHeaderNode()).w, 'px;"',
+ this._getTableAttrs(cellTagName),
+ ' class="', this._getColumnClass(arg_obj), '"'].join(''),
+ table = this._viewTables[arg_obj.viewIdx];
+ table.push('<', cellTagName, attrs, '>');
+ if(arg_obj.isHeader){
+ table.push(cell.name || cell.field);
+ } else{
+ table.push(this._getExportDataForCell(arg_obj.rowIdx, arg_obj.row, cell, arg_obj.grid));
+ }
+ table.push('</', cellTagName, '>');
+ },
+ afterContent: function(){
+ // summary:
+ // Overrided from _ExportWriter
+ dojo.forEach(this._viewTables, function(table){
+ table.push('</table>');
+ });
+ },
+ toString: function(){
+ // summary:
+ // Overrided from _ExportWriter
+ var viewsHTML = dojo.map(this._viewTables, function(table){ //String
+ return table.join('');
+ }).join('');
+ return ['<div style="position: relative;">', viewsHTML, '</div>'].join('');
+ }
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js
new file mode 100644
index 0000000..48e1e37
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js
@@ -0,0 +1,278 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.exporter._ExportWriter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.exporter._ExportWriter"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.exporter._ExportWriter");
+
+//require Exporter here, so the implementations only need to require this file,
+//and the users only need to require the implementation file.
+dojo.require("dojox.grid.enhanced.plugins.Exporter");
+
+dojo.declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
+ // summary:
+ // This is an abstract class for all kinds of writers used in the Exporter plugin.
+ // It utilizes the strategy pattern to break the export work into several stages,
+ // and provide interfaces for all of them.
+ // Implementations might choose some of the functions in this class to override,
+ // thus providing their own functionalities.
+ // The Exporter will go through the grid line by line. So in every line, all the Views
+ // will be reached, and the header line is only handled once.
+ // An *argObj* object is passed to most functions of this class.
+ // It carries context arguments that make sense when they are called.
+
+/*=====
+ argObj: {
+ // grid: EnhancedGrid
+ // The grid object we are now handling.
+ grid: null,
+
+ // isHeader: bool
+ // Indicating which context we're handling, header or content.
+ isHeader: true,
+
+ // view: _View
+ // Reference to the current _View object.
+ view: null,
+
+ // viewIdx: int
+ // The index of the current _View object in the views array.
+ // If the grid does not have any rowselector view, it conforms to the index
+ // in the _ViewManager.views.
+ viewIdx: -1,
+
+ // subrow: _View.structure.cells[i]
+ // Reference to the current subrow.
+ // A subrow describe the innter structure of a row in a view, it's an array of cells
+ subrow: null,
+
+ // subrowIdx: int
+ // The index of the current subrow in the subrow array: _View.structure.cells.
+ subrowIdx: -1,
+
+ // cell: dojox.grid.__CellDef
+ // Reference to the current cell.
+ cell: null,
+
+ //cellIdx: int
+ // The index of the current cell in the current subrow.
+ // It's different from cell.index, which is the index in the whole line.
+ cellIdx: -1,
+
+ //row: item
+ // The current row of data (logically), a.k.a.: current item.
+ row: null,
+
+ //rowIdx: int
+ // The index of the current row (item).
+ rowIdx: -1,
+
+ // spCols: Array<int>
+ // An array of special column indexes(flat,not regarding structure).
+ // Special columns are typically attached to grid as a kind of UI facility
+ // by the grid widget, instead of some real data.
+ // For example, indirect selectors and row indexers.
+ // Users can choose to export it or not.
+ spCols: [],
+
+ // colOffset: int
+ // If the grid has a _RowSelector view or something else, this view will NOT be
+ // passed to the user in argObj. So the column index (cell.index) will appear shifted
+ // (start from 1 instead of 0). This colOffset is provided to remove this shift.
+ // usage:
+ // var correctColIndex = argObj.cell.index + argObj.colOffset;
+ colOffset: 0
+ },
+=====*/
+
+ constructor: function(/* object? */writerArgs){
+ // summary:
+ // Writer initializations goes here.
+ // writerArgs: object?
+ // Any implementation of this class might accept a writerArgs object (optional),
+ // which contains some writer-specific arguments given by the user.
+ },
+ _getExportDataForCell: function(rowIndex, rowItem, cell, grid){
+ var data = (cell.get || grid.get).call(cell, rowIndex, rowItem);
+ if(this.formatter){
+ return this.formatter(data, cell, rowIndex, rowItem);
+ }else{
+ return data;
+ }
+ },
+ beforeHeader: function(/* EnhancedGrid */grid){
+ // summary:
+ // We are going to start the travel in the grid.
+ // Is there anything we should do now?
+ // tags:
+ // protected extension
+ // return:
+ // true: go on hanling the header row and then call afterHeader.
+ // false: skip the header row, won't call afterHeader.
+ return true; //Boolean
+ },
+ afterHeader: function(){
+ // summary:
+ // The header line has been handled.
+ // tags:
+ // protected extension
+ // returns:
+ // undefined
+ },
+ beforeContent: function(/* Array */items){
+ // summary:
+ // We are ready to go through all the contents(items).
+ // tags:
+ // protected extension
+ // items:
+ // All the items fetched from the store
+ // return:
+ // true: go on handling the contents and then call afterContent.
+ // false: skip all the contents, won't call afterContent.
+ return true; //Boolean
+ },
+ afterContent: function(){
+ // summary:
+ // We have finished the entire grid travel.
+ // Do some clean up work if you need to.
+ // tags:
+ // protected extension
+ // returns:
+ // undefined
+ },
+ beforeContentRow: function(/* object */argObj){
+ // summary:
+ // Before handling a line of data (not header).
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // row,rowIdx,
+ // spCols
+ // }
+ // return:
+ // true: go on handling the current data row and then call afterContentRow.
+ // false: skip the current data row, won't call afterContentRow.
+ return true; //Boolean
+ },
+ afterContentRow: function(/* object */argObj){
+ // summary:
+ // After handling a line of data (not header).
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // row,rowIdx,
+ // spCols
+ // }
+ // returns:
+ // undefined
+ },
+ beforeView: function(/* object */argObj){
+ // summary:
+ // Before handling a view.
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // view,viewIdx,
+ // spCols(if isHeader==false)
+ // }
+ // return:
+ // true: go on handling the current view and then call afterView.
+ // false: skip the current view, won't call afterView.
+ return true; //Boolean
+ },
+ afterView: function(/* object */argObj){
+ // summary:
+ // After handling a view.
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // view,viewIdx,
+ // spCols(if isHeader==false)
+ // }
+ // tags:
+ // protected extension
+ // returns:
+ // undefined
+ },
+ beforeSubrow: function(/* object */argObj){
+ // summary:
+ // Before handling a subrow in a line (defined in the grid structure).
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // row,rowIdx,
+ // view,viewIdx,
+ // subrow,subrowIdx,
+ // spCols(if isHeader==false)
+ // }
+ // return:
+ // true: go on handling the current subrow and then call afterSubrow.
+ // false: skip the current subrow, won't call afterSubrow.
+ return true; //Boolean
+ },
+ afterSubrow: function(/* object */argObj){
+ // summary:
+ // Before handling a subrow in a line (defined in the grid structure).
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // row,rowIdx,
+ // view,viewIdx,
+ // subrow,subrowIdx,
+ // spCols(if isHeader==false)
+ // }
+ // returns:
+ // undefined
+ },
+ handleCell: function(/* object */argObj){
+ // summary:
+ // Handle a header cell or data cell.
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // row,rowIdx,
+ // view,viewIdx,
+ // subrow,subrowIdx,
+ // cell,cellIdx,
+ // spCols(if isHeader==false)
+ // }
+ // returns:
+ // undefined
+ },
+ toString: function(){
+ // summary:
+ // Export to a string.
+ // tags:
+ // protected extension
+ // returns:
+ // The exported result string.
+ return ''; //String
+ }
+});
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/_ExportWriter.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/_ExportWriter.xd.js
new file mode 100644
index 0000000..77e7570
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/exporter/_ExportWriter.xd.js
@@ -0,0 +1,283 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.exporter._ExportWriter"],
+["require", "dojox.grid.enhanced.plugins.Exporter"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.exporter._ExportWriter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.exporter._ExportWriter"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.exporter._ExportWriter");
+
+//require Exporter here, so the implementations only need to require this file,
+//and the users only need to require the implementation file.
+dojo.require("dojox.grid.enhanced.plugins.Exporter");
+
+dojo.declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
+ // summary:
+ // This is an abstract class for all kinds of writers used in the Exporter plugin.
+ // It utilizes the strategy pattern to break the export work into several stages,
+ // and provide interfaces for all of them.
+ // Implementations might choose some of the functions in this class to override,
+ // thus providing their own functionalities.
+ // The Exporter will go through the grid line by line. So in every line, all the Views
+ // will be reached, and the header line is only handled once.
+ // An *argObj* object is passed to most functions of this class.
+ // It carries context arguments that make sense when they are called.
+
+/*=====
+ argObj: {
+ // grid: EnhancedGrid
+ // The grid object we are now handling.
+ grid: null,
+
+ // isHeader: bool
+ // Indicating which context we're handling, header or content.
+ isHeader: true,
+
+ // view: _View
+ // Reference to the current _View object.
+ view: null,
+
+ // viewIdx: int
+ // The index of the current _View object in the views array.
+ // If the grid does not have any rowselector view, it conforms to the index
+ // in the _ViewManager.views.
+ viewIdx: -1,
+
+ // subrow: _View.structure.cells[i]
+ // Reference to the current subrow.
+ // A subrow describe the innter structure of a row in a view, it's an array of cells
+ subrow: null,
+
+ // subrowIdx: int
+ // The index of the current subrow in the subrow array: _View.structure.cells.
+ subrowIdx: -1,
+
+ // cell: dojox.grid.__CellDef
+ // Reference to the current cell.
+ cell: null,
+
+ //cellIdx: int
+ // The index of the current cell in the current subrow.
+ // It's different from cell.index, which is the index in the whole line.
+ cellIdx: -1,
+
+ //row: item
+ // The current row of data (logically), a.k.a.: current item.
+ row: null,
+
+ //rowIdx: int
+ // The index of the current row (item).
+ rowIdx: -1,
+
+ // spCols: Array<int>
+ // An array of special column indexes(flat,not regarding structure).
+ // Special columns are typically attached to grid as a kind of UI facility
+ // by the grid widget, instead of some real data.
+ // For example, indirect selectors and row indexers.
+ // Users can choose to export it or not.
+ spCols: [],
+
+ // colOffset: int
+ // If the grid has a _RowSelector view or something else, this view will NOT be
+ // passed to the user in argObj. So the column index (cell.index) will appear shifted
+ // (start from 1 instead of 0). This colOffset is provided to remove this shift.
+ // usage:
+ // var correctColIndex = argObj.cell.index + argObj.colOffset;
+ colOffset: 0
+ },
+=====*/
+
+ constructor: function(/* object? */writerArgs){
+ // summary:
+ // Writer initializations goes here.
+ // writerArgs: object?
+ // Any implementation of this class might accept a writerArgs object (optional),
+ // which contains some writer-specific arguments given by the user.
+ },
+ _getExportDataForCell: function(rowIndex, rowItem, cell, grid){
+ var data = (cell.get || grid.get).call(cell, rowIndex, rowItem);
+ if(this.formatter){
+ return this.formatter(data, cell, rowIndex, rowItem);
+ }else{
+ return data;
+ }
+ },
+ beforeHeader: function(/* EnhancedGrid */grid){
+ // summary:
+ // We are going to start the travel in the grid.
+ // Is there anything we should do now?
+ // tags:
+ // protected extension
+ // return:
+ // true: go on hanling the header row and then call afterHeader.
+ // false: skip the header row, won't call afterHeader.
+ return true; //Boolean
+ },
+ afterHeader: function(){
+ // summary:
+ // The header line has been handled.
+ // tags:
+ // protected extension
+ // returns:
+ // undefined
+ },
+ beforeContent: function(/* Array */items){
+ // summary:
+ // We are ready to go through all the contents(items).
+ // tags:
+ // protected extension
+ // items:
+ // All the items fetched from the store
+ // return:
+ // true: go on handling the contents and then call afterContent.
+ // false: skip all the contents, won't call afterContent.
+ return true; //Boolean
+ },
+ afterContent: function(){
+ // summary:
+ // We have finished the entire grid travel.
+ // Do some clean up work if you need to.
+ // tags:
+ // protected extension
+ // returns:
+ // undefined
+ },
+ beforeContentRow: function(/* object */argObj){
+ // summary:
+ // Before handling a line of data (not header).
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // row,rowIdx,
+ // spCols
+ // }
+ // return:
+ // true: go on handling the current data row and then call afterContentRow.
+ // false: skip the current data row, won't call afterContentRow.
+ return true; //Boolean
+ },
+ afterContentRow: function(/* object */argObj){
+ // summary:
+ // After handling a line of data (not header).
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // row,rowIdx,
+ // spCols
+ // }
+ // returns:
+ // undefined
+ },
+ beforeView: function(/* object */argObj){
+ // summary:
+ // Before handling a view.
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // view,viewIdx,
+ // spCols(if isHeader==false)
+ // }
+ // return:
+ // true: go on handling the current view and then call afterView.
+ // false: skip the current view, won't call afterView.
+ return true; //Boolean
+ },
+ afterView: function(/* object */argObj){
+ // summary:
+ // After handling a view.
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // view,viewIdx,
+ // spCols(if isHeader==false)
+ // }
+ // tags:
+ // protected extension
+ // returns:
+ // undefined
+ },
+ beforeSubrow: function(/* object */argObj){
+ // summary:
+ // Before handling a subrow in a line (defined in the grid structure).
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // row,rowIdx,
+ // view,viewIdx,
+ // subrow,subrowIdx,
+ // spCols(if isHeader==false)
+ // }
+ // return:
+ // true: go on handling the current subrow and then call afterSubrow.
+ // false: skip the current subrow, won't call afterSubrow.
+ return true; //Boolean
+ },
+ afterSubrow: function(/* object */argObj){
+ // summary:
+ // Before handling a subrow in a line (defined in the grid structure).
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // row,rowIdx,
+ // view,viewIdx,
+ // subrow,subrowIdx,
+ // spCols(if isHeader==false)
+ // }
+ // returns:
+ // undefined
+ },
+ handleCell: function(/* object */argObj){
+ // summary:
+ // Handle a header cell or data cell.
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // row,rowIdx,
+ // view,viewIdx,
+ // subrow,subrowIdx,
+ // cell,cellIdx,
+ // spCols(if isHeader==false)
+ // }
+ // returns:
+ // undefined
+ },
+ toString: function(){
+ // summary:
+ // Export to a string.
+ // tags:
+ // protected extension
+ // returns:
+ // The exported result string.
+ return ''; //String
+ }
+});
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js
new file mode 100644
index 0000000..9b072d2
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js
@@ -0,0 +1,44 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter.ClearFilterConfirm"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter.ClearFilterConfirm"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm");
+
+dojo.require("dijit.form.Button");
+
+dojo.declare("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm",[dijit._Widget,dijit._Templated],{
+ // summary:
+ // The UI for user to confirm the operation of clearing filter.
+ templateString: dojo.cache("dojox.grid", "enhanced/templates/ClearFilterConfirmPane.html", "<div class=\"dojoxGridClearFilterConfirm\">\r\n\t<div class=\"dojoxGridClearFilterMsg\">\r\n\t\t${_clearFilterMsg}\r\n\t</div>\r\n\t<div class=\"dojoxGridClearFilterBtns\" dojoAttachPoint=\"btnsNode\">\r\n\t\t<span dojoType=\"dijit.form.Button\" label=\"${_cancelBtnLabel}\" dojoAttachPoint=\"cancelBtn\" dojoAttachEvent=\"onClick:_onCancel\"></span>\r\n\t\t<span dojoType=\"dijit.form.Button\" label=\"${_clearBtnLabel}\" dojoAttachPoint=\"clearBtn\" dojoAttachEvent=\"onClick:_onClear\"></span>\r\n\t</div>\r\n</div>\r\n"),
+ widgetsInTemplate: true,
+ plugin: null,
+ postMixInProperties: function(){
+ var nls = this.plugin.nls;
+ this._clearBtnLabel = nls["clearButton"];
+ this._cancelBtnLabel = nls["cancelButton"];
+ this._clearFilterMsg = nls["clearFilterMsg"];
+ },
+ postCreate: function(){
+ this.inherited(arguments);
+ dijit.setWaiState(this.cancelBtn.domNode, "label", this.plugin.nls["waiCancelButton"]);
+ dijit.setWaiState(this.clearBtn.domNode, "label", this.plugin.nls["waiClearButton"]);
+ },
+ uninitialize: function(){
+ this.plugin = null;
+ },
+ _onCancel: function(){
+ this.plugin.clearFilterDialog.hide();
+ },
+ _onClear: function(){
+ this.plugin.clearFilterDialog.hide();
+ this.plugin.filterDefDialog.clearFilter(this.plugin.filterDefDialog._clearWithoutRefresh);
+ }
+});
+
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.xd.js
new file mode 100644
index 0000000..20f8ed7
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.xd.js
@@ -0,0 +1,49 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.filter.ClearFilterConfirm"],
+["require", "dijit.form.Button"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter.ClearFilterConfirm"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter.ClearFilterConfirm"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm");
+
+dojo.require("dijit.form.Button");
+
+dojo.declare("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm",[dijit._Widget,dijit._Templated],{
+ // summary:
+ // The UI for user to confirm the operation of clearing filter.
+ templateString: dojo.cache("dojox.grid", "enhanced/templates/ClearFilterConfirmPane.html", "<div class=\"dojoxGridClearFilterConfirm\">\r\n\t<div class=\"dojoxGridClearFilterMsg\">\r\n\t\t${_clearFilterMsg}\r\n\t</div>\r\n\t<div class=\"dojoxGridClearFilterBtns\" dojoAttachPoint=\"btnsNode\">\r\n\t\t<span dojoType=\"dijit.form.Button\" label=\"${_cancelBtnLabel}\" dojoAttachPoint=\"cancelBtn\" dojoAttachEvent=\"onClick:_onCancel\"></span>\r\n\t\t<span dojoType=\"dijit.form.Button\" label=\"${_clearBtnLabel}\" dojoAttachPoint=\"clearBtn\" dojoAttachEvent=\"onClick:_onClear\"></span>\r\n\t</div>\r\n</div>\r\n"),
+ widgetsInTemplate: true,
+ plugin: null,
+ postMixInProperties: function(){
+ var nls = this.plugin.nls;
+ this._clearBtnLabel = nls["clearButton"];
+ this._cancelBtnLabel = nls["cancelButton"];
+ this._clearFilterMsg = nls["clearFilterMsg"];
+ },
+ postCreate: function(){
+ this.inherited(arguments);
+ dijit.setWaiState(this.cancelBtn.domNode, "label", this.plugin.nls["waiCancelButton"]);
+ dijit.setWaiState(this.clearBtn.domNode, "label", this.plugin.nls["waiClearButton"]);
+ },
+ uninitialize: function(){
+ this.plugin = null;
+ },
+ _onCancel: function(){
+ this.plugin.clearFilterDialog.hide();
+ },
+ _onClear: function(){
+ this.plugin.clearFilterDialog.hide();
+ this.plugin.filterDefDialog.clearFilter(this.plugin.filterDefDialog._clearWithoutRefresh);
+ }
+});
+
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterBar.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterBar.js
new file mode 100644
index 0000000..def0c38
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterBar.js
@@ -0,0 +1,380 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterBar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterBar"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter.FilterBar");
+
+dojo.require("dijit.form.Button");
+dojo.require("dojo.string");
+dojo.require("dojo.fx");
+
+(function(){
+var _focusClass = "dojoxGridFBarHover",
+ _filteredClass = "dojoxGridFBarFiltered",
+ _stopEvent = function(evt){
+ try{
+ if(evt && evt.preventDefault){
+ dojo.stopEvent(evt);
+ }
+ }catch(e){}
+ };
+
+dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, dijit._Templated],{
+ // summary:
+ // The filter bar UI.
+ templateString: dojo.cache("dojox.grid", "enhanced/templates/FilterBar.html", "<table class=\"dojoxGridFBar\" border=\"0\" cellspacing=\"0\" dojoAttachEvent=\"onclick:_onClickFilterBar, onmouseenter:_onMouseEnter, onmouseleave:_onMouseLeave, onmousemove:_onMouseMove\"\r\n\t><tr><td class=\"dojoxGridFBarBtnTD\"\r\n\t\t><span dojoType=\"dijit.form.Button\" class=\"dojoxGridFBarBtn\" dojoAttachPoint=\"defineFilterButton\" label=\"...\" iconClass=\"dojoxGridFBarDefFilterBtnIcon\" showLabel=\"true\" dojoAttachEvent=\"onClick:_showFilterDefDialog, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton\"></span\r\n\t></td><td class=\"dojoxGridFBarInfoTD\"\r\n\t\t><span class=\"dojoxGridFBarInner\"\r\n\t\t\t><span class=\"dojoxGridFBarStatus\" dojoAttachPoint=\"statusBarNode\">${_noFilterMsg}</span\r\n\t\t\t><span dojoType=\"dijit.form.Button\" class=\"dojoxGridFBarClearFilterBtn\" dojoAttachPoint=\"clearFilterButton\" \r\n\t\t\t\tlabel=\"${_filterBarClearBtnLabel}\" iconClass=\"dojoxGridFBarClearFilterBtnIcon\" showLabel=\"true\" \r\n\t\t\t\tdojoAttachEvent=\"onClick:_clearFilterDefDialog, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton\"></span\r\n\t\t\t><span dojotype=\"dijit.form.Button\" class=\"dojoxGridFBarCloseBtn\" dojoAttachPoint=\"closeFilterBarButton\" \r\n\t\t\t\tlabel=\"${_closeFilterBarBtnLabel}\" iconClass=\"dojoxGridFBarCloseBtnIcon\" showLabel=\"false\" \r\n\t\t\t\tdojoAttachEvent=\"onClick:_closeFilterBar, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton\"></span\r\n\t\t></span\r\n\t></td></tr\r\n></table>\r\n"),
+ widgetsInTemplate: true,
+
+ _timeout_statusTooltip: 300,
+ _handle_statusTooltip: null,
+ _curColIdx: -1,
+
+ plugin: null,
+ postMixInProperties: function(){
+ var plugin = this.plugin;
+ var nls = plugin.nls;
+ this._filterBarDefBtnLabel = nls["filterBarDefButton"];
+ this._filterBarClearBtnLabel = nls["filterBarClearButton"];
+ this._closeFilterBarBtnLabel = nls["closeFilterBarBtn"];
+ var itemsName = plugin.args.itemsName || nls["defaultItemsName"];
+ this._noFilterMsg = dojo.string.substitute(nls["filterBarMsgNoFilterTemplate"], ["", itemsName]);
+
+ var t = this.plugin.args.statusTipTimeout;
+ if(typeof t == 'number'){
+ this._timeout_statusTooltip = t;
+ }
+
+ var g = plugin.grid;
+ g.showFilterBar = dojo.hitch(this, "showFilterBar");
+ g.toggleFilterBar = dojo.hitch(this, "toggleFilterBar");
+ g.isFilterBarShown = dojo.hitch(this, "isFilterBarShown");
+ },
+ postCreate: function(){
+ this.inherited(arguments);
+ if(!this.plugin.args.closeFilterbarButton){
+ dojo.style(this.closeFilterBarButton.domNode, "display", "none");
+ }
+ var _this = this,
+ g = this.plugin.grid,
+ old_func = this.oldGetHeaderHeight = dojo.hitch(g,g._getHeaderHeight);
+
+ this.placeAt(g.viewsHeaderNode, "after");
+ this.connect(this.plugin.filterDefDialog, "showDialog", "_onShowFilterDefDialog");
+ this.connect(this.plugin.filterDefDialog, "closeDialog", "_onCloseFilterDefDialog");
+ this.connect(g.layer("filter"), "onFiltered", this._onFiltered);
+
+ this.defineFilterButton.domNode.title = this.plugin.nls["filterBarDefButton"];
+ if(dojo.hasClass(dojo.body(), "dijit_a11y")){
+ this.defineFilterButton.set("label", this.plugin.nls["a11yFilterBarDefButton"]);
+ }
+ this.connect(this.defineFilterButton.domNode, "click", _stopEvent);
+ this.connect(this.clearFilterButton.domNode, "click", _stopEvent);
+ this.connect(this.closeFilterBarButton.domNode, "click", _stopEvent);
+
+ this.toggleClearFilterBtn(true);
+ this._initAriaInfo();
+
+ //Hack the header height to include filter bar height;
+ g._getHeaderHeight = function(){
+ return old_func() + dojo.marginBox(_this.domNode).h;
+ };
+ //Define an area to make focusManager handle all the navigation stuff
+ g.focus.addArea({
+ name: "filterbar",
+ onFocus: dojo.hitch(this, this._onFocusFilterBar, false),
+ onBlur: dojo.hitch(this, this._onBlurFilterBar)
+ });
+ g.focus.placeArea("filterbar","after","header");
+ },
+ uninitialize: function(){
+ var g = this.plugin.grid;
+ g._getHeaderHeight = this.oldGetHeaderHeight;
+ g.focus.removeArea("filterbar");
+ this.plugin = null;
+ },
+ isFilterBarShown: function(){
+ return dojo.style(this.domNode, "display") != "none";
+ },
+ showFilterBar: function(toShow, useAnim, animArgs){
+ var g = this.plugin.grid;
+ if(useAnim){
+ if(Boolean(toShow) == this.isFilterBarShown()){ return; }
+ animArgs = animArgs || {};
+ var anims = [], defaultDuration = 500;
+ anims.push(dojo.fx[toShow ? "wipeIn" : "wipeOut"](dojo.mixin({
+ "node": this.domNode,
+ "duration": defaultDuration
+ }, animArgs)));
+ var curHeight = g.views.views[0].domNode.offsetHeight;
+ var prop = {
+ "duration": defaultDuration,
+ "properties": {
+ "height": {
+ "end": dojo.hitch(this, function(){
+ var barHeight = this.domNode.scrollHeight;
+ if(dojo.isFF){
+ barHeight -= 2;
+ }
+ return toShow ? (curHeight - barHeight) : (curHeight + barHeight);
+ })
+ }
+ }
+ };
+ dojo.forEach(g.views.views, function(view){
+ anims.push(dojo.animateProperty(dojo.mixin({
+ "node": view.domNode
+ }, prop, animArgs)), dojo.animateProperty(dojo.mixin({
+ "node": view.scrollboxNode
+ }, prop, animArgs)));
+ });
+ anims.push(dojo.animateProperty(dojo.mixin({
+ "node": g.viewsNode
+ }, prop, animArgs)));
+ dojo.fx.combine(anims).play();
+ }else{
+ dojo.style(this.domNode, "display", toShow ? "" : "none");
+ g.update();
+ }
+ },
+ toggleFilterBar: function(useAnim, animArgs){
+ this.showFilterBar(!this.isFilterBarShown(), useAnim, animArgs);
+ },
+ getColumnIdx: function(/* int */coordX){
+ var headers = dojo.query("[role='columnheader']", this.plugin.grid.viewsHeaderNode);
+ var idx = -1;
+ for(var i = headers.length - 1; i >= 0; --i){
+ var coord = dojo.coords(headers[i]);
+ if(coordX >= coord.x && coordX < coord.x + coord.w){
+ idx = i;
+ break;
+ }
+ }
+ if(idx >= 0 && this.plugin.grid.layout.cells[idx].filterable !== false){
+ return idx; //Integer
+ }else{
+ return -1; //Integer
+ }
+ },
+ toggleClearFilterBtn: function(toHide){
+ dojo.style(this.clearFilterButton.domNode, "display", toHide ? "none" : "");
+ },
+ _closeFilterBar: function(e){
+ _stopEvent(e);
+ var rulesCnt = this.plugin.filterDefDialog.getCriteria();
+ if(rulesCnt){
+ var handle = dojo.connect(this.plugin.filterDefDialog, "clearFilter", this, function(){
+ this.showFilterBar(false, true);
+ dojo.disconnect(handle);
+ });
+ this._clearFilterDefDialog(e);
+ }else{
+ this.showFilterBar(false, true);
+ }
+ },
+
+ _showFilterDefDialog: function(e){
+ _stopEvent(e);
+ this.plugin.filterDefDialog.showDialog(this._curColIdx);
+ this.plugin.grid.focus.focusArea("filterbar");
+ },
+ _clearFilterDefDialog: function(e){
+ _stopEvent(e);
+ this.plugin.filterDefDialog.onClearFilter();
+ this.plugin.grid.focus.focusArea("filterbar");
+ },
+ _onEnterButton: function(e){
+ //If mouse is hovering the btn, which means the user is about to click,
+ //we should not show status tip on the btn!
+ this._onBlurFilterBar();
+ _stopEvent(e);
+ },
+ _onMoveButton: function(e){
+ this._onBlurFilterBar();
+ },
+ _onLeaveButton: function(e){
+ this._leavingBtn = true;
+ },
+ _onShowFilterDefDialog: function(/* Integer */colIdx){
+ if(typeof colIdx == "number"){
+ this._curColIdx = colIdx;
+ }
+ this._defPaneIsShown = true;
+ },
+ _onCloseFilterDefDialog: function(){
+ this._defPaneIsShown = false;
+ //Do not remember what column are we on, so clicking the btn will show 'any column'
+ this._curColIdx = -1;
+ dijit.focus(this.defineFilterButton.domNode);
+ },
+ _onClickFilterBar: function(/* event */e){
+ _stopEvent(e);
+ this._clearStatusTipTimeout();
+ this.plugin.grid.focus.focusArea("filterbar");
+ this.plugin.filterDefDialog.showDialog(this.getColumnIdx(e.clientX));
+ },
+ _onMouseEnter: function(/* event */e){
+ this._onFocusFilterBar(true, null);
+ this._updateTipPosition(e);
+ this._setStatusTipTimeout();
+ },
+ _onMouseMove: function(/* event */e){
+ if(this._leavingBtn){
+ this._onFocusFilterBar(true, null);
+ this._leavingBtn = false;
+ }
+ if(this._isFocused){
+ this._setStatusTipTimeout();
+ this._highlightHeader(this.getColumnIdx(e.clientX));
+ if(this._handle_statusTooltip){
+ this._updateTipPosition(e);
+ }
+ }
+ },
+ _onMouseLeave: function(e){
+ this._onBlurFilterBar();
+ },
+ _updateTipPosition: function(evt){
+ this._tippos = {
+ x: evt.pageX,
+ y: evt.pageY
+ };
+ },
+ _onFocusFilterBar: function(highlightOnly, evt, step){
+ if(!this.isFilterBarShown()){
+ return false;
+ }
+ this._isFocused = true;
+ dojo.addClass(this.domNode,_focusClass);
+ if(!highlightOnly){
+ var hasFilter = dojo.style(this.clearFilterButton.domNode, "display") !== "none";
+ var hasCloseButton = dojo.style(this.closeFilterBarButton.domNode, "display") !== "none";
+ if(typeof this._focusPos == "undefined"){
+ if(step > 0){
+ this._focusPos = 0;
+ }else{
+ if(hasCloseButton){
+ this._focusPos = 1;
+ }else{
+ this._focusPos = 0;
+ }
+ if(hasFilter){
+ ++this._focusPos;
+ }
+ }
+ }
+ if(this._focusPos === 0){
+ dijit.focus(this.defineFilterButton.focusNode);
+ }else if(this._focusPos === 1 && hasFilter){
+ dijit.focus(this.clearFilterButton.focusNode);
+ }else{
+ dijit.focus(this.closeFilterBarButton.focusNode);
+ }
+ }
+ _stopEvent(evt);
+ return true;
+ },
+ _onBlurFilterBar: function(evt, step){
+ if(this._isFocused){
+ this._isFocused = false;
+ dojo.removeClass(this.domNode,_focusClass);
+ this._clearStatusTipTimeout();
+ this._clearHeaderHighlight();
+ }
+ var toBlur = true;
+ if(step){
+ var buttonCount = 3;
+ if(dojo.style(this.closeFilterBarButton.domNode, "display") === "none"){
+ --buttonCount;
+ }
+ if(dojo.style(this.clearFilterButton.domNode, "display") === "none"){
+ --buttonCount;
+ }
+ if(buttonCount == 1){
+ delete this._focusPos;
+ }else{
+ var current = this._focusPos;
+ for(var next = current + step; next < 0; next += buttonCount){}
+ next %= buttonCount;
+ if((step > 0 && next < current) || (step < 0 && next > current)){
+ delete this._focusPos;
+ }else{
+ this._focusPos = next;
+ toBlur = false;
+ }
+ }
+ }
+ return toBlur;
+ },
+ _onFiltered: function(/* int */filteredSize,/* int */originSize){
+ var p = this.plugin,
+ itemsName = p.args.itemsName || p.nls["defaultItemsName"],
+ msg = "", g = p.grid,
+ filterLayer = g.layer("filter");
+ if(filterLayer.filterDef()){
+ msg = dojo.string.substitute(p.nls["filterBarMsgHasFilterTemplate"], [filteredSize, originSize, itemsName]);
+ dojo.addClass(this.domNode, _filteredClass);
+ }else{
+ msg = dojo.string.substitute(p.nls["filterBarMsgNoFilterTemplate"], [originSize, itemsName]);
+ dojo.removeClass(this.domNode, _filteredClass);
+ }
+ this.statusBarNode.innerHTML = msg;
+ this._focusPos = 0;
+ },
+ _initAriaInfo: function(){
+ dijit.setWaiState(this.defineFilterButton.domNode, "label", this.plugin.nls["waiFilterBarDefButton"]);
+ dijit.setWaiState(this.clearFilterButton.domNode,"label", this.plugin.nls["waiFilterBarClearButton"]);
+ },
+ _isInColumn: function(/* int */mousePos_x, /* domNode */headerNode, /* int */colIndex){
+ var coord = dojo.coords(headerNode);
+ return mousePos_x >= coord.x && mousePos_x < coord.x + coord.w;
+ },
+ _setStatusTipTimeout: function(){
+ this._clearStatusTipTimeout();
+ if(!this._defPaneIsShown){
+ this._handle_statusTooltip = setTimeout(dojo.hitch(this,this._showStatusTooltip),this._timeout_statusTooltip);
+ }
+ },
+ _clearStatusTipTimeout: function(){
+ clearTimeout(this._handle_statusTooltip);
+ this._handle_statusTooltip = null;
+ },
+ _showStatusTooltip: function(){
+ this._handle_statusTooltip = null;
+ this.plugin.filterStatusTip.showDialog(this._tippos.x, this._tippos.y, this.getColumnIdx(this._tippos.x));
+ },
+ _highlightHeader: function(/* int */colIdx){
+ if(colIdx != this._previousHeaderIdx){
+ var g = this.plugin.grid,
+ cell = g.getCell(this._previousHeaderIdx);
+ if(cell){
+ dojo.removeClass(cell.getHeaderNode(), "dojoxGridCellOver");
+ }
+ cell = g.getCell(colIdx);
+ if(cell){
+ dojo.addClass(cell.getHeaderNode(), "dojoxGridCellOver");
+ }
+ this._previousHeaderIdx = colIdx;
+ }
+ },
+ _clearHeaderHighlight: function(){
+ if(typeof this._previousHeaderIdx != "undefined"){
+ var g = this.plugin.grid,
+ cell = g.getCell(this._previousHeaderIdx);
+ if(cell){
+ g.onHeaderCellMouseOut({
+ cellNode: cell.getHeaderNode()
+ });
+ }
+ delete this._previousHeaderIdx;
+ }
+ }
+});
+})();
+
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterBar.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterBar.xd.js
new file mode 100644
index 0000000..df88446
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterBar.xd.js
@@ -0,0 +1,387 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.filter.FilterBar"],
+["require", "dijit.form.Button"],
+["require", "dojo.string"],
+["require", "dojo.fx"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterBar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterBar"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter.FilterBar");
+
+dojo.require("dijit.form.Button");
+dojo.require("dojo.string");
+dojo.require("dojo.fx");
+
+(function(){
+var _focusClass = "dojoxGridFBarHover",
+ _filteredClass = "dojoxGridFBarFiltered",
+ _stopEvent = function(evt){
+ try{
+ if(evt && evt.preventDefault){
+ dojo.stopEvent(evt);
+ }
+ }catch(e){}
+ };
+
+dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, dijit._Templated],{
+ // summary:
+ // The filter bar UI.
+ templateString: dojo.cache("dojox.grid", "enhanced/templates/FilterBar.html", "<table class=\"dojoxGridFBar\" border=\"0\" cellspacing=\"0\" dojoAttachEvent=\"onclick:_onClickFilterBar, onmouseenter:_onMouseEnter, onmouseleave:_onMouseLeave, onmousemove:_onMouseMove\"\r\n\t><tr><td class=\"dojoxGridFBarBtnTD\"\r\n\t\t><span dojoType=\"dijit.form.Button\" class=\"dojoxGridFBarBtn\" dojoAttachPoint=\"defineFilterButton\" label=\"...\" iconClass=\"dojoxGridFBarDefFilterBtnIcon\" showLabel=\"true\" dojoAttachEvent=\"onClick:_showFilterDefDialog, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton\"></span\r\n\t></td><td class=\"dojoxGridFBarInfoTD\"\r\n\t\t><span class=\"dojoxGridFBarInner\"\r\n\t\t\t><span class=\"dojoxGridFBarStatus\" dojoAttachPoint=\"statusBarNode\">${_noFilterMsg}</span\r\n\t\t\t><span dojoType=\"dijit.form.Button\" class=\"dojoxGridFBarClearFilterBtn\" dojoAttachPoint=\"clearFilterButton\" \r\n\t\t\t\tlabel=\"${_filterBarClearBtnLabel}\" iconClass=\"dojoxGridFBarClearFilterBtnIcon\" showLabel=\"true\" \r\n\t\t\t\tdojoAttachEvent=\"onClick:_clearFilterDefDialog, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton\"></span\r\n\t\t\t><span dojotype=\"dijit.form.Button\" class=\"dojoxGridFBarCloseBtn\" dojoAttachPoint=\"closeFilterBarButton\" \r\n\t\t\t\tlabel=\"${_closeFilterBarBtnLabel}\" iconClass=\"dojoxGridFBarCloseBtnIcon\" showLabel=\"false\" \r\n\t\t\t\tdojoAttachEvent=\"onClick:_closeFilterBar, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton\"></span\r\n\t\t></span\r\n\t></td></tr\r\n></table>\r\n"),
+ widgetsInTemplate: true,
+
+ _timeout_statusTooltip: 300,
+ _handle_statusTooltip: null,
+ _curColIdx: -1,
+
+ plugin: null,
+ postMixInProperties: function(){
+ var plugin = this.plugin;
+ var nls = plugin.nls;
+ this._filterBarDefBtnLabel = nls["filterBarDefButton"];
+ this._filterBarClearBtnLabel = nls["filterBarClearButton"];
+ this._closeFilterBarBtnLabel = nls["closeFilterBarBtn"];
+ var itemsName = plugin.args.itemsName || nls["defaultItemsName"];
+ this._noFilterMsg = dojo.string.substitute(nls["filterBarMsgNoFilterTemplate"], ["", itemsName]);
+
+ var t = this.plugin.args.statusTipTimeout;
+ if(typeof t == 'number'){
+ this._timeout_statusTooltip = t;
+ }
+
+ var g = plugin.grid;
+ g.showFilterBar = dojo.hitch(this, "showFilterBar");
+ g.toggleFilterBar = dojo.hitch(this, "toggleFilterBar");
+ g.isFilterBarShown = dojo.hitch(this, "isFilterBarShown");
+ },
+ postCreate: function(){
+ this.inherited(arguments);
+ if(!this.plugin.args.closeFilterbarButton){
+ dojo.style(this.closeFilterBarButton.domNode, "display", "none");
+ }
+ var _this = this,
+ g = this.plugin.grid,
+ old_func = this.oldGetHeaderHeight = dojo.hitch(g,g._getHeaderHeight);
+
+ this.placeAt(g.viewsHeaderNode, "after");
+ this.connect(this.plugin.filterDefDialog, "showDialog", "_onShowFilterDefDialog");
+ this.connect(this.plugin.filterDefDialog, "closeDialog", "_onCloseFilterDefDialog");
+ this.connect(g.layer("filter"), "onFiltered", this._onFiltered);
+
+ this.defineFilterButton.domNode.title = this.plugin.nls["filterBarDefButton"];
+ if(dojo.hasClass(dojo.body(), "dijit_a11y")){
+ this.defineFilterButton.set("label", this.plugin.nls["a11yFilterBarDefButton"]);
+ }
+ this.connect(this.defineFilterButton.domNode, "click", _stopEvent);
+ this.connect(this.clearFilterButton.domNode, "click", _stopEvent);
+ this.connect(this.closeFilterBarButton.domNode, "click", _stopEvent);
+
+ this.toggleClearFilterBtn(true);
+ this._initAriaInfo();
+
+ //Hack the header height to include filter bar height;
+ g._getHeaderHeight = function(){
+ return old_func() + dojo.marginBox(_this.domNode).h;
+ };
+ //Define an area to make focusManager handle all the navigation stuff
+ g.focus.addArea({
+ name: "filterbar",
+ onFocus: dojo.hitch(this, this._onFocusFilterBar, false),
+ onBlur: dojo.hitch(this, this._onBlurFilterBar)
+ });
+ g.focus.placeArea("filterbar","after","header");
+ },
+ uninitialize: function(){
+ var g = this.plugin.grid;
+ g._getHeaderHeight = this.oldGetHeaderHeight;
+ g.focus.removeArea("filterbar");
+ this.plugin = null;
+ },
+ isFilterBarShown: function(){
+ return dojo.style(this.domNode, "display") != "none";
+ },
+ showFilterBar: function(toShow, useAnim, animArgs){
+ var g = this.plugin.grid;
+ if(useAnim){
+ if(Boolean(toShow) == this.isFilterBarShown()){ return; }
+ animArgs = animArgs || {};
+ var anims = [], defaultDuration = 500;
+ anims.push(dojo.fx[toShow ? "wipeIn" : "wipeOut"](dojo.mixin({
+ "node": this.domNode,
+ "duration": defaultDuration
+ }, animArgs)));
+ var curHeight = g.views.views[0].domNode.offsetHeight;
+ var prop = {
+ "duration": defaultDuration,
+ "properties": {
+ "height": {
+ "end": dojo.hitch(this, function(){
+ var barHeight = this.domNode.scrollHeight;
+ if(dojo.isFF){
+ barHeight -= 2;
+ }
+ return toShow ? (curHeight - barHeight) : (curHeight + barHeight);
+ })
+ }
+ }
+ };
+ dojo.forEach(g.views.views, function(view){
+ anims.push(dojo.animateProperty(dojo.mixin({
+ "node": view.domNode
+ }, prop, animArgs)), dojo.animateProperty(dojo.mixin({
+ "node": view.scrollboxNode
+ }, prop, animArgs)));
+ });
+ anims.push(dojo.animateProperty(dojo.mixin({
+ "node": g.viewsNode
+ }, prop, animArgs)));
+ dojo.fx.combine(anims).play();
+ }else{
+ dojo.style(this.domNode, "display", toShow ? "" : "none");
+ g.update();
+ }
+ },
+ toggleFilterBar: function(useAnim, animArgs){
+ this.showFilterBar(!this.isFilterBarShown(), useAnim, animArgs);
+ },
+ getColumnIdx: function(/* int */coordX){
+ var headers = dojo.query("[role='columnheader']", this.plugin.grid.viewsHeaderNode);
+ var idx = -1;
+ for(var i = headers.length - 1; i >= 0; --i){
+ var coord = dojo.coords(headers[i]);
+ if(coordX >= coord.x && coordX < coord.x + coord.w){
+ idx = i;
+ break;
+ }
+ }
+ if(idx >= 0 && this.plugin.grid.layout.cells[idx].filterable !== false){
+ return idx; //Integer
+ }else{
+ return -1; //Integer
+ }
+ },
+ toggleClearFilterBtn: function(toHide){
+ dojo.style(this.clearFilterButton.domNode, "display", toHide ? "none" : "");
+ },
+ _closeFilterBar: function(e){
+ _stopEvent(e);
+ var rulesCnt = this.plugin.filterDefDialog.getCriteria();
+ if(rulesCnt){
+ var handle = dojo.connect(this.plugin.filterDefDialog, "clearFilter", this, function(){
+ this.showFilterBar(false, true);
+ dojo.disconnect(handle);
+ });
+ this._clearFilterDefDialog(e);
+ }else{
+ this.showFilterBar(false, true);
+ }
+ },
+
+ _showFilterDefDialog: function(e){
+ _stopEvent(e);
+ this.plugin.filterDefDialog.showDialog(this._curColIdx);
+ this.plugin.grid.focus.focusArea("filterbar");
+ },
+ _clearFilterDefDialog: function(e){
+ _stopEvent(e);
+ this.plugin.filterDefDialog.onClearFilter();
+ this.plugin.grid.focus.focusArea("filterbar");
+ },
+ _onEnterButton: function(e){
+ //If mouse is hovering the btn, which means the user is about to click,
+ //we should not show status tip on the btn!
+ this._onBlurFilterBar();
+ _stopEvent(e);
+ },
+ _onMoveButton: function(e){
+ this._onBlurFilterBar();
+ },
+ _onLeaveButton: function(e){
+ this._leavingBtn = true;
+ },
+ _onShowFilterDefDialog: function(/* Integer */colIdx){
+ if(typeof colIdx == "number"){
+ this._curColIdx = colIdx;
+ }
+ this._defPaneIsShown = true;
+ },
+ _onCloseFilterDefDialog: function(){
+ this._defPaneIsShown = false;
+ //Do not remember what column are we on, so clicking the btn will show 'any column'
+ this._curColIdx = -1;
+ dijit.focus(this.defineFilterButton.domNode);
+ },
+ _onClickFilterBar: function(/* event */e){
+ _stopEvent(e);
+ this._clearStatusTipTimeout();
+ this.plugin.grid.focus.focusArea("filterbar");
+ this.plugin.filterDefDialog.showDialog(this.getColumnIdx(e.clientX));
+ },
+ _onMouseEnter: function(/* event */e){
+ this._onFocusFilterBar(true, null);
+ this._updateTipPosition(e);
+ this._setStatusTipTimeout();
+ },
+ _onMouseMove: function(/* event */e){
+ if(this._leavingBtn){
+ this._onFocusFilterBar(true, null);
+ this._leavingBtn = false;
+ }
+ if(this._isFocused){
+ this._setStatusTipTimeout();
+ this._highlightHeader(this.getColumnIdx(e.clientX));
+ if(this._handle_statusTooltip){
+ this._updateTipPosition(e);
+ }
+ }
+ },
+ _onMouseLeave: function(e){
+ this._onBlurFilterBar();
+ },
+ _updateTipPosition: function(evt){
+ this._tippos = {
+ x: evt.pageX,
+ y: evt.pageY
+ };
+ },
+ _onFocusFilterBar: function(highlightOnly, evt, step){
+ if(!this.isFilterBarShown()){
+ return false;
+ }
+ this._isFocused = true;
+ dojo.addClass(this.domNode,_focusClass);
+ if(!highlightOnly){
+ var hasFilter = dojo.style(this.clearFilterButton.domNode, "display") !== "none";
+ var hasCloseButton = dojo.style(this.closeFilterBarButton.domNode, "display") !== "none";
+ if(typeof this._focusPos == "undefined"){
+ if(step > 0){
+ this._focusPos = 0;
+ }else{
+ if(hasCloseButton){
+ this._focusPos = 1;
+ }else{
+ this._focusPos = 0;
+ }
+ if(hasFilter){
+ ++this._focusPos;
+ }
+ }
+ }
+ if(this._focusPos === 0){
+ dijit.focus(this.defineFilterButton.focusNode);
+ }else if(this._focusPos === 1 && hasFilter){
+ dijit.focus(this.clearFilterButton.focusNode);
+ }else{
+ dijit.focus(this.closeFilterBarButton.focusNode);
+ }
+ }
+ _stopEvent(evt);
+ return true;
+ },
+ _onBlurFilterBar: function(evt, step){
+ if(this._isFocused){
+ this._isFocused = false;
+ dojo.removeClass(this.domNode,_focusClass);
+ this._clearStatusTipTimeout();
+ this._clearHeaderHighlight();
+ }
+ var toBlur = true;
+ if(step){
+ var buttonCount = 3;
+ if(dojo.style(this.closeFilterBarButton.domNode, "display") === "none"){
+ --buttonCount;
+ }
+ if(dojo.style(this.clearFilterButton.domNode, "display") === "none"){
+ --buttonCount;
+ }
+ if(buttonCount == 1){
+ delete this._focusPos;
+ }else{
+ var current = this._focusPos;
+ for(var next = current + step; next < 0; next += buttonCount){}
+ next %= buttonCount;
+ if((step > 0 && next < current) || (step < 0 && next > current)){
+ delete this._focusPos;
+ }else{
+ this._focusPos = next;
+ toBlur = false;
+ }
+ }
+ }
+ return toBlur;
+ },
+ _onFiltered: function(/* int */filteredSize,/* int */originSize){
+ var p = this.plugin,
+ itemsName = p.args.itemsName || p.nls["defaultItemsName"],
+ msg = "", g = p.grid,
+ filterLayer = g.layer("filter");
+ if(filterLayer.filterDef()){
+ msg = dojo.string.substitute(p.nls["filterBarMsgHasFilterTemplate"], [filteredSize, originSize, itemsName]);
+ dojo.addClass(this.domNode, _filteredClass);
+ }else{
+ msg = dojo.string.substitute(p.nls["filterBarMsgNoFilterTemplate"], [originSize, itemsName]);
+ dojo.removeClass(this.domNode, _filteredClass);
+ }
+ this.statusBarNode.innerHTML = msg;
+ this._focusPos = 0;
+ },
+ _initAriaInfo: function(){
+ dijit.setWaiState(this.defineFilterButton.domNode, "label", this.plugin.nls["waiFilterBarDefButton"]);
+ dijit.setWaiState(this.clearFilterButton.domNode,"label", this.plugin.nls["waiFilterBarClearButton"]);
+ },
+ _isInColumn: function(/* int */mousePos_x, /* domNode */headerNode, /* int */colIndex){
+ var coord = dojo.coords(headerNode);
+ return mousePos_x >= coord.x && mousePos_x < coord.x + coord.w;
+ },
+ _setStatusTipTimeout: function(){
+ this._clearStatusTipTimeout();
+ if(!this._defPaneIsShown){
+ this._handle_statusTooltip = setTimeout(dojo.hitch(this,this._showStatusTooltip),this._timeout_statusTooltip);
+ }
+ },
+ _clearStatusTipTimeout: function(){
+ clearTimeout(this._handle_statusTooltip);
+ this._handle_statusTooltip = null;
+ },
+ _showStatusTooltip: function(){
+ this._handle_statusTooltip = null;
+ this.plugin.filterStatusTip.showDialog(this._tippos.x, this._tippos.y, this.getColumnIdx(this._tippos.x));
+ },
+ _highlightHeader: function(/* int */colIdx){
+ if(colIdx != this._previousHeaderIdx){
+ var g = this.plugin.grid,
+ cell = g.getCell(this._previousHeaderIdx);
+ if(cell){
+ dojo.removeClass(cell.getHeaderNode(), "dojoxGridCellOver");
+ }
+ cell = g.getCell(colIdx);
+ if(cell){
+ dojo.addClass(cell.getHeaderNode(), "dojoxGridCellOver");
+ }
+ this._previousHeaderIdx = colIdx;
+ }
+ },
+ _clearHeaderHighlight: function(){
+ if(typeof this._previousHeaderIdx != "undefined"){
+ var g = this.plugin.grid,
+ cell = g.getCell(this._previousHeaderIdx);
+ if(cell){
+ g.onHeaderCellMouseOut({
+ cellNode: cell.getHeaderNode()
+ });
+ }
+ delete this._previousHeaderIdx;
+ }
+ }
+});
+})();
+
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterBuilder.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterBuilder.js
new file mode 100644
index 0000000..7231252
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterBuilder.js
@@ -0,0 +1,89 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterBuilder"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterBuilder"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter.FilterBuilder");
+dojo.require("dojox.grid.enhanced.plugins.filter._FilterExpr");
+
+(function(){
+var fns = dojox.grid.enhanced.plugins.filter,
+ bdr = function(opCls){
+ return dojo.partial(function(cls,operands){
+ return new fns[cls](operands);
+ },opCls);
+ },
+ bdr_not = function(opCls){
+ return dojo.partial(function(cls,operands){
+ return new fns.LogicNOT(new fns[cls](operands));
+ },opCls);
+ };
+dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBuilder", null, {
+ // summary:
+ // Create filter expression from a JSON object.
+ buildExpression: function(def){
+ if("op" in def){
+ return this.supportedOps[def.op.toLowerCase()](dojo.map(def.data, this.buildExpression, this));
+ }else{
+ var args = dojo.mixin(this.defaultArgs[def.datatype], def.args || {});
+ return new this.supportedTypes[def.datatype](def.data, def.isColumn, args);
+ }
+ },
+ supportedOps: {
+ // summary:
+ // The builders of all supported operations
+ "equalto": bdr("EqualTo"),
+ "lessthan": bdr("LessThan"),
+ "lessthanorequalto": bdr("LessThanOrEqualTo"),
+ "largerthan": bdr("LargerThan"),
+ "largerthanorequalto": bdr("LargerThanOrEqualTo"),
+ "contains": bdr("Contains"),
+ "startswith": bdr("StartsWith"),
+ "endswith": bdr("EndsWith"),
+ "notequalto": bdr_not("EqualTo"),
+ "notcontains": bdr_not("Contains"),
+ "notstartswith": bdr_not("StartsWith"),
+ "notendswith": bdr_not("EndsWith"),
+ "isempty": bdr("IsEmpty"),
+ "range": function(operands){
+ return new fns.LogicALL(
+ new fns.LargerThanOrEqualTo(operands.slice(0,2)),
+ new fns.LessThanOrEqualTo(operands[0], operands[2])
+ );
+ },
+ "logicany": bdr("LogicANY"),
+ "logicall": bdr("LogicALL")
+ },
+ supportedTypes: {
+ "number": fns.NumberExpr,
+ "string": fns.StringExpr,
+ "boolean": fns.BooleanExpr,
+ "date": fns.DateExpr,
+ "time": fns.TimeExpr
+ },
+ defaultArgs: {
+ "boolean": {
+ "falseValue": "false",
+ "convert": function(dataValue, args){
+ var falseValue = args.falseValue;
+ var trueValue = args.trueValue;
+ if(dojo.isString(dataValue)){
+ if(trueValue && dataValue.toLowerCase() == trueValue){
+ return true;
+ }
+ if(falseValue && dataValue.toLowerCase() == falseValue){
+ return false;
+ }
+ }
+ return !!dataValue;
+ }
+ }
+ }
+});
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterBuilder.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterBuilder.xd.js
new file mode 100644
index 0000000..c8c8cdb
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterBuilder.xd.js
@@ -0,0 +1,94 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.filter.FilterBuilder"],
+["require", "dojox.grid.enhanced.plugins.filter._FilterExpr"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterBuilder"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterBuilder"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter.FilterBuilder");
+dojo.require("dojox.grid.enhanced.plugins.filter._FilterExpr");
+
+(function(){
+var fns = dojox.grid.enhanced.plugins.filter,
+ bdr = function(opCls){
+ return dojo.partial(function(cls,operands){
+ return new fns[cls](operands);
+ },opCls);
+ },
+ bdr_not = function(opCls){
+ return dojo.partial(function(cls,operands){
+ return new fns.LogicNOT(new fns[cls](operands));
+ },opCls);
+ };
+dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBuilder", null, {
+ // summary:
+ // Create filter expression from a JSON object.
+ buildExpression: function(def){
+ if("op" in def){
+ return this.supportedOps[def.op.toLowerCase()](dojo.map(def.data, this.buildExpression, this));
+ }else{
+ var args = dojo.mixin(this.defaultArgs[def.datatype], def.args || {});
+ return new this.supportedTypes[def.datatype](def.data, def.isColumn, args);
+ }
+ },
+ supportedOps: {
+ // summary:
+ // The builders of all supported operations
+ "equalto": bdr("EqualTo"),
+ "lessthan": bdr("LessThan"),
+ "lessthanorequalto": bdr("LessThanOrEqualTo"),
+ "largerthan": bdr("LargerThan"),
+ "largerthanorequalto": bdr("LargerThanOrEqualTo"),
+ "contains": bdr("Contains"),
+ "startswith": bdr("StartsWith"),
+ "endswith": bdr("EndsWith"),
+ "notequalto": bdr_not("EqualTo"),
+ "notcontains": bdr_not("Contains"),
+ "notstartswith": bdr_not("StartsWith"),
+ "notendswith": bdr_not("EndsWith"),
+ "isempty": bdr("IsEmpty"),
+ "range": function(operands){
+ return new fns.LogicALL(
+ new fns.LargerThanOrEqualTo(operands.slice(0,2)),
+ new fns.LessThanOrEqualTo(operands[0], operands[2])
+ );
+ },
+ "logicany": bdr("LogicANY"),
+ "logicall": bdr("LogicALL")
+ },
+ supportedTypes: {
+ "number": fns.NumberExpr,
+ "string": fns.StringExpr,
+ "boolean": fns.BooleanExpr,
+ "date": fns.DateExpr,
+ "time": fns.TimeExpr
+ },
+ defaultArgs: {
+ "boolean": {
+ "falseValue": "false",
+ "convert": function(dataValue, args){
+ var falseValue = args.falseValue;
+ var trueValue = args.trueValue;
+ if(dojo.isString(dataValue)){
+ if(trueValue && dataValue.toLowerCase() == trueValue){
+ return true;
+ }
+ if(falseValue && dataValue.toLowerCase() == falseValue){
+ return false;
+ }
+ }
+ return !!dataValue;
+ }
+ }
+ }
+});
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js
new file mode 100644
index 0000000..40880ac
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js
@@ -0,0 +1,1236 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterDefDialog"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterDefDialog"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter.FilterDefDialog");
+
+dojo.require("dijit.dijit");
+dojo.require("dijit.Tooltip");
+dojo.require("dojox.grid.enhanced.plugins.Dialog");
+dojo.require("dijit.form.ComboBox");
+dojo.require("dijit.form.Select");
+dojo.require("dijit.form.TextBox");
+dojo.require("dijit.form.CheckBox");
+dojo.require("dijit.form.NumberTextBox");
+dojo.require("dijit.form.DateTextBox");
+dojo.require("dijit.form.TimeTextBox");
+dojo.require("dijit.form.Button");
+dojo.require("dijit.layout.AccordionContainer");
+dojo.require("dijit.layout.ContentPane");
+dojo.require("dojo.date.locale");
+dojo.require("dojo.string");
+dojo.require("dojox.grid.enhanced.plugins.filter.FilterBuilder");
+dojo.require("dojox.grid.cells.dijit");
+dojo.require("dojox.html.ellipsis");
+dojo.require("dojox.html.metrics");
+dojo.require("dojo.window");
+
+(function(){
+var fns = dojox.grid.enhanced.plugins.filter,
+ _tabIdxes = {
+ // summary:
+ // Define tabindexes for elements in the filter definition dialog
+ relSelect: 60,
+ accordionTitle: 70,
+ removeCBoxBtn: -1,
+ colSelect: 90,
+ condSelect: 95,
+ valueBox: 10,
+ addCBoxBtn: 20,
+ filterBtn: 30,
+ clearBtn: 40,
+ cancelBtn: 50
+ };
+dojo.declare("dojox.grid.enhanced.plugins.filter.FilterDefDialog", null, {
+ // summary:
+ // Create the filter definition UI.
+ curColIdx: -1,
+ _relOpCls: "logicall",
+ _savedCriterias: null,
+ plugin: null,
+ constructor: function(args){
+ var plugin = this.plugin = args.plugin;
+ this.builder = new fns.FilterBuilder();
+ this._setupData();
+ this._cboxes = [];
+ this.defaultType = plugin.args.defaultType || "string";
+
+ (this.filterDefPane = new fns.FilterDefPane({
+ "dlg": this
+ })).startup();
+ (this._defPane = new dojox.grid.enhanced.plugins.Dialog({
+ "refNode": this.plugin.grid.domNode,
+ "title": plugin.nls.filterDefDialogTitle,
+ "class": "dojoxGridFDTitlePane",
+ "iconClass": "dojoxGridFDPaneIcon",
+ "content": this.filterDefPane
+ })).startup();
+
+ this._defPane.connect(plugin.grid.layer('filter'), "filterDef", dojo.hitch(this, "_onSetFilter"));
+ plugin.grid.setFilter = dojo.hitch(this, "setFilter");
+ plugin.grid.getFilter = dojo.hitch(this, "getFilter");
+ plugin.grid.getFilterRelation = dojo.hitch(this, function(){
+ return this._relOpCls;
+ });
+
+ plugin.connect(plugin.grid.layout, "moveColumn", dojo.hitch(this, "onMoveColumn"));
+ },
+ onMoveColumn: function(sourceViewIndex, destViewIndex, cellIndex, targetIndex, before){
+ if(this._savedCriterias && cellIndex != targetIndex){
+ if(before){ --targetIndex; }
+ var min = cellIndex < targetIndex ? cellIndex : targetIndex;
+ var max = cellIndex < targetIndex ? targetIndex : cellIndex;
+ var dir = targetIndex > min ? 1 : -1;
+ dojo.forEach(this._savedCriterias, function(sc){
+ var idx = parseInt(sc.column, 10);
+ if(!isNaN(idx) && idx >= min && idx <= max){
+ sc.column = String(idx == cellIndex ? idx + (max - min) * dir : idx - dir);
+ }
+ });
+ }
+ },
+ destroy: function(){
+ this._defPane.destroyRecursive();
+ this._defPane = null;
+ this.filterDefPane = null;
+ this.builder = null;
+ this._dataTypeMap = null;
+ this._cboxes = null;
+ var g = this.plugin.grid;
+ g.setFilter = null;
+ g.getFilter = null;
+ g.getFilterRelation = null;
+ this.plugin = null;
+ },
+ _setupData: function(){
+ var nls = this.plugin.nls;
+ this._dataTypeMap = {
+ // summary:
+ // All supported data types
+ "number":{
+ valueBoxCls: {
+ dft: dijit.form.NumberTextBox
+ },
+ conditions:[
+ {label: nls.conditionEqual, value: "equalto", selected: true},
+ {label: nls.conditionNotEqual, value: "notequalto"},
+ {label: nls.conditionLess, value: "lessthan"},
+ {label: nls.conditionLessEqual, value: "lessthanorequalto"},
+ {label: nls.conditionLarger, value: "largerthan"},
+ {label: nls.conditionLargerEqual, value: "largerthanorequalto"},
+ {label: nls.conditionIsEmpty, value: "isempty"}
+ ]
+ },
+ "string":{
+ valueBoxCls: {
+ dft: dijit.form.TextBox,
+ ac: fns.UniqueComboBox //For autoComplete
+ },
+ conditions:[
+ {label: nls.conditionContains, value: "contains", selected: true},
+ {label: nls.conditionIs, value: "equalto"},
+ {label: nls.conditionStartsWith, value: "startswith"},
+ {label: nls.conditionEndWith, value: "endswith"},
+ {label: nls.conditionNotContain, value: "notcontains"},
+ {label: nls.conditionIsNot, value: "notequalto"},
+ {label: nls.conditionNotStartWith, value: "notstartswith"},
+ {label: nls.conditionNotEndWith, value: "notendswith"},
+ {label: nls.conditionIsEmpty, value: "isempty"}
+ ]
+ },
+ "date":{
+ valueBoxCls: {
+ dft: dijit.form.DateTextBox
+ },
+ conditions:[
+ {label: nls.conditionIs, value: "equalto", selected: true},
+ {label: nls.conditionBefore, value: "lessthan"},
+ {label: nls.conditionAfter, value: "largerthan"},
+ {label: nls.conditionRange, value: "range"},
+ {label: nls.conditionIsEmpty, value: "isempty"}
+ ]
+ },
+ "time":{
+ valueBoxCls: {
+ dft: dijit.form.TimeTextBox
+ },
+ conditions:[
+ {label: nls.conditionIs, value: "equalto", selected: true},
+ {label: nls.conditionBefore, value: "lessthan"},
+ {label: nls.conditionAfter, value: "largerthan"},
+ {label: nls.conditionRange, value: "range"},
+ {label: nls.conditionIsEmpty, value: "isempty"}
+ ]
+ },
+ "boolean": {
+ valueBoxCls: {
+ dft: fns.BooleanValueBox
+ },
+ conditions: [
+ {label: nls.conditionIs, value: "equalto", selected: true},
+ {label: nls.conditionIsEmpty, value: "isempty"}
+ ]
+ }
+ };
+ },
+ setFilter: function(rules, ruleRelation){
+ rules = rules || [];
+ if(!dojo.isArray(rules)){
+ rules = [rules];
+ }
+ var func = function(){
+ if(rules.length){
+ this._savedCriterias = dojo.map(rules, function(rule){
+ var type = rule.type || this.defaultType;
+ return {
+ "type": type,
+ "column": String(rule.column),
+ "condition": rule.condition,
+ "value": rule.value,
+ "colTxt": this.getColumnLabelByValue(String(rule.column)),
+ "condTxt": this.getConditionLabelByValue(type, rule.condition),
+ "formattedVal": rule.formattedVal || rule.value
+ };
+ }, this);
+ this._criteriasChanged = true;
+ if(ruleRelation === "logicall" || ruleRelation === "logicany"){
+ this._relOpCls = ruleRelation;
+ }
+ var exprs = dojo.map(rules, this.getExprForCriteria, this);
+ exprs = this.builder.buildExpression(exprs.length == 1 ? exprs[0] : {
+ "op": this._relOpCls,
+ "data": exprs
+ });
+ this.plugin.grid.layer("filter").filterDef(exprs);
+ this.plugin.filterBar.toggleClearFilterBtn(false);
+ }
+ this._closeDlgAndUpdateGrid();
+ };
+ if(this._savedCriterias){
+ this._clearWithoutRefresh = true;
+ var handle = dojo.connect(this, "clearFilter", this, function(){
+ dojo.disconnect(handle);
+ this._clearWithoutRefresh = false;
+ func.apply(this);
+ });
+ this.onClearFilter();
+ }else{
+ func.apply(this);
+ }
+ },
+ getFilter: function(){
+ return dojo.clone(this._savedCriterias) || [];
+ },
+ getColumnLabelByValue: function(v){
+ var nls = this.plugin.nls;
+ if(v.toLowerCase() == "anycolumn"){
+ return nls["anyColumnOption"];
+ }else{
+ var cell = this.plugin.grid.layout.cells[parseInt(v, 10)];
+ return cell ? (cell.name || cell.field) : "";
+ }
+ },
+ getConditionLabelByValue: function(type, c){
+ var conditions = this._dataTypeMap[type].conditions;
+ for(var i = conditions.length - 1; i >= 0; --i){
+ var cond = conditions[i];
+ if(cond.value == c.toLowerCase()){
+ return cond.label;
+ }
+ }
+ return "";
+ },
+ addCriteriaBoxes: function(/* int */cnt){
+ // summary:
+ // Add *cnt* criteria boxes to the filter definition pane.
+ // Check overflow if necessary.
+ if(typeof cnt != "number" || cnt <= 0){
+ return;
+ }
+ var cbs = this._cboxes,
+ cc = this.filterDefPane.cboxContainer,
+ total = this.plugin.args.ruleCount,
+ len = cbs.length, cbox;
+ //If overflow, add to max rule count.
+ if(total > 0 && len + cnt > total){
+ cnt = total - len;
+ }
+ for(; cnt > 0; --cnt){
+ cbox = new fns.CriteriaBox({
+ dlg: this
+ });
+ cbs.push(cbox);
+ cc.addChild(cbox);
+ }
+ //If there's no content box in it , AccordionContainer can not startup
+ cc.startup();
+ this._updatePane();
+ this._updateCBoxTitles();
+ cc.selectChild(cbs[cbs.length-1]);
+ //Asign an impossibly large scrollTop to scroll the criteria pane to the bottom.
+ this.filterDefPane.criteriaPane.scrollTop = 1000000;
+ if(cbs.length === 4){
+ if(dojo.isIE <= 6 && !this.__alreadyResizedForIE6){
+ var size = dojo.position(cc.domNode);
+ size.w -= dojox.html.metrics.getScrollbar().w;
+ cc.resize(size);
+ this.__alreadyResizedForIE6 = true;
+ }else{
+ cc.resize();
+ }
+ }
+ },
+ removeCriteriaBoxes: function(/* int|CriteriaBox|int[] */cnt,/* bool? */isIdx){
+ // summary:
+ // Remove criteria boxes from the filter definition pane.
+ var cbs = this._cboxes, cc = this.filterDefPane.cboxContainer,
+ len = cbs.length, start = len - cnt,
+ end = len - 1, cbox,
+ curIdx = dojo.indexOf(cbs, cc.selectedChildWidget.content);
+ if(dojo.isArray(cnt)){
+ var i, idxes = cnt;
+ idxes.sort();
+ cnt = idxes.length;
+ //find a rule that's not deleted.
+ //must find and focus the last one, or the hack will not work.
+ for(i = len - 1; i >= 0 && dojo.indexOf(idxes, i) >= 0; --i){}
+ if(i >= 0){
+ //must select before remove
+ if(i != curIdx){
+ cc.selectChild(cbs[i]);
+ }
+ //idxes is sorted from small to large,
+ //so travel reversely won't need change index after delete from array.
+ for(i = cnt-1; i >= 0; --i){
+ if(idxes[i] >= 0 && idxes[i] < len){
+ cc.removeChild(cbs[idxes[i]]);
+ cbs.splice(idxes[i],1);
+ }
+ }
+ }
+ start = cbs.length;
+ }else{
+ if(isIdx === true){
+ if(cnt >= 0 && cnt < len){
+ start = end = cnt;
+ cnt = 1;
+ }else{
+ return;
+ }
+ }else{
+ if(cnt instanceof fns.CriteriaBox){
+ cbox = cnt;
+ cnt = 1;
+ start = end = dojo.indexOf(cbs, cbox);
+ }else if(typeof cnt != "number" || cnt <= 0){
+ return;
+ }else if(cnt >= len){
+ cnt = end;
+ start = 1;
+ }
+ }
+ if(end < start){
+ return;
+ }
+ //must select before remove
+ if(curIdx >= start && curIdx <= end){
+ cc.selectChild(cbs[start ? start-1 : end+1]);
+ }
+ for(; end >= start; --end){
+ cc.removeChild(cbs[end]);
+ }
+ cbs.splice(start, cnt);
+ }
+ this._updatePane();
+ this._updateCBoxTitles();
+ if(cbs.length === 3){
+ //In ie6, resize back to the normal width will cause the title button look strange.
+ cc.resize();
+ }
+ },
+ getCriteria: function(/* int */idx){
+ // summary:
+ // Get the *idx*-th criteria.
+ if(typeof idx != "number"){
+ return this._savedCriterias ? this._savedCriterias.length : 0;
+ }
+ if(this._savedCriterias && this._savedCriterias[idx]){
+ return dojo.mixin({
+ relation: this._relOpCls == "logicall" ? this.plugin.nls.and : this.plugin.nls.or
+ },this._savedCriterias[idx]);
+ }
+ return null;
+ },
+ getExprForCriteria: function(rule){
+ if(rule.column == "anycolumn"){
+ var cells = dojo.filter(this.plugin.grid.layout.cells, function(cell){
+ return !(cell.filterable === false || cell.hidden);
+ });
+ return {
+ "op": "logicany",
+ "data": dojo.map(cells, function(cell){
+ return this.getExprForColumn(rule.value, cell.index, rule.type, rule.condition);
+ }, this)
+ };
+ }else{
+ return this.getExprForColumn(rule.value, rule.column, rule.type, rule.condition);
+ }
+ },
+ getExprForColumn: function(value, colIdx, type, condition){
+ colIdx = parseInt(colIdx, 10);
+ var cell = this.plugin.grid.layout.cells[colIdx],
+ colName = cell.field || cell.name,
+ obj = {
+ "datatype": type || this.getColumnType(colIdx),
+ "args": cell.dataTypeArgs,
+ "isColumn": true
+ },
+ operands = [dojo.mixin({"data": this.plugin.args.isServerSide ? colName : cell}, obj)];
+ obj.isColumn = false;
+ if(condition == "range"){
+ operands.push(dojo.mixin({"data": value.start}, obj),
+ dojo.mixin({"data": value.end}, obj));
+ }else if(condition != "isempty"){
+ operands.push(dojo.mixin({"data": value}, obj));
+ }
+ return {
+ "op": condition,
+ "data": operands
+ };
+ },
+ getColumnType: function(/* int */colIndex){
+ var cell = this.plugin.grid.layout.cells[parseInt(colIndex, 10)];
+ if(!cell || !cell.datatype){
+ return this.defaultType;
+ }
+ var type = String(cell.datatype).toLowerCase();
+ return this._dataTypeMap[type] ? type : this.defaultType;
+ },
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////
+ clearFilter: function(noRefresh){
+ // summary:
+ // Clear filter definition.
+ if(!this._savedCriterias){
+ return;
+ }
+ this._savedCriterias = null;
+ this.plugin.grid.layer("filter").filterDef(null);
+ try{
+ this.plugin.filterBar.toggleClearFilterBtn(true);
+ this.filterDefPane._clearFilterBtn.set("disabled", true);
+ this.removeCriteriaBoxes(this._cboxes.length-1);
+ this._cboxes[0].load({});
+ }catch(e){
+ //Any error means the filter is defined outside this plugin.
+ }
+ if(noRefresh){
+ this.closeDialog();
+ }else{
+ this._closeDlgAndUpdateGrid();
+ }
+ },
+ showDialog: function(/* int */colIndex){
+ // summary:
+ // Show the filter defintion dialog.
+ this._defPane.show();
+ this.plugin.filterStatusTip.closeDialog();
+ this._prepareDialog(colIndex);
+ },
+ closeDialog: function(){
+ // summary:
+ // Close the filter definition dialog.
+ this._defPane.hide();
+ },
+ onFilter: function(e){
+ // summary:
+ // Triggered when the "Filter" button is clicked.
+ if(this.canFilter()){
+ this._defineFilter();
+ this._closeDlgAndUpdateGrid();
+ this.plugin.filterBar.toggleClearFilterBtn(false);
+ }
+ },
+ onClearFilter: function(e){
+ // summary:
+ // Triggered when the "Clear" button is clicked.
+ if(this._savedCriterias){
+ if(this._savedCriterias.length > 1){
+ this.plugin.clearFilterDialog.show();
+ }else{
+ this.clearFilter(this._clearWithoutRefresh);
+ }
+ }
+ },
+ onCancel: function(e){
+ // summary:
+ // Triggered when the "Cancel" buttton is clicked.
+ var sc = this._savedCriterias;
+ var cbs = this._cboxes;
+ if(sc){
+ this.addCriteriaBoxes(sc.length - cbs.length);
+ this.removeCriteriaBoxes(cbs.length - sc.length);
+ dojo.forEach(sc, function(c, i){
+ cbs[i].load(c);
+ });
+ }else{
+ this.removeCriteriaBoxes(cbs.length - 1);
+ cbs[0].load({});
+ }
+ this.closeDialog();
+ },
+ onRendered: function(cbox){
+ // summary:
+ // Triggered when the rendering of the filter definition dialog is completely finished.
+ // cbox:
+ // Current visible criteria box
+ if(!dojo.isFF){
+ var elems = dijit._getTabNavigable(dojo.byId(cbox.domNode));
+ dijit.focus(elems.lowest || elems.first);
+ }else{
+ var dp = this._defPane;
+ dp._getFocusItems(dp.domNode);
+ dijit.focus(dp._firstFocusItem);
+ }
+ },
+ _onSetFilter: function(filterDef){
+ // summary:
+ // If someone clear the filter def in the store directly, we must clear it in the UI.
+ // If someone defines a filter, don't know how to handle it!
+ if(filterDef === null && this._savedCriterias){
+ this.clearFilter();
+ }
+ },
+ _prepareDialog: function(/* int */colIndex){
+ var sc = this._savedCriterias,
+ cbs = this._cboxes, i, cbox,
+ columnChanged = this.curColIdx != colIndex;
+ this.curColIdx = colIndex;
+ if(!sc){
+ if(cbs.length === 0){
+ this.addCriteriaBoxes(1);
+ }else if(columnChanged){
+ for(i = 0; (cbox = cbs[i]); ++i){
+ cbox.changeCurrentColumn();
+ }
+ }
+ }else if(this._criteriasChanged){
+ this.filterDefPane._relSelect.set("value", this._relOpCls === "logicall" ? "0" : "1");
+ this._criteriasChanged = false;
+ var needNewCBox = sc.length > cbs.length;
+ this.addCriteriaBoxes(sc.length - cbs.length);
+ this.removeCriteriaBoxes(cbs.length - sc.length);
+ this.filterDefPane._clearFilterBtn.set("disabled", false);
+ if(needNewCBox){
+ dojo.forEach(sc, function(c, i){
+ var handle = dojo.connect(this, "onRendered", function(cbox){
+ if(cbox == cbs[i]){
+ dojo.disconnect(handle);
+ cbox.load(c);
+ }
+ });
+ }, this);
+ }else{
+ for(i = 0; i < sc.length; ++i){
+ cbs[i].load(sc[i]);
+ }
+ }
+ }
+ //Since we're allowed to remove cboxes when the definition pane is not shown,
+ //we have to resize the container to have a correct _verticalSpace.
+ this.filterDefPane.cboxContainer.resize();
+ },
+ _defineFilter: function(){
+ var cbs = this._cboxes,
+ filterCboxes = function(method){
+ return dojo.filter(dojo.map(cbs, function(cbox){
+ return cbox[method]();
+ }), function(result){
+ return !!result;
+ });
+ },
+ exprs = filterCboxes("getExpr");
+ this._savedCriterias = filterCboxes("save");
+ exprs = exprs.length == 1 ? exprs[0] : {
+ "op": this._relOpCls,
+ "data": exprs
+ };
+ exprs = this.builder.buildExpression(exprs);
+
+ this.plugin.grid.layer("filter").filterDef(exprs);
+ this.filterDefPane._clearFilterBtn.set("disabled", false);
+ },
+ _updateCBoxTitles: function(){
+ for(var cbs = this._cboxes, i = cbs.length; i > 0; --i){
+ cbs[i - 1].updateRuleIndex(i);
+ cbs[i - 1].setAriaInfo(i);
+ }
+ },
+ _updatePane: function(){
+ var cbs = this._cboxes,
+ defPane = this.filterDefPane;
+ defPane._addCBoxBtn.set("disabled", cbs.length == this.plugin.args.ruleCount);
+ defPane._filterBtn.set("disabled", !this.canFilter());
+ },
+ canFilter: function(){
+ return dojo.filter(this._cboxes, function(cbox){
+ return !cbox.isEmpty();
+ }).length > 0;
+ },
+ _closeDlgAndUpdateGrid: function(){
+ this.closeDialog();
+ var g = this.plugin.grid;
+ g.showMessage(g.loadingMessage);
+ setTimeout(dojo.hitch(g, g._refresh), this._defPane.duration + 10);
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter.FilterDefPane",[dijit._Widget,dijit._Templated],{
+ templateString: dojo.cache("dojox.grid", "enhanced/templates/FilterDefPane.html", "<div class=\"dojoxGridFDPane\">\r\n\t<div class=\"dojoxGridFDPaneRelation\">${_relMsgFront}\r\n\t<span class=\"dojoxGridFDPaneModes\" dojoAttachPoint=\"criteriaModeNode\">\r\n\t\t<select dojoAttachPoint=\"_relSelect\" dojoType=\"dijit.form.Select\" dojoAttachEvent=\"onChange: _onRelSelectChange\">\r\n\t\t\t<option value=\"0\">${_relAll}</option>\r\n\t\t\t<option value=\"1\">${_relAny}</option>\r\n\t\t</select>\r\n\t</span>\r\n\t${_relMsgTail}\r\n\t</div>\r\n\t<div dojoAttachPoint=\"criteriaPane\" class=\"dojoxGridFDPaneRulePane\"></div>\r\n\t<div dojoAttachPoint=\"_addCBoxBtn\" dojoType=\"dijit.form.Button\" \r\n\t\tclass=\"dojoxGridFDPaneAddCBoxBtn\" iconClass=\"dojoxGridFDPaneAddCBoxBtnIcon\"\r\n\t\tdojoAttachEvent=\"onClick:_onAddCBox\" label=\"${_addRuleBtnLabel}\" showLabel=\"false\">\r\n\t</div>\r\n\t<div class=\"dojoxGridFDPaneBtns\" dojoAttachPoint=\"buttonsPane\">\r\n\t\t<span dojoAttachPoint=\"_cancelBtn\" dojoType=\"dijit.form.Button\" \r\n\t\t\tdojoAttachEvent=\"onClick:_onCancel\" label=\"${_cancelBtnLabel}\">\r\n\t\t</span>\r\n\t\t<span dojoAttachPoint=\"_clearFilterBtn\" dojoType=\"dijit.form.Button\" \r\n\t\t\tdojoAttachEvent=\"onClick:_onClearFilter\" label=\"${_clearBtnLabel}\" disabled=\"true\">\r\n\t\t</span>\r\n\t\t<span dojoAttachPoint=\"_filterBtn\" dojoType=\"dijit.form.Button\" \r\n\t\t\tdojoAttachEvent=\"onClick:_onFilter\" label=\"${_filterBtnLabel}\" disabled=\"true\">\r\n\t\t</span>\r\n\t</div>\r\n</div>\r\n"),
+ widgetsInTemplate: true,
+ dlg: null,
+ postMixInProperties: function(){
+ this.plugin = this.dlg.plugin;
+ var nls = this.plugin.nls;
+ this._addRuleBtnLabel = nls.addRuleButton;
+ this._cancelBtnLabel = nls.cancelButton;
+ this._clearBtnLabel = nls.clearButton;
+ this._filterBtnLabel = nls.filterButton;
+ this._relAll = nls.relationAll;
+ this._relAny = nls.relationAny;
+ this._relMsgFront = nls.relationMsgFront;
+ this._relMsgTail = nls.relationMsgTail;
+ },
+ postCreate: function(){
+ this.inherited(arguments);
+ this.connect(this.domNode, "onkeypress", "_onKey");
+ (this.cboxContainer = new fns.AccordionContainer({
+ nls: this.plugin.nls
+ })).placeAt(this.criteriaPane);
+
+ this._relSelect.set("tabIndex", _tabIdxes.relSelect);
+ this._addCBoxBtn.set("tabIndex", _tabIdxes.addCBoxBtn);
+ this._cancelBtn.set("tabIndex", _tabIdxes.cancelBtn);
+ this._clearFilterBtn.set("tabIndex", _tabIdxes.clearBtn);
+ this._filterBtn.set("tabIndex", _tabIdxes.filterBtn);
+
+ var nls = this.plugin.nls;
+ dijit.setWaiState(this._relSelect.domNode, "label", nls.waiRelAll);
+ dijit.setWaiState(this._addCBoxBtn.domNode, "label", nls.waiAddRuleButton);
+ dijit.setWaiState(this._cancelBtn.domNode, "label", nls.waiCancelButton);
+ dijit.setWaiState(this._clearFilterBtn.domNode, "label", nls.waiClearButton);
+ dijit.setWaiState(this._filterBtn.domNode, "label", nls.waiFilterButton);
+
+ this._relSelect.set("value", this.dlg._relOpCls === "logicall" ? "0" : "1");
+ },
+ uninitialize: function(){
+ this.cboxContainer.destroyRecursive();
+ this.plugin = null;
+ this.dlg = null;
+ },
+ _onRelSelectChange: function(val){
+ this.dlg._relOpCls = val == "0" ? "logicall" : "logicany";
+ dijit.setWaiState(this._relSelect.domNode,"label", this.plugin.nls[val == "0" ? "waiRelAll" : "waiRelAny"]);
+ },
+ _onAddCBox: function(){
+ this.dlg.addCriteriaBoxes(1);
+ },
+ _onCancel: function(){
+ this.dlg.onCancel();
+ },
+ _onClearFilter: function(){
+ this.dlg.onClearFilter();
+ },
+ _onFilter: function(){
+ this.dlg.onFilter();
+ },
+ _onKey: function(e){
+ if(e.keyCode == dojo.keys.ENTER){
+ this.dlg.onFilter();
+ }
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[dijit._Widget,dijit._Templated],{
+ templateString: dojo.cache("dojox.grid", "enhanced/templates/CriteriaBox.html", "<div class=\"dojoxGridFCBox\">\r\n\t<div class=\"dojoxGridFCBoxSelCol\" dojoAttachPoint=\"selColNode\">\r\n\t\t<span class=\"dojoxGridFCBoxField\">${_colSelectLabel}</span>\r\n\t\t<select dojoAttachPoint=\"_colSelect\" dojoType=\"dijit.form.Select\" \r\n\t\t\tclass=\"dojoxGridFCBoxColSelect\"\r\n\t\t\tdojoAttachEvent=\"onChange:_onChangeColumn\">\r\n\t\t</select>\r\n\t</div>\r\n\t<div class=\"dojoxGridFCBoxCondition\" dojoAttachPoint=\"condNode\">\r\n\t\t<span class=\"dojoxGridFCBoxField\">${_condSelectLabel}</span>\r\n\t\t<select dojoAttachPoint=\"_condSelect\" dojoType=\"dijit.form.Select\" \r\n\t\t\tclass=\"dojoxGridFCBoxCondSelect\"\r\n\t\t\tdojoAttachEvent=\"onChange:_onChangeCondition\">\r\n\t\t</select>\r\n\t\t<div class=\"dojoxGridFCBoxCondSelectAlt\" dojoAttachPoint=\"_condSelectAlt\" style=\"display:none;\"></div>\r\n\t</div>\r\n\t<div class=\"dojoxGridFCBoxValue\" dojoAttachPoint=\"valueNode\">\r\n\t\t<span class=\"dojoxGridFCBoxField\">${_valueBoxLabel}</span>\r\n\t</div>\r\n</div>\r\n"),
+ widgetsInTemplate: true,
+ dlg: null,
+ postMixInProperties: function(){
+ this.plugin = this.dlg.plugin;
+ this._curValueBox = null;
+
+ var nls = this.plugin.nls;
+ this._colSelectLabel = nls.columnSelectLabel;
+ this._condSelectLabel = nls.conditionSelectLabel;
+ this._valueBoxLabel = nls.valueBoxLabel;
+ this._anyColumnOption = nls.anyColumnOption;
+ },
+ postCreate: function(){
+ var dlg = this.dlg, g = this.plugin.grid;
+ //Select Column
+ this._colSelect.set("tabIndex", _tabIdxes.colSelect);
+ this._colOptions = this._getColumnOptions();
+ this._colSelect.addOption([
+ {label: this.plugin.nls.anyColumnOption, value: "anycolumn", selected: dlg.curColIdx < 0},
+ {value: ""}
+ ].concat(this._colOptions));
+ //Select Condition
+ this._condSelect.set("tabIndex", _tabIdxes.condSelect);
+ this._condSelect.addOption(this._getUsableConditions(dlg.getColumnType(dlg.curColIdx)));
+ this._showSelectOrLabel(this._condSelect, this._condSelectAlt);
+
+ this.connect(g.layout, "moveColumn", "onMoveColumn");
+ },
+ _getColumnOptions: function(){
+ var colIdx = this.dlg.curColIdx >= 0 ? String(this.dlg.curColIdx) : "anycolumn";
+ return dojo.map(dojo.filter(this.plugin.grid.layout.cells, function(cell){
+ return !(cell.filterable === false || cell.hidden);
+ }), function(cell){
+ return {
+ label: cell.name || cell.field,
+ value: String(cell.index),
+ selected: colIdx == String(cell.index)
+ };
+ });
+ },
+ onMoveColumn: function(){
+ var tmp = this._onChangeColumn;
+ this._onChangeColumn = function(){};
+ var option = this._colSelect.get("selectedOptions");
+ this._colSelect.removeOption(this._colOptions);
+ this._colOptions = this._getColumnOptions();
+ this._colSelect.addOption(this._colOptions);
+ var i = 0;
+ for(; i < this._colOptions.length; ++i){
+ if(this._colOptions[i].label == option.label){
+ break;
+ }
+ }
+ if(i < this._colOptions.length){
+ this._colSelect.set("value", this._colOptions[i].value);
+ }
+ var _this = this;
+ setTimeout(function(){
+ _this._onChangeColumn = tmp;
+ }, 0);
+ },
+ onRemove: function(){
+ this.dlg.removeCriteriaBoxes(this);
+ },
+ uninitialize: function(){
+ if(this._curValueBox){
+ this._curValueBox.destroyRecursive();
+ this._curValueBox = null;
+ }
+ this.plugin = null;
+ this.dlg = null;
+ },
+ _showSelectOrLabel: function(sel, alt){
+ var options = sel.getOptions();
+ if(options.length == 1){
+ alt.innerHTML = options[0].label;
+ dojo.style(sel.domNode, "display", "none");
+ dojo.style(alt, "display", "");
+ }else{
+ dojo.style(sel.domNode, "display", "");
+ dojo.style(alt, "display", "none");
+ }
+ },
+ _onChangeColumn: function(val){
+ this._checkValidCriteria();
+ var type = this.dlg.getColumnType(val);
+ this._setConditionsByType(type);
+ this._setValueBoxByType(type);
+ this._updateValueBox();
+ },
+ _onChangeCondition: function(val){
+ this._checkValidCriteria();
+ var f = (val == "range");
+ if(f ^ this._isRange){
+ this._isRange = f;
+ this._setValueBoxByType(this.dlg.getColumnType(this._colSelect.get("value")));
+ }
+ this._updateValueBox();
+ },
+ _updateValueBox: function(cond){
+ this._curValueBox.set("disabled", this._condSelect.get("value") == "isempty");
+ },
+ _checkValidCriteria: function(){
+ // summary:
+ // Check whether the given criteria box is completed. If it is, mark it.
+ setTimeout(dojo.hitch(this, function(){
+ this.updateRuleTitle();
+ this.dlg._updatePane();
+ }),0);
+ },
+ _createValueBox: function(/* widget constructor */cls,/* object */arg){
+ // summary:
+ // Create a value input box with given class and arguments
+ var func = dojo.hitch(arg.cbox, "_checkValidCriteria");
+ return new cls(dojo.mixin(arg,{
+ tabIndex: _tabIdxes.valueBox,
+ onKeyPress: func,
+ onChange: func,
+ "class": "dojoxGridFCBoxValueBox"
+ }));
+ },
+ _createRangeBox: function(/* widget constructor */cls,/* object */arg){
+ // summary:
+ // Create a DIV containing 2 input widgets, which represents a range, with the given class and arguments
+ var func = dojo.hitch(arg.cbox, "_checkValidCriteria");
+ dojo.mixin(arg,{
+ tabIndex: _tabIdxes.valueBox,
+ onKeyPress: func,
+ onChange: func
+ });
+ var div = dojo.create("div", {"class": "dojoxGridFCBoxValueBox"}),
+ start = new cls(arg),
+ txt = dojo.create("span", {"class": "dojoxGridFCBoxRangeValueTxt", "innerHTML": this.plugin.nls.rangeTo}),
+ end = new cls(arg);
+ dojo.addClass(start.domNode, "dojoxGridFCBoxStartValue");
+ dojo.addClass(end.domNode, "dojoxGridFCBoxEndValue");
+ div.appendChild(start.domNode);
+ div.appendChild(txt);
+ div.appendChild(end.domNode);
+ div.domNode = div;
+ //Mock functions for set and get (in place of the old attr function)
+ div.set = function(dummy, args){
+ if(dojo.isObject(args)){
+ start.set("value", args.start);
+ end.set("value", args.end);
+ }
+ };
+ div.get = function(){
+ var s = start.get("value"),
+ e = end.get("value");
+ return s && e ? {start: s, end: e} : "";
+ };
+ return div;
+ },
+ changeCurrentColumn: function(/* bool */selectCurCol){
+ var colIdx = this.dlg.curColIdx;
+ this._colSelect.set('value', colIdx >= 0 ? String(colIdx) : "anycolumn");
+ this.updateRuleTitle(true);
+ },
+ curColumn: function(){
+ return this._colSelect.getOptions(this._colSelect.get("value")).label;
+ },
+ curCondition: function(){
+ return this._condSelect.getOptions(this._condSelect.get("value")).label;
+ },
+ curValue: function(){
+ var cond = this._condSelect.get("value");
+ if(cond == "isempty"){return "";}
+ return this._curValueBox ? this._curValueBox.get("value") : "";
+ },
+ save: function(){
+ if(this.isEmpty()){
+ return null;
+ }
+ var colIdx = this._colSelect.get("value"),
+ type = this.dlg.getColumnType(colIdx),
+ value = this.curValue(),
+ cond = this._condSelect.get("value");
+ return {
+ "column": colIdx,
+ "condition": cond,
+ "value": value,
+ "formattedVal": this.formatValue(type, cond, value),
+ "type": type,
+ "colTxt": this.curColumn(),
+ "condTxt": this.curCondition()
+ };
+ },
+ load: function(obj){
+ var tmp = [
+ this._onChangeColumn,
+ this._onChangeCondition
+ ];
+ this._onChangeColumn = this._onChangeCondition = function(){};
+ if(obj.column){
+ this._colSelect.set("value", obj.column);
+ }
+ if(obj.condition){
+ this._condSelect.set("value", obj.condition);
+ }
+ if(obj.type){
+ this._setValueBoxByType(obj.type);
+ }else{
+ obj.type = this.dlg.getColumnType(this._colSelect.get("value"));
+ }
+ var value = obj.value || "";
+ if(value || (obj.type != "date" && obj.type != "time")){
+ this._curValueBox.set("value", value);
+ }
+ this._updateValueBox();
+ setTimeout(dojo.hitch(this, function(){
+ this._onChangeColumn = tmp[0];
+ this._onChangeCondition = tmp[1];
+ }), 0);
+ },
+ getExpr: function(){
+ if(this.isEmpty()){
+ return null;
+ }
+ var colval = this._colSelect.get("value");
+ return this.dlg.getExprForCriteria({
+ "type": this.dlg.getColumnType(colval),
+ "column": colval,
+ "condition": this._condSelect.get("value"),
+ "value": this.curValue()
+ });
+ },
+ isEmpty: function(){
+ var cond = this._condSelect.get("value");
+ if(cond == "isempty"){return false;}
+ var v = this.curValue();
+ return v === "" || v === null || typeof v == "undefined" || (typeof v == "number" && isNaN(v));
+ },
+ updateRuleTitle: function(isEmpty){
+ var node = this._pane._buttonWidget.titleTextNode;
+ var title = [
+ "<div class='dojoxEllipsis'>"
+ ];
+ if(isEmpty || this.isEmpty()){
+ node.title = dojo.string.substitute(this.plugin.nls.ruleTitleTemplate, [this._ruleIndex || 1]);
+ title.push(node.title);
+ }else{
+ var type = this.dlg.getColumnType(this._colSelect.get("value"));
+ var column = this.curColumn();
+ var condition = this.curCondition();
+ var value = this.formatValue(type, this._condSelect.get("value"), this.curValue());
+ title.push(
+ column,
+ "&nbsp;<span class='dojoxGridRuleTitleCondition'>",
+ condition,
+ "</span>&nbsp;",
+ value
+ );
+ node.title = [column, " ", condition, " ", value].join('');
+ }
+ node.innerHTML = title.join('');
+ if(dojo.isMoz){
+ var tt = dojo.create("div", {
+ "style": "width: 100%; height: 100%; position: absolute; top: 0; left: 0; z-index: 9999;"
+ }, node);
+ tt.title = node.title;
+ }
+ },
+ updateRuleIndex: function(index){
+ if(this._ruleIndex != index){
+ this._ruleIndex = index;
+ if(this.isEmpty()){
+ this.updateRuleTitle();
+ }
+ }
+ },
+ setAriaInfo: function(idx){
+ var dss = dojo.string.substitute, nls = this.plugin.nls;
+ dijit.setWaiState(this._colSelect.domNode,"label", dss(nls.waiColumnSelectTemplate, [idx]));
+ dijit.setWaiState(this._condSelect.domNode,"label", dss(nls.waiConditionSelectTemplate, [idx]));
+ dijit.setWaiState(this._pane._removeCBoxBtn.domNode,"label", dss(nls.waiRemoveRuleButtonTemplate, [idx]));
+ this._index = idx;
+ },
+ _getUsableConditions: function(type){
+ var conditions = this.dlg._dataTypeMap[type].conditions;
+ var typeDisabledConds = (this.plugin.args.disabledConditions || {})[type];
+ var colIdx = parseInt(this._colSelect.get("value"), 10);
+ var colDisabledConds = isNaN(colIdx) ?
+ (this.plugin.args.disabledConditions || {})["anycolumn"] :
+ this.plugin.grid.layout.cells[colIdx].disabledConditions;
+ if(!dojo.isArray(typeDisabledConds)){
+ typeDisabledConds = [];
+ }
+ if(!dojo.isArray(colDisabledConds)){
+ colDisabledConds = [];
+ }
+ var arr = typeDisabledConds.concat(colDisabledConds);
+ if(arr.length){
+ var disabledConds = {};
+ dojo.forEach(arr, function(c){
+ if(dojo.isString(c)){
+ disabledConds[c.toLowerCase()] = true;
+ }
+ });
+ return dojo.filter(conditions, function(condOption){
+ return !(condOption.value in disabledConds);
+ });
+ }
+ return conditions;
+ },
+ _setConditionsByType: function(/* string */type){
+ var condSelect = this._condSelect;
+ condSelect.removeOption(condSelect.options);
+ condSelect.addOption(this._getUsableConditions(type));
+ this._showSelectOrLabel(this._condSelect, this._condSelectAlt);
+ },
+ _setValueBoxByType: function(/* string */type){
+ if(this._curValueBox){
+ this.valueNode.removeChild(this._curValueBox.domNode);
+ try{
+ this._curValueBox.destroyRecursive();
+ }catch(e){}
+ delete this._curValueBox;
+ }
+ //value box class
+ var vbcls = this.dlg._dataTypeMap[type].valueBoxCls[this._getValueBoxClsInfo(this._colSelect.get("value"), type)],
+ vboxArg = this._getValueBoxArgByType(type);
+ this._curValueBox = this[this._isRange ? "_createRangeBox" : "_createValueBox"](vbcls, vboxArg);
+ this.valueNode.appendChild(this._curValueBox.domNode);
+
+ //Can not move to setAriaInfo, 'cause the value box is created after the defpane is loaded.
+ dijit.setWaiState(this._curValueBox.domNode, "label", dojo.string.substitute(this.plugin.nls.waiValueBoxTemplate,[this._index]));
+ //Now our cbox is completely ready
+ this.dlg.onRendered(this);
+ },
+ //--------------------------UI Configuration--------------------------------------
+ _getValueBoxArgByType: function(/* string */type){
+ // summary:
+ // Get the arguments for the value box construction.
+ var g = this.plugin.grid,
+ cell = g.layout.cells[parseInt(this._colSelect.get("value"), 10)],
+ res = {
+ cbox: this
+ };
+ if(type == "string"){
+ if(cell && (cell.suggestion || cell.autoComplete)){
+ dojo.mixin(res, {
+ store: g.store,
+ searchAttr: cell.field || cell.name,
+ fetchProperties: {
+ sort: [{"attribute": cell.field || cell.name}]
+ }
+ });
+ }
+ }else if(type == "boolean"){
+ dojo.mixin(res, this.dlg.builder.defaultArgs["boolean"]);
+ }
+ if(cell && cell.dataTypeArgs){
+ dojo.mixin(res, cell.dataTypeArgs);
+ }
+ return res;
+ },
+ formatValue: function(type, cond, v){
+ // summary:
+ // Format the value to be shown in tooltip.
+ if(cond == "isempty"){return "";}
+ if(type == "date" || type == "time"){
+ var opt = {selector: type},
+ fmt = dojo.date.locale.format;
+ if(cond == "range"){
+ return dojo.string.substitute(this.plugin.nls.rangeTemplate, [fmt(v.start, opt), fmt(v.end, opt)]);
+ }
+ return fmt(v, opt);
+ }else if(type == "boolean"){
+ return v ? this._curValueBox._lblTrue : this._curValueBox._lblFalse;
+ }
+ return v;
+ },
+ _getValueBoxClsInfo: function(/* int|string */colIndex, /* string */type){
+ // summary:
+ // Decide which value box to use given data type and column index.
+ var cell = this.plugin.grid.layout.cells[parseInt(colIndex, 10)];
+ //Now we only need to handle string. But maybe we need to handle more types here in the future.
+ if(type == "string"){
+ return (cell && (cell.suggestion || cell.autoComplete)) ? "ac" : "dft";
+ }
+ return "dft";
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter.AccordionContainer", dijit.layout.AccordionContainer, {
+ nls: null,
+ addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
+ var pane = arguments[0] = child._pane = new dijit.layout.ContentPane({
+ content: child
+ });
+ this.inherited(arguments);
+ this._modifyChild(pane);
+ },
+ removeChild: function(child){
+ var pane = child, isRemoveByUser = false;
+ if(child._pane){
+ isRemoveByUser = true;
+ pane = arguments[0] = child._pane;
+ }
+ this.inherited(arguments);
+ if(isRemoveByUser){
+ this._hackHeight(false, this._titleHeight);
+ var children = this.getChildren();
+ if(children.length === 1){
+ dojo.style(children[0]._removeCBoxBtn.domNode, "display", "none");
+ }
+ }
+ pane.destroyRecursive();
+ },
+ selectChild: function(child){
+ if(child._pane){
+ arguments[0] = child._pane;
+ }
+ this.inherited(arguments);
+ },
+ resize: function(){
+ this.inherited(arguments);
+ dojo.forEach(this.getChildren(), this._setupTitleDom);
+ },
+ startup: function(){
+ if(this._started){
+ return;
+ }
+ this.inherited(arguments);
+ if(parseInt(dojo.isIE, 10) == 7){
+ //IE7 will fire a lot of "onresize" event during initialization.
+ dojo.some(this._connects, function(cnnt){
+ if(cnnt[0][1] == "onresize"){
+ this.disconnect(cnnt);
+ return true;
+ }
+ }, this);
+ }
+ dojo.forEach(this.getChildren(), function(child){
+ this._modifyChild(child, true);
+ }, this);
+ },
+ _onKeyPress: function(/*Event*/ e, /*dijit._Widget*/ fromTitle){
+ // summary:
+ // Overrides base class method, make left/right button do other things.
+ if(this.disabled || e.altKey || !(fromTitle || e.ctrlKey)){
+ return;
+ }
+ var k = dojo.keys, c = e.charOrCode, ltr = dojo._isBodyLtr(), toNext = null;
+ if((fromTitle && c == k.UP_ARROW) || (e.ctrlKey && c == k.PAGE_UP)){
+ toNext = false;
+ }else if((fromTitle && c == k.DOWN_ARROW) || (e.ctrlKey && (c == k.PAGE_DOWN || c == k.TAB))){
+ toNext = true;
+ }else if(c == (ltr ? k.LEFT_ARROW : k.RIGHT_ARROW)){
+ toNext = this._focusOnRemoveBtn ? null : false;
+ this._focusOnRemoveBtn = !this._focusOnRemoveBtn;
+ }else if(c == (ltr ? k.RIGHT_ARROW : k.LEFT_ARROW)){
+ toNext = this._focusOnRemoveBtn ? true : null;
+ this._focusOnRemoveBtn = !this._focusOnRemoveBtn;
+ }else{
+ return;
+ }
+ if(toNext !== null){
+ this._adjacent(toNext)._buttonWidget._onTitleClick();
+ }
+ dojo.stopEvent(e);
+ dojo.window.scrollIntoView(this.selectedChildWidget._buttonWidget.domNode.parentNode);
+ if(dojo.isIE){
+ //IE will not show focus indicator if tabIndex is -1
+ this.selectedChildWidget._removeCBoxBtn.focusNode.setAttribute("tabIndex", this._focusOnRemoveBtn ? _tabIdxes.accordionTitle : -1);
+ }
+ dijit.focus(this.selectedChildWidget[this._focusOnRemoveBtn ? "_removeCBoxBtn" : "_buttonWidget"].focusNode);
+ },
+ _modifyChild: function(child, isFirst){
+ if(!child || !this._started){
+ return;
+ }
+ dojo.style(child.domNode, "overflow", "hidden");
+ child._buttonWidget.connect(child._buttonWidget, "_setSelectedAttr", function(){
+ this.focusNode.setAttribute("tabIndex", this.selected ? _tabIdxes.accordionTitle : "-1");
+ });
+ var _this = this;
+ child._buttonWidget.connect(child._buttonWidget.domNode, "onclick", function(){
+ _this._focusOnRemoveBtn = false;
+ });
+ (child._removeCBoxBtn = new dijit.form.Button({
+ label: this.nls.removeRuleButton,
+ showLabel: false,
+ iconClass: "dojoxGridFCBoxRemoveCBoxBtnIcon",
+ tabIndex: _tabIdxes.removeCBoxBtn,
+ onClick: dojo.hitch(child.content, "onRemove"),
+ onKeyPress: function(e){
+ _this._onKeyPress(e, child._buttonWidget.contentWidget);
+ }
+ })).placeAt(child._buttonWidget.domNode);
+ var i, children = this.getChildren();
+ if(children.length === 1){
+ child._buttonWidget.set("selected", true);
+ dojo.style(child._removeCBoxBtn.domNode, "display", "none");
+ }else{
+ for(i = 0; i < children.length; ++i){
+ if(children[i]._removeCBoxBtn){
+ dojo.style(children[i]._removeCBoxBtn.domNode, "display", "");
+ }
+ }
+ }
+ this._setupTitleDom(child);
+ if(!this._titleHeight){
+ for(i = 0; i < children.length; ++i){
+ if(children[i] != this.selectedChildWidget){
+ this._titleHeight = dojo.marginBox(children[i]._buttonWidget.domNode.parentNode).h;
+ break;
+ }
+ }
+ }
+ if(!isFirst){
+ this._hackHeight(true, this._titleHeight);
+ }
+ },
+ _hackHeight: function(/* bool */toGrow,/* int */heightDif){
+ var children = this.getChildren(),
+ dn = this.domNode, h = dojo.style(dn, "height");
+ if(!toGrow){
+ dn.style.height = (h - heightDif) + 'px';
+ }else if(children.length > 1){
+ dn.style.height = (h + heightDif) + 'px';
+ }else{
+ //Only one rule, no need to do anything.
+ return;
+ }
+ this.resize();
+ },
+ _setupTitleDom: function(child){
+ var w = dojo.contentBox(child._buttonWidget.titleNode).w;
+ if(dojo.isIE < 8){ w -= 8; }
+ dojo.style(child._buttonWidget.titleTextNode, "width", w + "px");
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter.UniqueComboBox", dijit.form.ComboBox, {
+ _openResultList: function(results){
+ var cache = {}, s = this.store, colName = this.searchAttr;
+ arguments[0] = dojo.filter(results, function(item){
+ var key = s.getValue(item, colName), existed = cache[key];
+ cache[key] = true;
+ return !existed;
+ });
+ this.inherited(arguments);
+ },
+ _onKey: function(evt){
+ if(evt.charOrCode === dojo.keys.ENTER && this._opened){
+ dojo.stopEvent(evt);
+ }
+ this.inherited(arguments);
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter.BooleanValueBox", [dijit._Widget, dijit._Templated], {
+ templateString: dojo.cache("dojox.grid", "enhanced/templates/FilterBoolValueBox.html", "<div class=\"dojoxGridBoolValueBox\">\r\n\t<div class=\"dojoxGridTrueBox\">\r\n\t\t<input dojoType=\"dijit.form.RadioButton\" type='radio' name='a1' id='${_baseId}_rbTrue' checked=\"true\" \r\n\t\t\tdojoAttachPoint=\"rbTrue\" dojoAttachEvent=\"onChange: onChange\"/>\r\n\t\t<div class=\"dojoxGridTrueLabel\" for='${_baseId}_rbTrue'>${_lblTrue}</div>\r\n\t</div>\r\n\t<div class=\"dojoxGridFalseBox\">\r\n\t\t<input dojoType=\"dijit.form.RadioButton\" dojoAttachPoint=\"rbFalse\" type='radio' name='a1' id='${_baseId}_rbFalse'/>\r\n\t\t<div class=\"dojoxGridTrueLabel\" for='${_baseId}_rbFalse'>${_lblFalse}</div>\r\n\t</div>\r\n</div>\r\n"),
+ widgetsInTemplate: true,
+ constructor: function(args){
+ var nls = args.cbox.plugin.nls;
+ this._baseId = args.cbox.id;
+ this._lblTrue = args.trueLabel || nls.trueLabel || "true";
+ this._lblFalse = args.falseLabel || nls.falseLabel || "false";
+ this.args = args;
+ },
+ postCreate: function(){
+ this.onChange();
+ },
+ onChange: function(){},
+
+ get: function(prop){
+ return this.rbTrue.get("checked");
+ },
+ set: function(prop, v){
+ this.inherited(arguments);
+ if(prop == "value"){
+ this.rbTrue.set("checked", !!v);
+ this.rbFalse.set("checked", !v);
+ }
+ }
+});
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterDefDialog.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterDefDialog.xd.js
new file mode 100644
index 0000000..ba827a8
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterDefDialog.xd.js
@@ -0,0 +1,1260 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.filter.FilterDefDialog"],
+["require", "dijit.dijit"],
+["require", "dijit.Tooltip"],
+["require", "dojox.grid.enhanced.plugins.Dialog"],
+["require", "dijit.form.ComboBox"],
+["require", "dijit.form.Select"],
+["require", "dijit.form.TextBox"],
+["require", "dijit.form.CheckBox"],
+["require", "dijit.form.NumberTextBox"],
+["require", "dijit.form.DateTextBox"],
+["require", "dijit.form.TimeTextBox"],
+["require", "dijit.form.Button"],
+["require", "dijit.layout.AccordionContainer"],
+["require", "dijit.layout.ContentPane"],
+["require", "dojo.date.locale"],
+["require", "dojo.string"],
+["require", "dojox.grid.enhanced.plugins.filter.FilterBuilder"],
+["require", "dojox.grid.cells.dijit"],
+["require", "dojox.html.ellipsis"],
+["require", "dojox.html.metrics"],
+["require", "dojo.window"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterDefDialog"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterDefDialog"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter.FilterDefDialog");
+
+dojo.require("dijit.dijit");
+dojo.require("dijit.Tooltip");
+dojo.require("dojox.grid.enhanced.plugins.Dialog");
+dojo.require("dijit.form.ComboBox");
+dojo.require("dijit.form.Select");
+dojo.require("dijit.form.TextBox");
+dojo.require("dijit.form.CheckBox");
+dojo.require("dijit.form.NumberTextBox");
+dojo.require("dijit.form.DateTextBox");
+dojo.require("dijit.form.TimeTextBox");
+dojo.require("dijit.form.Button");
+dojo.require("dijit.layout.AccordionContainer");
+dojo.require("dijit.layout.ContentPane");
+dojo.require("dojo.date.locale");
+dojo.require("dojo.string");
+dojo.require("dojox.grid.enhanced.plugins.filter.FilterBuilder");
+dojo.require("dojox.grid.cells.dijit");
+dojo.require("dojox.html.ellipsis");
+dojo.require("dojox.html.metrics");
+dojo.require("dojo.window");
+
+(function(){
+var fns = dojox.grid.enhanced.plugins.filter,
+ _tabIdxes = {
+ // summary:
+ // Define tabindexes for elements in the filter definition dialog
+ relSelect: 60,
+ accordionTitle: 70,
+ removeCBoxBtn: -1,
+ colSelect: 90,
+ condSelect: 95,
+ valueBox: 10,
+ addCBoxBtn: 20,
+ filterBtn: 30,
+ clearBtn: 40,
+ cancelBtn: 50
+ };
+dojo.declare("dojox.grid.enhanced.plugins.filter.FilterDefDialog", null, {
+ // summary:
+ // Create the filter definition UI.
+ curColIdx: -1,
+ _relOpCls: "logicall",
+ _savedCriterias: null,
+ plugin: null,
+ constructor: function(args){
+ var plugin = this.plugin = args.plugin;
+ this.builder = new fns.FilterBuilder();
+ this._setupData();
+ this._cboxes = [];
+ this.defaultType = plugin.args.defaultType || "string";
+
+ (this.filterDefPane = new fns.FilterDefPane({
+ "dlg": this
+ })).startup();
+ (this._defPane = new dojox.grid.enhanced.plugins.Dialog({
+ "refNode": this.plugin.grid.domNode,
+ "title": plugin.nls.filterDefDialogTitle,
+ "class": "dojoxGridFDTitlePane",
+ "iconClass": "dojoxGridFDPaneIcon",
+ "content": this.filterDefPane
+ })).startup();
+
+ this._defPane.connect(plugin.grid.layer('filter'), "filterDef", dojo.hitch(this, "_onSetFilter"));
+ plugin.grid.setFilter = dojo.hitch(this, "setFilter");
+ plugin.grid.getFilter = dojo.hitch(this, "getFilter");
+ plugin.grid.getFilterRelation = dojo.hitch(this, function(){
+ return this._relOpCls;
+ });
+
+ plugin.connect(plugin.grid.layout, "moveColumn", dojo.hitch(this, "onMoveColumn"));
+ },
+ onMoveColumn: function(sourceViewIndex, destViewIndex, cellIndex, targetIndex, before){
+ if(this._savedCriterias && cellIndex != targetIndex){
+ if(before){ --targetIndex; }
+ var min = cellIndex < targetIndex ? cellIndex : targetIndex;
+ var max = cellIndex < targetIndex ? targetIndex : cellIndex;
+ var dir = targetIndex > min ? 1 : -1;
+ dojo.forEach(this._savedCriterias, function(sc){
+ var idx = parseInt(sc.column, 10);
+ if(!isNaN(idx) && idx >= min && idx <= max){
+ sc.column = String(idx == cellIndex ? idx + (max - min) * dir : idx - dir);
+ }
+ });
+ }
+ },
+ destroy: function(){
+ this._defPane.destroyRecursive();
+ this._defPane = null;
+ this.filterDefPane = null;
+ this.builder = null;
+ this._dataTypeMap = null;
+ this._cboxes = null;
+ var g = this.plugin.grid;
+ g.setFilter = null;
+ g.getFilter = null;
+ g.getFilterRelation = null;
+ this.plugin = null;
+ },
+ _setupData: function(){
+ var nls = this.plugin.nls;
+ this._dataTypeMap = {
+ // summary:
+ // All supported data types
+ "number":{
+ valueBoxCls: {
+ dft: dijit.form.NumberTextBox
+ },
+ conditions:[
+ {label: nls.conditionEqual, value: "equalto", selected: true},
+ {label: nls.conditionNotEqual, value: "notequalto"},
+ {label: nls.conditionLess, value: "lessthan"},
+ {label: nls.conditionLessEqual, value: "lessthanorequalto"},
+ {label: nls.conditionLarger, value: "largerthan"},
+ {label: nls.conditionLargerEqual, value: "largerthanorequalto"},
+ {label: nls.conditionIsEmpty, value: "isempty"}
+ ]
+ },
+ "string":{
+ valueBoxCls: {
+ dft: dijit.form.TextBox,
+ ac: fns.UniqueComboBox //For autoComplete
+ },
+ conditions:[
+ {label: nls.conditionContains, value: "contains", selected: true},
+ {label: nls.conditionIs, value: "equalto"},
+ {label: nls.conditionStartsWith, value: "startswith"},
+ {label: nls.conditionEndWith, value: "endswith"},
+ {label: nls.conditionNotContain, value: "notcontains"},
+ {label: nls.conditionIsNot, value: "notequalto"},
+ {label: nls.conditionNotStartWith, value: "notstartswith"},
+ {label: nls.conditionNotEndWith, value: "notendswith"},
+ {label: nls.conditionIsEmpty, value: "isempty"}
+ ]
+ },
+ "date":{
+ valueBoxCls: {
+ dft: dijit.form.DateTextBox
+ },
+ conditions:[
+ {label: nls.conditionIs, value: "equalto", selected: true},
+ {label: nls.conditionBefore, value: "lessthan"},
+ {label: nls.conditionAfter, value: "largerthan"},
+ {label: nls.conditionRange, value: "range"},
+ {label: nls.conditionIsEmpty, value: "isempty"}
+ ]
+ },
+ "time":{
+ valueBoxCls: {
+ dft: dijit.form.TimeTextBox
+ },
+ conditions:[
+ {label: nls.conditionIs, value: "equalto", selected: true},
+ {label: nls.conditionBefore, value: "lessthan"},
+ {label: nls.conditionAfter, value: "largerthan"},
+ {label: nls.conditionRange, value: "range"},
+ {label: nls.conditionIsEmpty, value: "isempty"}
+ ]
+ },
+ "boolean": {
+ valueBoxCls: {
+ dft: fns.BooleanValueBox
+ },
+ conditions: [
+ {label: nls.conditionIs, value: "equalto", selected: true},
+ {label: nls.conditionIsEmpty, value: "isempty"}
+ ]
+ }
+ };
+ },
+ setFilter: function(rules, ruleRelation){
+ rules = rules || [];
+ if(!dojo.isArray(rules)){
+ rules = [rules];
+ }
+ var func = function(){
+ if(rules.length){
+ this._savedCriterias = dojo.map(rules, function(rule){
+ var type = rule.type || this.defaultType;
+ return {
+ "type": type,
+ "column": String(rule.column),
+ "condition": rule.condition,
+ "value": rule.value,
+ "colTxt": this.getColumnLabelByValue(String(rule.column)),
+ "condTxt": this.getConditionLabelByValue(type, rule.condition),
+ "formattedVal": rule.formattedVal || rule.value
+ };
+ }, this);
+ this._criteriasChanged = true;
+ if(ruleRelation === "logicall" || ruleRelation === "logicany"){
+ this._relOpCls = ruleRelation;
+ }
+ var exprs = dojo.map(rules, this.getExprForCriteria, this);
+ exprs = this.builder.buildExpression(exprs.length == 1 ? exprs[0] : {
+ "op": this._relOpCls,
+ "data": exprs
+ });
+ this.plugin.grid.layer("filter").filterDef(exprs);
+ this.plugin.filterBar.toggleClearFilterBtn(false);
+ }
+ this._closeDlgAndUpdateGrid();
+ };
+ if(this._savedCriterias){
+ this._clearWithoutRefresh = true;
+ var handle = dojo.connect(this, "clearFilter", this, function(){
+ dojo.disconnect(handle);
+ this._clearWithoutRefresh = false;
+ func.apply(this);
+ });
+ this.onClearFilter();
+ }else{
+ func.apply(this);
+ }
+ },
+ getFilter: function(){
+ return dojo.clone(this._savedCriterias) || [];
+ },
+ getColumnLabelByValue: function(v){
+ var nls = this.plugin.nls;
+ if(v.toLowerCase() == "anycolumn"){
+ return nls["anyColumnOption"];
+ }else{
+ var cell = this.plugin.grid.layout.cells[parseInt(v, 10)];
+ return cell ? (cell.name || cell.field) : "";
+ }
+ },
+ getConditionLabelByValue: function(type, c){
+ var conditions = this._dataTypeMap[type].conditions;
+ for(var i = conditions.length - 1; i >= 0; --i){
+ var cond = conditions[i];
+ if(cond.value == c.toLowerCase()){
+ return cond.label;
+ }
+ }
+ return "";
+ },
+ addCriteriaBoxes: function(/* int */cnt){
+ // summary:
+ // Add *cnt* criteria boxes to the filter definition pane.
+ // Check overflow if necessary.
+ if(typeof cnt != "number" || cnt <= 0){
+ return;
+ }
+ var cbs = this._cboxes,
+ cc = this.filterDefPane.cboxContainer,
+ total = this.plugin.args.ruleCount,
+ len = cbs.length, cbox;
+ //If overflow, add to max rule count.
+ if(total > 0 && len + cnt > total){
+ cnt = total - len;
+ }
+ for(; cnt > 0; --cnt){
+ cbox = new fns.CriteriaBox({
+ dlg: this
+ });
+ cbs.push(cbox);
+ cc.addChild(cbox);
+ }
+ //If there's no content box in it , AccordionContainer can not startup
+ cc.startup();
+ this._updatePane();
+ this._updateCBoxTitles();
+ cc.selectChild(cbs[cbs.length-1]);
+ //Asign an impossibly large scrollTop to scroll the criteria pane to the bottom.
+ this.filterDefPane.criteriaPane.scrollTop = 1000000;
+ if(cbs.length === 4){
+ if(dojo.isIE <= 6 && !this.__alreadyResizedForIE6){
+ var size = dojo.position(cc.domNode);
+ size.w -= dojox.html.metrics.getScrollbar().w;
+ cc.resize(size);
+ this.__alreadyResizedForIE6 = true;
+ }else{
+ cc.resize();
+ }
+ }
+ },
+ removeCriteriaBoxes: function(/* int|CriteriaBox|int[] */cnt,/* bool? */isIdx){
+ // summary:
+ // Remove criteria boxes from the filter definition pane.
+ var cbs = this._cboxes, cc = this.filterDefPane.cboxContainer,
+ len = cbs.length, start = len - cnt,
+ end = len - 1, cbox,
+ curIdx = dojo.indexOf(cbs, cc.selectedChildWidget.content);
+ if(dojo.isArray(cnt)){
+ var i, idxes = cnt;
+ idxes.sort();
+ cnt = idxes.length;
+ //find a rule that's not deleted.
+ //must find and focus the last one, or the hack will not work.
+ for(i = len - 1; i >= 0 && dojo.indexOf(idxes, i) >= 0; --i){}
+ if(i >= 0){
+ //must select before remove
+ if(i != curIdx){
+ cc.selectChild(cbs[i]);
+ }
+ //idxes is sorted from small to large,
+ //so travel reversely won't need change index after delete from array.
+ for(i = cnt-1; i >= 0; --i){
+ if(idxes[i] >= 0 && idxes[i] < len){
+ cc.removeChild(cbs[idxes[i]]);
+ cbs.splice(idxes[i],1);
+ }
+ }
+ }
+ start = cbs.length;
+ }else{
+ if(isIdx === true){
+ if(cnt >= 0 && cnt < len){
+ start = end = cnt;
+ cnt = 1;
+ }else{
+ return;
+ }
+ }else{
+ if(cnt instanceof fns.CriteriaBox){
+ cbox = cnt;
+ cnt = 1;
+ start = end = dojo.indexOf(cbs, cbox);
+ }else if(typeof cnt != "number" || cnt <= 0){
+ return;
+ }else if(cnt >= len){
+ cnt = end;
+ start = 1;
+ }
+ }
+ if(end < start){
+ return;
+ }
+ //must select before remove
+ if(curIdx >= start && curIdx <= end){
+ cc.selectChild(cbs[start ? start-1 : end+1]);
+ }
+ for(; end >= start; --end){
+ cc.removeChild(cbs[end]);
+ }
+ cbs.splice(start, cnt);
+ }
+ this._updatePane();
+ this._updateCBoxTitles();
+ if(cbs.length === 3){
+ //In ie6, resize back to the normal width will cause the title button look strange.
+ cc.resize();
+ }
+ },
+ getCriteria: function(/* int */idx){
+ // summary:
+ // Get the *idx*-th criteria.
+ if(typeof idx != "number"){
+ return this._savedCriterias ? this._savedCriterias.length : 0;
+ }
+ if(this._savedCriterias && this._savedCriterias[idx]){
+ return dojo.mixin({
+ relation: this._relOpCls == "logicall" ? this.plugin.nls.and : this.plugin.nls.or
+ },this._savedCriterias[idx]);
+ }
+ return null;
+ },
+ getExprForCriteria: function(rule){
+ if(rule.column == "anycolumn"){
+ var cells = dojo.filter(this.plugin.grid.layout.cells, function(cell){
+ return !(cell.filterable === false || cell.hidden);
+ });
+ return {
+ "op": "logicany",
+ "data": dojo.map(cells, function(cell){
+ return this.getExprForColumn(rule.value, cell.index, rule.type, rule.condition);
+ }, this)
+ };
+ }else{
+ return this.getExprForColumn(rule.value, rule.column, rule.type, rule.condition);
+ }
+ },
+ getExprForColumn: function(value, colIdx, type, condition){
+ colIdx = parseInt(colIdx, 10);
+ var cell = this.plugin.grid.layout.cells[colIdx],
+ colName = cell.field || cell.name,
+ obj = {
+ "datatype": type || this.getColumnType(colIdx),
+ "args": cell.dataTypeArgs,
+ "isColumn": true
+ },
+ operands = [dojo.mixin({"data": this.plugin.args.isServerSide ? colName : cell}, obj)];
+ obj.isColumn = false;
+ if(condition == "range"){
+ operands.push(dojo.mixin({"data": value.start}, obj),
+ dojo.mixin({"data": value.end}, obj));
+ }else if(condition != "isempty"){
+ operands.push(dojo.mixin({"data": value}, obj));
+ }
+ return {
+ "op": condition,
+ "data": operands
+ };
+ },
+ getColumnType: function(/* int */colIndex){
+ var cell = this.plugin.grid.layout.cells[parseInt(colIndex, 10)];
+ if(!cell || !cell.datatype){
+ return this.defaultType;
+ }
+ var type = String(cell.datatype).toLowerCase();
+ return this._dataTypeMap[type] ? type : this.defaultType;
+ },
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////
+ clearFilter: function(noRefresh){
+ // summary:
+ // Clear filter definition.
+ if(!this._savedCriterias){
+ return;
+ }
+ this._savedCriterias = null;
+ this.plugin.grid.layer("filter").filterDef(null);
+ try{
+ this.plugin.filterBar.toggleClearFilterBtn(true);
+ this.filterDefPane._clearFilterBtn.set("disabled", true);
+ this.removeCriteriaBoxes(this._cboxes.length-1);
+ this._cboxes[0].load({});
+ }catch(e){
+ //Any error means the filter is defined outside this plugin.
+ }
+ if(noRefresh){
+ this.closeDialog();
+ }else{
+ this._closeDlgAndUpdateGrid();
+ }
+ },
+ showDialog: function(/* int */colIndex){
+ // summary:
+ // Show the filter defintion dialog.
+ this._defPane.show();
+ this.plugin.filterStatusTip.closeDialog();
+ this._prepareDialog(colIndex);
+ },
+ closeDialog: function(){
+ // summary:
+ // Close the filter definition dialog.
+ this._defPane.hide();
+ },
+ onFilter: function(e){
+ // summary:
+ // Triggered when the "Filter" button is clicked.
+ if(this.canFilter()){
+ this._defineFilter();
+ this._closeDlgAndUpdateGrid();
+ this.plugin.filterBar.toggleClearFilterBtn(false);
+ }
+ },
+ onClearFilter: function(e){
+ // summary:
+ // Triggered when the "Clear" button is clicked.
+ if(this._savedCriterias){
+ if(this._savedCriterias.length > 1){
+ this.plugin.clearFilterDialog.show();
+ }else{
+ this.clearFilter(this._clearWithoutRefresh);
+ }
+ }
+ },
+ onCancel: function(e){
+ // summary:
+ // Triggered when the "Cancel" buttton is clicked.
+ var sc = this._savedCriterias;
+ var cbs = this._cboxes;
+ if(sc){
+ this.addCriteriaBoxes(sc.length - cbs.length);
+ this.removeCriteriaBoxes(cbs.length - sc.length);
+ dojo.forEach(sc, function(c, i){
+ cbs[i].load(c);
+ });
+ }else{
+ this.removeCriteriaBoxes(cbs.length - 1);
+ cbs[0].load({});
+ }
+ this.closeDialog();
+ },
+ onRendered: function(cbox){
+ // summary:
+ // Triggered when the rendering of the filter definition dialog is completely finished.
+ // cbox:
+ // Current visible criteria box
+ if(!dojo.isFF){
+ var elems = dijit._getTabNavigable(dojo.byId(cbox.domNode));
+ dijit.focus(elems.lowest || elems.first);
+ }else{
+ var dp = this._defPane;
+ dp._getFocusItems(dp.domNode);
+ dijit.focus(dp._firstFocusItem);
+ }
+ },
+ _onSetFilter: function(filterDef){
+ // summary:
+ // If someone clear the filter def in the store directly, we must clear it in the UI.
+ // If someone defines a filter, don't know how to handle it!
+ if(filterDef === null && this._savedCriterias){
+ this.clearFilter();
+ }
+ },
+ _prepareDialog: function(/* int */colIndex){
+ var sc = this._savedCriterias,
+ cbs = this._cboxes, i, cbox,
+ columnChanged = this.curColIdx != colIndex;
+ this.curColIdx = colIndex;
+ if(!sc){
+ if(cbs.length === 0){
+ this.addCriteriaBoxes(1);
+ }else if(columnChanged){
+ for(i = 0; (cbox = cbs[i]); ++i){
+ cbox.changeCurrentColumn();
+ }
+ }
+ }else if(this._criteriasChanged){
+ this.filterDefPane._relSelect.set("value", this._relOpCls === "logicall" ? "0" : "1");
+ this._criteriasChanged = false;
+ var needNewCBox = sc.length > cbs.length;
+ this.addCriteriaBoxes(sc.length - cbs.length);
+ this.removeCriteriaBoxes(cbs.length - sc.length);
+ this.filterDefPane._clearFilterBtn.set("disabled", false);
+ if(needNewCBox){
+ dojo.forEach(sc, function(c, i){
+ var handle = dojo.connect(this, "onRendered", function(cbox){
+ if(cbox == cbs[i]){
+ dojo.disconnect(handle);
+ cbox.load(c);
+ }
+ });
+ }, this);
+ }else{
+ for(i = 0; i < sc.length; ++i){
+ cbs[i].load(sc[i]);
+ }
+ }
+ }
+ //Since we're allowed to remove cboxes when the definition pane is not shown,
+ //we have to resize the container to have a correct _verticalSpace.
+ this.filterDefPane.cboxContainer.resize();
+ },
+ _defineFilter: function(){
+ var cbs = this._cboxes,
+ filterCboxes = function(method){
+ return dojo.filter(dojo.map(cbs, function(cbox){
+ return cbox[method]();
+ }), function(result){
+ return !!result;
+ });
+ },
+ exprs = filterCboxes("getExpr");
+ this._savedCriterias = filterCboxes("save");
+ exprs = exprs.length == 1 ? exprs[0] : {
+ "op": this._relOpCls,
+ "data": exprs
+ };
+ exprs = this.builder.buildExpression(exprs);
+
+ this.plugin.grid.layer("filter").filterDef(exprs);
+ this.filterDefPane._clearFilterBtn.set("disabled", false);
+ },
+ _updateCBoxTitles: function(){
+ for(var cbs = this._cboxes, i = cbs.length; i > 0; --i){
+ cbs[i - 1].updateRuleIndex(i);
+ cbs[i - 1].setAriaInfo(i);
+ }
+ },
+ _updatePane: function(){
+ var cbs = this._cboxes,
+ defPane = this.filterDefPane;
+ defPane._addCBoxBtn.set("disabled", cbs.length == this.plugin.args.ruleCount);
+ defPane._filterBtn.set("disabled", !this.canFilter());
+ },
+ canFilter: function(){
+ return dojo.filter(this._cboxes, function(cbox){
+ return !cbox.isEmpty();
+ }).length > 0;
+ },
+ _closeDlgAndUpdateGrid: function(){
+ this.closeDialog();
+ var g = this.plugin.grid;
+ g.showMessage(g.loadingMessage);
+ setTimeout(dojo.hitch(g, g._refresh), this._defPane.duration + 10);
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter.FilterDefPane",[dijit._Widget,dijit._Templated],{
+ templateString: dojo.cache("dojox.grid", "enhanced/templates/FilterDefPane.html", "<div class=\"dojoxGridFDPane\">\r\n\t<div class=\"dojoxGridFDPaneRelation\">${_relMsgFront}\r\n\t<span class=\"dojoxGridFDPaneModes\" dojoAttachPoint=\"criteriaModeNode\">\r\n\t\t<select dojoAttachPoint=\"_relSelect\" dojoType=\"dijit.form.Select\" dojoAttachEvent=\"onChange: _onRelSelectChange\">\r\n\t\t\t<option value=\"0\">${_relAll}</option>\r\n\t\t\t<option value=\"1\">${_relAny}</option>\r\n\t\t</select>\r\n\t</span>\r\n\t${_relMsgTail}\r\n\t</div>\r\n\t<div dojoAttachPoint=\"criteriaPane\" class=\"dojoxGridFDPaneRulePane\"></div>\r\n\t<div dojoAttachPoint=\"_addCBoxBtn\" dojoType=\"dijit.form.Button\" \r\n\t\tclass=\"dojoxGridFDPaneAddCBoxBtn\" iconClass=\"dojoxGridFDPaneAddCBoxBtnIcon\"\r\n\t\tdojoAttachEvent=\"onClick:_onAddCBox\" label=\"${_addRuleBtnLabel}\" showLabel=\"false\">\r\n\t</div>\r\n\t<div class=\"dojoxGridFDPaneBtns\" dojoAttachPoint=\"buttonsPane\">\r\n\t\t<span dojoAttachPoint=\"_cancelBtn\" dojoType=\"dijit.form.Button\" \r\n\t\t\tdojoAttachEvent=\"onClick:_onCancel\" label=\"${_cancelBtnLabel}\">\r\n\t\t</span>\r\n\t\t<span dojoAttachPoint=\"_clearFilterBtn\" dojoType=\"dijit.form.Button\" \r\n\t\t\tdojoAttachEvent=\"onClick:_onClearFilter\" label=\"${_clearBtnLabel}\" disabled=\"true\">\r\n\t\t</span>\r\n\t\t<span dojoAttachPoint=\"_filterBtn\" dojoType=\"dijit.form.Button\" \r\n\t\t\tdojoAttachEvent=\"onClick:_onFilter\" label=\"${_filterBtnLabel}\" disabled=\"true\">\r\n\t\t</span>\r\n\t</div>\r\n</div>\r\n"),
+ widgetsInTemplate: true,
+ dlg: null,
+ postMixInProperties: function(){
+ this.plugin = this.dlg.plugin;
+ var nls = this.plugin.nls;
+ this._addRuleBtnLabel = nls.addRuleButton;
+ this._cancelBtnLabel = nls.cancelButton;
+ this._clearBtnLabel = nls.clearButton;
+ this._filterBtnLabel = nls.filterButton;
+ this._relAll = nls.relationAll;
+ this._relAny = nls.relationAny;
+ this._relMsgFront = nls.relationMsgFront;
+ this._relMsgTail = nls.relationMsgTail;
+ },
+ postCreate: function(){
+ this.inherited(arguments);
+ this.connect(this.domNode, "onkeypress", "_onKey");
+ (this.cboxContainer = new fns.AccordionContainer({
+ nls: this.plugin.nls
+ })).placeAt(this.criteriaPane);
+
+ this._relSelect.set("tabIndex", _tabIdxes.relSelect);
+ this._addCBoxBtn.set("tabIndex", _tabIdxes.addCBoxBtn);
+ this._cancelBtn.set("tabIndex", _tabIdxes.cancelBtn);
+ this._clearFilterBtn.set("tabIndex", _tabIdxes.clearBtn);
+ this._filterBtn.set("tabIndex", _tabIdxes.filterBtn);
+
+ var nls = this.plugin.nls;
+ dijit.setWaiState(this._relSelect.domNode, "label", nls.waiRelAll);
+ dijit.setWaiState(this._addCBoxBtn.domNode, "label", nls.waiAddRuleButton);
+ dijit.setWaiState(this._cancelBtn.domNode, "label", nls.waiCancelButton);
+ dijit.setWaiState(this._clearFilterBtn.domNode, "label", nls.waiClearButton);
+ dijit.setWaiState(this._filterBtn.domNode, "label", nls.waiFilterButton);
+
+ this._relSelect.set("value", this.dlg._relOpCls === "logicall" ? "0" : "1");
+ },
+ uninitialize: function(){
+ this.cboxContainer.destroyRecursive();
+ this.plugin = null;
+ this.dlg = null;
+ },
+ _onRelSelectChange: function(val){
+ this.dlg._relOpCls = val == "0" ? "logicall" : "logicany";
+ dijit.setWaiState(this._relSelect.domNode,"label", this.plugin.nls[val == "0" ? "waiRelAll" : "waiRelAny"]);
+ },
+ _onAddCBox: function(){
+ this.dlg.addCriteriaBoxes(1);
+ },
+ _onCancel: function(){
+ this.dlg.onCancel();
+ },
+ _onClearFilter: function(){
+ this.dlg.onClearFilter();
+ },
+ _onFilter: function(){
+ this.dlg.onFilter();
+ },
+ _onKey: function(e){
+ if(e.keyCode == dojo.keys.ENTER){
+ this.dlg.onFilter();
+ }
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[dijit._Widget,dijit._Templated],{
+ templateString: dojo.cache("dojox.grid", "enhanced/templates/CriteriaBox.html", "<div class=\"dojoxGridFCBox\">\r\n\t<div class=\"dojoxGridFCBoxSelCol\" dojoAttachPoint=\"selColNode\">\r\n\t\t<span class=\"dojoxGridFCBoxField\">${_colSelectLabel}</span>\r\n\t\t<select dojoAttachPoint=\"_colSelect\" dojoType=\"dijit.form.Select\" \r\n\t\t\tclass=\"dojoxGridFCBoxColSelect\"\r\n\t\t\tdojoAttachEvent=\"onChange:_onChangeColumn\">\r\n\t\t</select>\r\n\t</div>\r\n\t<div class=\"dojoxGridFCBoxCondition\" dojoAttachPoint=\"condNode\">\r\n\t\t<span class=\"dojoxGridFCBoxField\">${_condSelectLabel}</span>\r\n\t\t<select dojoAttachPoint=\"_condSelect\" dojoType=\"dijit.form.Select\" \r\n\t\t\tclass=\"dojoxGridFCBoxCondSelect\"\r\n\t\t\tdojoAttachEvent=\"onChange:_onChangeCondition\">\r\n\t\t</select>\r\n\t\t<div class=\"dojoxGridFCBoxCondSelectAlt\" dojoAttachPoint=\"_condSelectAlt\" style=\"display:none;\"></div>\r\n\t</div>\r\n\t<div class=\"dojoxGridFCBoxValue\" dojoAttachPoint=\"valueNode\">\r\n\t\t<span class=\"dojoxGridFCBoxField\">${_valueBoxLabel}</span>\r\n\t</div>\r\n</div>\r\n"),
+ widgetsInTemplate: true,
+ dlg: null,
+ postMixInProperties: function(){
+ this.plugin = this.dlg.plugin;
+ this._curValueBox = null;
+
+ var nls = this.plugin.nls;
+ this._colSelectLabel = nls.columnSelectLabel;
+ this._condSelectLabel = nls.conditionSelectLabel;
+ this._valueBoxLabel = nls.valueBoxLabel;
+ this._anyColumnOption = nls.anyColumnOption;
+ },
+ postCreate: function(){
+ var dlg = this.dlg, g = this.plugin.grid;
+ //Select Column
+ this._colSelect.set("tabIndex", _tabIdxes.colSelect);
+ this._colOptions = this._getColumnOptions();
+ this._colSelect.addOption([
+ {label: this.plugin.nls.anyColumnOption, value: "anycolumn", selected: dlg.curColIdx < 0},
+ {value: ""}
+ ].concat(this._colOptions));
+ //Select Condition
+ this._condSelect.set("tabIndex", _tabIdxes.condSelect);
+ this._condSelect.addOption(this._getUsableConditions(dlg.getColumnType(dlg.curColIdx)));
+ this._showSelectOrLabel(this._condSelect, this._condSelectAlt);
+
+ this.connect(g.layout, "moveColumn", "onMoveColumn");
+ },
+ _getColumnOptions: function(){
+ var colIdx = this.dlg.curColIdx >= 0 ? String(this.dlg.curColIdx) : "anycolumn";
+ return dojo.map(dojo.filter(this.plugin.grid.layout.cells, function(cell){
+ return !(cell.filterable === false || cell.hidden);
+ }), function(cell){
+ return {
+ label: cell.name || cell.field,
+ value: String(cell.index),
+ selected: colIdx == String(cell.index)
+ };
+ });
+ },
+ onMoveColumn: function(){
+ var tmp = this._onChangeColumn;
+ this._onChangeColumn = function(){};
+ var option = this._colSelect.get("selectedOptions");
+ this._colSelect.removeOption(this._colOptions);
+ this._colOptions = this._getColumnOptions();
+ this._colSelect.addOption(this._colOptions);
+ var i = 0;
+ for(; i < this._colOptions.length; ++i){
+ if(this._colOptions[i].label == option.label){
+ break;
+ }
+ }
+ if(i < this._colOptions.length){
+ this._colSelect.set("value", this._colOptions[i].value);
+ }
+ var _this = this;
+ setTimeout(function(){
+ _this._onChangeColumn = tmp;
+ }, 0);
+ },
+ onRemove: function(){
+ this.dlg.removeCriteriaBoxes(this);
+ },
+ uninitialize: function(){
+ if(this._curValueBox){
+ this._curValueBox.destroyRecursive();
+ this._curValueBox = null;
+ }
+ this.plugin = null;
+ this.dlg = null;
+ },
+ _showSelectOrLabel: function(sel, alt){
+ var options = sel.getOptions();
+ if(options.length == 1){
+ alt.innerHTML = options[0].label;
+ dojo.style(sel.domNode, "display", "none");
+ dojo.style(alt, "display", "");
+ }else{
+ dojo.style(sel.domNode, "display", "");
+ dojo.style(alt, "display", "none");
+ }
+ },
+ _onChangeColumn: function(val){
+ this._checkValidCriteria();
+ var type = this.dlg.getColumnType(val);
+ this._setConditionsByType(type);
+ this._setValueBoxByType(type);
+ this._updateValueBox();
+ },
+ _onChangeCondition: function(val){
+ this._checkValidCriteria();
+ var f = (val == "range");
+ if(f ^ this._isRange){
+ this._isRange = f;
+ this._setValueBoxByType(this.dlg.getColumnType(this._colSelect.get("value")));
+ }
+ this._updateValueBox();
+ },
+ _updateValueBox: function(cond){
+ this._curValueBox.set("disabled", this._condSelect.get("value") == "isempty");
+ },
+ _checkValidCriteria: function(){
+ // summary:
+ // Check whether the given criteria box is completed. If it is, mark it.
+ setTimeout(dojo.hitch(this, function(){
+ this.updateRuleTitle();
+ this.dlg._updatePane();
+ }),0);
+ },
+ _createValueBox: function(/* widget constructor */cls,/* object */arg){
+ // summary:
+ // Create a value input box with given class and arguments
+ var func = dojo.hitch(arg.cbox, "_checkValidCriteria");
+ return new cls(dojo.mixin(arg,{
+ tabIndex: _tabIdxes.valueBox,
+ onKeyPress: func,
+ onChange: func,
+ "class": "dojoxGridFCBoxValueBox"
+ }));
+ },
+ _createRangeBox: function(/* widget constructor */cls,/* object */arg){
+ // summary:
+ // Create a DIV containing 2 input widgets, which represents a range, with the given class and arguments
+ var func = dojo.hitch(arg.cbox, "_checkValidCriteria");
+ dojo.mixin(arg,{
+ tabIndex: _tabIdxes.valueBox,
+ onKeyPress: func,
+ onChange: func
+ });
+ var div = dojo.create("div", {"class": "dojoxGridFCBoxValueBox"}),
+ start = new cls(arg),
+ txt = dojo.create("span", {"class": "dojoxGridFCBoxRangeValueTxt", "innerHTML": this.plugin.nls.rangeTo}),
+ end = new cls(arg);
+ dojo.addClass(start.domNode, "dojoxGridFCBoxStartValue");
+ dojo.addClass(end.domNode, "dojoxGridFCBoxEndValue");
+ div.appendChild(start.domNode);
+ div.appendChild(txt);
+ div.appendChild(end.domNode);
+ div.domNode = div;
+ //Mock functions for set and get (in place of the old attr function)
+ div.set = function(dummy, args){
+ if(dojo.isObject(args)){
+ start.set("value", args.start);
+ end.set("value", args.end);
+ }
+ };
+ div.get = function(){
+ var s = start.get("value"),
+ e = end.get("value");
+ return s && e ? {start: s, end: e} : "";
+ };
+ return div;
+ },
+ changeCurrentColumn: function(/* bool */selectCurCol){
+ var colIdx = this.dlg.curColIdx;
+ this._colSelect.set('value', colIdx >= 0 ? String(colIdx) : "anycolumn");
+ this.updateRuleTitle(true);
+ },
+ curColumn: function(){
+ return this._colSelect.getOptions(this._colSelect.get("value")).label;
+ },
+ curCondition: function(){
+ return this._condSelect.getOptions(this._condSelect.get("value")).label;
+ },
+ curValue: function(){
+ var cond = this._condSelect.get("value");
+ if(cond == "isempty"){return "";}
+ return this._curValueBox ? this._curValueBox.get("value") : "";
+ },
+ save: function(){
+ if(this.isEmpty()){
+ return null;
+ }
+ var colIdx = this._colSelect.get("value"),
+ type = this.dlg.getColumnType(colIdx),
+ value = this.curValue(),
+ cond = this._condSelect.get("value");
+ return {
+ "column": colIdx,
+ "condition": cond,
+ "value": value,
+ "formattedVal": this.formatValue(type, cond, value),
+ "type": type,
+ "colTxt": this.curColumn(),
+ "condTxt": this.curCondition()
+ };
+ },
+ load: function(obj){
+ var tmp = [
+ this._onChangeColumn,
+ this._onChangeCondition
+ ];
+ this._onChangeColumn = this._onChangeCondition = function(){};
+ if(obj.column){
+ this._colSelect.set("value", obj.column);
+ }
+ if(obj.condition){
+ this._condSelect.set("value", obj.condition);
+ }
+ if(obj.type){
+ this._setValueBoxByType(obj.type);
+ }else{
+ obj.type = this.dlg.getColumnType(this._colSelect.get("value"));
+ }
+ var value = obj.value || "";
+ if(value || (obj.type != "date" && obj.type != "time")){
+ this._curValueBox.set("value", value);
+ }
+ this._updateValueBox();
+ setTimeout(dojo.hitch(this, function(){
+ this._onChangeColumn = tmp[0];
+ this._onChangeCondition = tmp[1];
+ }), 0);
+ },
+ getExpr: function(){
+ if(this.isEmpty()){
+ return null;
+ }
+ var colval = this._colSelect.get("value");
+ return this.dlg.getExprForCriteria({
+ "type": this.dlg.getColumnType(colval),
+ "column": colval,
+ "condition": this._condSelect.get("value"),
+ "value": this.curValue()
+ });
+ },
+ isEmpty: function(){
+ var cond = this._condSelect.get("value");
+ if(cond == "isempty"){return false;}
+ var v = this.curValue();
+ return v === "" || v === null || typeof v == "undefined" || (typeof v == "number" && isNaN(v));
+ },
+ updateRuleTitle: function(isEmpty){
+ var node = this._pane._buttonWidget.titleTextNode;
+ var title = [
+ "<div class='dojoxEllipsis'>"
+ ];
+ if(isEmpty || this.isEmpty()){
+ node.title = dojo.string.substitute(this.plugin.nls.ruleTitleTemplate, [this._ruleIndex || 1]);
+ title.push(node.title);
+ }else{
+ var type = this.dlg.getColumnType(this._colSelect.get("value"));
+ var column = this.curColumn();
+ var condition = this.curCondition();
+ var value = this.formatValue(type, this._condSelect.get("value"), this.curValue());
+ title.push(
+ column,
+ "&nbsp;<span class='dojoxGridRuleTitleCondition'>",
+ condition,
+ "</span>&nbsp;",
+ value
+ );
+ node.title = [column, " ", condition, " ", value].join('');
+ }
+ node.innerHTML = title.join('');
+ if(dojo.isMoz){
+ var tt = dojo.create("div", {
+ "style": "width: 100%; height: 100%; position: absolute; top: 0; left: 0; z-index: 9999;"
+ }, node);
+ tt.title = node.title;
+ }
+ },
+ updateRuleIndex: function(index){
+ if(this._ruleIndex != index){
+ this._ruleIndex = index;
+ if(this.isEmpty()){
+ this.updateRuleTitle();
+ }
+ }
+ },
+ setAriaInfo: function(idx){
+ var dss = dojo.string.substitute, nls = this.plugin.nls;
+ dijit.setWaiState(this._colSelect.domNode,"label", dss(nls.waiColumnSelectTemplate, [idx]));
+ dijit.setWaiState(this._condSelect.domNode,"label", dss(nls.waiConditionSelectTemplate, [idx]));
+ dijit.setWaiState(this._pane._removeCBoxBtn.domNode,"label", dss(nls.waiRemoveRuleButtonTemplate, [idx]));
+ this._index = idx;
+ },
+ _getUsableConditions: function(type){
+ var conditions = this.dlg._dataTypeMap[type].conditions;
+ var typeDisabledConds = (this.plugin.args.disabledConditions || {})[type];
+ var colIdx = parseInt(this._colSelect.get("value"), 10);
+ var colDisabledConds = isNaN(colIdx) ?
+ (this.plugin.args.disabledConditions || {})["anycolumn"] :
+ this.plugin.grid.layout.cells[colIdx].disabledConditions;
+ if(!dojo.isArray(typeDisabledConds)){
+ typeDisabledConds = [];
+ }
+ if(!dojo.isArray(colDisabledConds)){
+ colDisabledConds = [];
+ }
+ var arr = typeDisabledConds.concat(colDisabledConds);
+ if(arr.length){
+ var disabledConds = {};
+ dojo.forEach(arr, function(c){
+ if(dojo.isString(c)){
+ disabledConds[c.toLowerCase()] = true;
+ }
+ });
+ return dojo.filter(conditions, function(condOption){
+ return !(condOption.value in disabledConds);
+ });
+ }
+ return conditions;
+ },
+ _setConditionsByType: function(/* string */type){
+ var condSelect = this._condSelect;
+ condSelect.removeOption(condSelect.options);
+ condSelect.addOption(this._getUsableConditions(type));
+ this._showSelectOrLabel(this._condSelect, this._condSelectAlt);
+ },
+ _setValueBoxByType: function(/* string */type){
+ if(this._curValueBox){
+ this.valueNode.removeChild(this._curValueBox.domNode);
+ try{
+ this._curValueBox.destroyRecursive();
+ }catch(e){}
+ delete this._curValueBox;
+ }
+ //value box class
+ var vbcls = this.dlg._dataTypeMap[type].valueBoxCls[this._getValueBoxClsInfo(this._colSelect.get("value"), type)],
+ vboxArg = this._getValueBoxArgByType(type);
+ this._curValueBox = this[this._isRange ? "_createRangeBox" : "_createValueBox"](vbcls, vboxArg);
+ this.valueNode.appendChild(this._curValueBox.domNode);
+
+ //Can not move to setAriaInfo, 'cause the value box is created after the defpane is loaded.
+ dijit.setWaiState(this._curValueBox.domNode, "label", dojo.string.substitute(this.plugin.nls.waiValueBoxTemplate,[this._index]));
+ //Now our cbox is completely ready
+ this.dlg.onRendered(this);
+ },
+ //--------------------------UI Configuration--------------------------------------
+ _getValueBoxArgByType: function(/* string */type){
+ // summary:
+ // Get the arguments for the value box construction.
+ var g = this.plugin.grid,
+ cell = g.layout.cells[parseInt(this._colSelect.get("value"), 10)],
+ res = {
+ cbox: this
+ };
+ if(type == "string"){
+ if(cell && (cell.suggestion || cell.autoComplete)){
+ dojo.mixin(res, {
+ store: g.store,
+ searchAttr: cell.field || cell.name,
+ fetchProperties: {
+ sort: [{"attribute": cell.field || cell.name}]
+ }
+ });
+ }
+ }else if(type == "boolean"){
+ dojo.mixin(res, this.dlg.builder.defaultArgs["boolean"]);
+ }
+ if(cell && cell.dataTypeArgs){
+ dojo.mixin(res, cell.dataTypeArgs);
+ }
+ return res;
+ },
+ formatValue: function(type, cond, v){
+ // summary:
+ // Format the value to be shown in tooltip.
+ if(cond == "isempty"){return "";}
+ if(type == "date" || type == "time"){
+ var opt = {selector: type},
+ fmt = dojo.date.locale.format;
+ if(cond == "range"){
+ return dojo.string.substitute(this.plugin.nls.rangeTemplate, [fmt(v.start, opt), fmt(v.end, opt)]);
+ }
+ return fmt(v, opt);
+ }else if(type == "boolean"){
+ return v ? this._curValueBox._lblTrue : this._curValueBox._lblFalse;
+ }
+ return v;
+ },
+ _getValueBoxClsInfo: function(/* int|string */colIndex, /* string */type){
+ // summary:
+ // Decide which value box to use given data type and column index.
+ var cell = this.plugin.grid.layout.cells[parseInt(colIndex, 10)];
+ //Now we only need to handle string. But maybe we need to handle more types here in the future.
+ if(type == "string"){
+ return (cell && (cell.suggestion || cell.autoComplete)) ? "ac" : "dft";
+ }
+ return "dft";
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter.AccordionContainer", dijit.layout.AccordionContainer, {
+ nls: null,
+ addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
+ var pane = arguments[0] = child._pane = new dijit.layout.ContentPane({
+ content: child
+ });
+ this.inherited(arguments);
+ this._modifyChild(pane);
+ },
+ removeChild: function(child){
+ var pane = child, isRemoveByUser = false;
+ if(child._pane){
+ isRemoveByUser = true;
+ pane = arguments[0] = child._pane;
+ }
+ this.inherited(arguments);
+ if(isRemoveByUser){
+ this._hackHeight(false, this._titleHeight);
+ var children = this.getChildren();
+ if(children.length === 1){
+ dojo.style(children[0]._removeCBoxBtn.domNode, "display", "none");
+ }
+ }
+ pane.destroyRecursive();
+ },
+ selectChild: function(child){
+ if(child._pane){
+ arguments[0] = child._pane;
+ }
+ this.inherited(arguments);
+ },
+ resize: function(){
+ this.inherited(arguments);
+ dojo.forEach(this.getChildren(), this._setupTitleDom);
+ },
+ startup: function(){
+ if(this._started){
+ return;
+ }
+ this.inherited(arguments);
+ if(parseInt(dojo.isIE, 10) == 7){
+ //IE7 will fire a lot of "onresize" event during initialization.
+ dojo.some(this._connects, function(cnnt){
+ if(cnnt[0][1] == "onresize"){
+ this.disconnect(cnnt);
+ return true;
+ }
+ }, this);
+ }
+ dojo.forEach(this.getChildren(), function(child){
+ this._modifyChild(child, true);
+ }, this);
+ },
+ _onKeyPress: function(/*Event*/ e, /*dijit._Widget*/ fromTitle){
+ // summary:
+ // Overrides base class method, make left/right button do other things.
+ if(this.disabled || e.altKey || !(fromTitle || e.ctrlKey)){
+ return;
+ }
+ var k = dojo.keys, c = e.charOrCode, ltr = dojo._isBodyLtr(), toNext = null;
+ if((fromTitle && c == k.UP_ARROW) || (e.ctrlKey && c == k.PAGE_UP)){
+ toNext = false;
+ }else if((fromTitle && c == k.DOWN_ARROW) || (e.ctrlKey && (c == k.PAGE_DOWN || c == k.TAB))){
+ toNext = true;
+ }else if(c == (ltr ? k.LEFT_ARROW : k.RIGHT_ARROW)){
+ toNext = this._focusOnRemoveBtn ? null : false;
+ this._focusOnRemoveBtn = !this._focusOnRemoveBtn;
+ }else if(c == (ltr ? k.RIGHT_ARROW : k.LEFT_ARROW)){
+ toNext = this._focusOnRemoveBtn ? true : null;
+ this._focusOnRemoveBtn = !this._focusOnRemoveBtn;
+ }else{
+ return;
+ }
+ if(toNext !== null){
+ this._adjacent(toNext)._buttonWidget._onTitleClick();
+ }
+ dojo.stopEvent(e);
+ dojo.window.scrollIntoView(this.selectedChildWidget._buttonWidget.domNode.parentNode);
+ if(dojo.isIE){
+ //IE will not show focus indicator if tabIndex is -1
+ this.selectedChildWidget._removeCBoxBtn.focusNode.setAttribute("tabIndex", this._focusOnRemoveBtn ? _tabIdxes.accordionTitle : -1);
+ }
+ dijit.focus(this.selectedChildWidget[this._focusOnRemoveBtn ? "_removeCBoxBtn" : "_buttonWidget"].focusNode);
+ },
+ _modifyChild: function(child, isFirst){
+ if(!child || !this._started){
+ return;
+ }
+ dojo.style(child.domNode, "overflow", "hidden");
+ child._buttonWidget.connect(child._buttonWidget, "_setSelectedAttr", function(){
+ this.focusNode.setAttribute("tabIndex", this.selected ? _tabIdxes.accordionTitle : "-1");
+ });
+ var _this = this;
+ child._buttonWidget.connect(child._buttonWidget.domNode, "onclick", function(){
+ _this._focusOnRemoveBtn = false;
+ });
+ (child._removeCBoxBtn = new dijit.form.Button({
+ label: this.nls.removeRuleButton,
+ showLabel: false,
+ iconClass: "dojoxGridFCBoxRemoveCBoxBtnIcon",
+ tabIndex: _tabIdxes.removeCBoxBtn,
+ onClick: dojo.hitch(child.content, "onRemove"),
+ onKeyPress: function(e){
+ _this._onKeyPress(e, child._buttonWidget.contentWidget);
+ }
+ })).placeAt(child._buttonWidget.domNode);
+ var i, children = this.getChildren();
+ if(children.length === 1){
+ child._buttonWidget.set("selected", true);
+ dojo.style(child._removeCBoxBtn.domNode, "display", "none");
+ }else{
+ for(i = 0; i < children.length; ++i){
+ if(children[i]._removeCBoxBtn){
+ dojo.style(children[i]._removeCBoxBtn.domNode, "display", "");
+ }
+ }
+ }
+ this._setupTitleDom(child);
+ if(!this._titleHeight){
+ for(i = 0; i < children.length; ++i){
+ if(children[i] != this.selectedChildWidget){
+ this._titleHeight = dojo.marginBox(children[i]._buttonWidget.domNode.parentNode).h;
+ break;
+ }
+ }
+ }
+ if(!isFirst){
+ this._hackHeight(true, this._titleHeight);
+ }
+ },
+ _hackHeight: function(/* bool */toGrow,/* int */heightDif){
+ var children = this.getChildren(),
+ dn = this.domNode, h = dojo.style(dn, "height");
+ if(!toGrow){
+ dn.style.height = (h - heightDif) + 'px';
+ }else if(children.length > 1){
+ dn.style.height = (h + heightDif) + 'px';
+ }else{
+ //Only one rule, no need to do anything.
+ return;
+ }
+ this.resize();
+ },
+ _setupTitleDom: function(child){
+ var w = dojo.contentBox(child._buttonWidget.titleNode).w;
+ if(dojo.isIE < 8){ w -= 8; }
+ dojo.style(child._buttonWidget.titleTextNode, "width", w + "px");
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter.UniqueComboBox", dijit.form.ComboBox, {
+ _openResultList: function(results){
+ var cache = {}, s = this.store, colName = this.searchAttr;
+ arguments[0] = dojo.filter(results, function(item){
+ var key = s.getValue(item, colName), existed = cache[key];
+ cache[key] = true;
+ return !existed;
+ });
+ this.inherited(arguments);
+ },
+ _onKey: function(evt){
+ if(evt.charOrCode === dojo.keys.ENTER && this._opened){
+ dojo.stopEvent(evt);
+ }
+ this.inherited(arguments);
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter.BooleanValueBox", [dijit._Widget, dijit._Templated], {
+ templateString: dojo.cache("dojox.grid", "enhanced/templates/FilterBoolValueBox.html", "<div class=\"dojoxGridBoolValueBox\">\r\n\t<div class=\"dojoxGridTrueBox\">\r\n\t\t<input dojoType=\"dijit.form.RadioButton\" type='radio' name='a1' id='${_baseId}_rbTrue' checked=\"true\" \r\n\t\t\tdojoAttachPoint=\"rbTrue\" dojoAttachEvent=\"onChange: onChange\"/>\r\n\t\t<div class=\"dojoxGridTrueLabel\" for='${_baseId}_rbTrue'>${_lblTrue}</div>\r\n\t</div>\r\n\t<div class=\"dojoxGridFalseBox\">\r\n\t\t<input dojoType=\"dijit.form.RadioButton\" dojoAttachPoint=\"rbFalse\" type='radio' name='a1' id='${_baseId}_rbFalse'/>\r\n\t\t<div class=\"dojoxGridTrueLabel\" for='${_baseId}_rbFalse'>${_lblFalse}</div>\r\n\t</div>\r\n</div>\r\n"),
+ widgetsInTemplate: true,
+ constructor: function(args){
+ var nls = args.cbox.plugin.nls;
+ this._baseId = args.cbox.id;
+ this._lblTrue = args.trueLabel || nls.trueLabel || "true";
+ this._lblFalse = args.falseLabel || nls.falseLabel || "false";
+ this.args = args;
+ },
+ postCreate: function(){
+ this.onChange();
+ },
+ onChange: function(){},
+
+ get: function(prop){
+ return this.rbTrue.get("checked");
+ },
+ set: function(prop, v){
+ this.inherited(arguments);
+ if(prop == "value"){
+ this.rbTrue.set("checked", !!v);
+ this.rbFalse.set("checked", !v);
+ }
+ }
+});
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterLayer.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterLayer.js
new file mode 100644
index 0000000..9125d4c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterLayer.js
@@ -0,0 +1,415 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterLayer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterLayer"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter.FilterLayer");
+
+dojo.require("dojox.grid.enhanced.plugins.filter._FilterExpr");
+dojo.require("dojox.grid.enhanced.plugins._StoreLayer");
+
+(function(){
+var ns = dojox.grid.enhanced.plugins,
+ cmdSetFilter = "filter",
+ cmdClearFilter = "clear",
+ hitchIfCan = function(scope, func){
+ return func ? dojo.hitch(scope || dojo.global, func) : function(){};
+ },
+ shallowClone = function(obj){
+ var res = {};
+ if(obj && dojo.isObject(obj)){
+ for(var name in obj){
+ res[name] = obj[name];
+ }
+ }
+ return res;
+ };
+ dojo.declare("dojox.grid.enhanced.plugins.filter._FilterLayerMixin", null, {
+/*=====
+ // _filter: _ConditionExpr
+ // The filter definition
+ _filter: null,
+
+ filterDef: function(filter){
+ // summary:
+ // Get/set/clear the filter definition
+ // tags:
+ // public
+ // filter: (_ConditionExpr|null)?
+ // null: clear filter definition
+ // undefined: it's getter
+ // returns:
+ // A filter definition if it's getter.
+ },
+=====*/
+ tags: ["sizeChange"],
+ name: function(){
+ // summary:
+ // override from _StoreLayer.name
+ return "filter"; //string
+ },
+ onFilterDefined: function(filter){},
+
+ onFiltered: function(filteredSize, totalSize){
+ // summary:
+ // Called when store data is filtered. This event is before *onComplete*, after *onBegin*.
+ // tags:
+ // callback extension
+ // filteredSize: Integer
+ // The number of remaining fetched items after filtering.
+ // totalSize: Integer
+ // The number of original fetched items.
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.ServerSideFilterLayer", [ns._ServerSideLayer, ns.filter._FilterLayerMixin], {
+ constructor: function(args){
+ this._onUserCommandLoad = args.setupFilterQuery || this._onUserCommandLoad;
+ this.filterDef(null);
+ },
+ filterDef: function(/* (_ConditionExpr|null)? */filter){
+ // summary:
+ // See _FilterLayerMixin.filterDef
+ if(filter){
+ this._filter = filter;
+ var obj = filter.toObject();
+ //Stateless implementation will need to parse the filter object.
+ this.command(cmdSetFilter, this._isStateful ? dojo.toJson(obj) : obj);
+ this.command(cmdClearFilter, null);
+ this.useCommands(true);
+ this.onFilterDefined(filter);
+ }else if(filter === null){
+ this._filter = null;
+ this.command(cmdSetFilter, null);
+ this.command(cmdClearFilter, true);
+ this.useCommands(true);
+ this.onFilterDefined(null);
+ }
+ return this._filter; //_ConditionExpr
+ },
+ onCommandLoad: function(/* (in)string */responce, /* (in|out)keywordArgs */ userRequest){
+ // summary:
+ // override from _ServerSideLayer.onCommandLoad
+ this.inherited(arguments);
+ var oldOnBegin = userRequest.onBegin;
+ if(this._isStateful){
+ var filteredSize;
+ if(responce){
+ this.command(cmdSetFilter, null);
+ this.command(cmdClearFilter, null);
+ this.useCommands(false);
+ var sizes = responce.split(',');
+ if(sizes.length >= 2){
+ filteredSize = this._filteredSize = parseInt(sizes[0], 10);
+ this.onFiltered(filteredSize, parseInt(sizes[1], 10));
+ }else{
+ //Error here.
+ return;
+ }
+ }else{
+ filteredSize = this._filteredSize;
+ }
+ if(this.enabled()){
+ userRequest.onBegin = function(size, req){
+ hitchIfCan(userRequest.scope, oldOnBegin)(filteredSize, req);
+ };
+ }
+ }else{
+ var _this = this;
+ userRequest.onBegin = function(size, req){
+ if(!_this._filter){
+ _this._storeSize = size;
+ }
+ _this.onFiltered(size, _this._storeSize || size);
+ req.onBegin = oldOnBegin;
+ hitchIfCan(userRequest.scope, oldOnBegin)(size, req);
+ };
+ }
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.ClientSideFilterLayer", [ns._StoreLayer, ns.filter._FilterLayerMixin], {
+ // summary:
+ // Add a client side filter layer on top of the data store,
+ // so any filter expression can be applied to the store.
+/*=====
+ //_items: Array,
+ // Cached items (may contain holes)
+ _items: [],
+
+ //_result: Array,
+ // Current fetch result
+ _result: [],
+
+ //_resultStartIdx: Integer,
+ // The index in cache of the first result item
+ _resultStartIdx: 0,
+
+ //_indexMap: Array,
+ // A map from the row index of this._items to the row index of the original store.
+ _indexMap: null,
+
+ //_getter: function(datarow, colArg, rowIndex, store);
+ // A user defined way to get data from store
+ _getter: null,
+
+ // _nextUnfetchedIdx: Integer
+ // The index of the next item in the store that is never fetched.
+ _nextUnfetchedIdx: 0,
+=====*/
+ // _storeSize: Integer
+ // The actual size of the original store
+ _storeSize: -1,
+
+ // _fetchAll
+ // If the store is small or store size must be correct when onBegin is called,
+ // we should fetch and filter all the items on the first query.
+ _fetchAll: true,
+
+ constructor: function(args){
+ this.filterDef(null);
+ args = dojo.isObject(args) ? args : {};
+ this.fetchAllOnFirstFilter(args.fetchAll);
+ this._getter = dojo.isFunction(args.getter) ? args.getter : this._defaultGetter;
+ },
+ _defaultGetter: function(datarow, colName, rowIndex, store){
+ return store.getValue(datarow, colName);
+ },
+ filterDef: function(/* (_ConditionExpr|null)? */filter){
+ // summary:
+ // See _FilterLayerMixin.filterDef
+ if(filter !== undefined){
+ this._filter = filter;
+ this.invalidate();
+ this.onFilterDefined(filter);
+ }
+ return this._filter; //_ConditionExpr
+ },
+ setGetter: function(/* function */getter){
+ // summary:
+ // Set the user defined way to retrieve data from store.
+ // tags:
+ // public
+ // getter: function(datarow, colArg, rowIndex, store);
+ if(dojo.isFunction(getter)){
+ this._getter = getter;
+ }
+ },
+ fetchAllOnFirstFilter: function(/* bool? */toFetchAll){
+ // summary:
+ // The get/set function for fetchAll.
+ // tags:
+ // public
+ // toFetchAll: boolean?
+ // If provided, it's a set function, otherwise it's a get function.
+ // returns:
+ // Whether fetch all on first filter if this is a getter
+ if(toFetchAll !== undefined){
+ this._fetchAll = !!toFetchAll;
+ }
+ return this._fetchAll; //Boolean
+ },
+ invalidate: function(){
+ // summary:
+ // Clear all the status information of this layer
+ // tags:
+ // private
+ this._items = [];
+ this._nextUnfetchedIdx = 0;
+ this._result = [];
+ this._indexMap = [];
+ this._resultStartIdx = 0;
+ },
+ //----------------Private Functions-----------------------------
+ _fetch: function(userRequest,filterRequest){
+ // summary:
+ // Implement _StoreLayer._fetch
+ // tags:
+ // private callback
+ // filterRequest: dojo.data.api.Request
+ // The actual request used in store.fetch.
+ // This function is called recursively to fill the result store items
+ // until the user specified item count is reached. Only in recursive calls,
+ // this parameter is valid.
+ if(!this._filter){
+ //If we don't have any filter, use the original request and fetch.
+ var old_onbegin = userRequest.onBegin, _this = this;
+ userRequest.onBegin = function(size, r){
+ hitchIfCan(userRequest.scope, old_onbegin)(size, r);
+ _this.onFiltered(size, size);
+ };
+ this.originFetch(userRequest);
+ return userRequest;
+ }
+ try{
+ //If the fetch is at the beginning, user's start position is used;
+ //If we are in a recursion, our own request is used.
+ var start = filterRequest ? filterRequest._nextResultItemIdx : userRequest.start;
+ start = start || 0;
+ if(!filterRequest){
+ //Initially, we have no results.
+ this._result = [];
+ this._resultStartIdx = start;
+ var sortStr;
+ if(dojo.isArray(userRequest.sort) && userRequest.sort.length > 0 &&
+ //Sort info will stay here in every re-fetch, so remember it!
+ (sortStr = dojo.toJson(userRequest.sort)) != this._lastSortInfo){
+ //If we should sort data, all the old caches are no longer valid.
+ this.invalidate();
+ this._lastSortInfo = sortStr;
+ }
+ }
+ //this._result contains the current fetch result (of every recursion).
+ var end = typeof userRequest.count == "number" ?
+ start + userRequest.count - this._result.length : this._items.length;
+ //Try to retrieve all the items from our cache.
+ //Only need items after userRequest.start, test it in case start is smaller.
+ if(this._result.length){
+ this._result = this._result.concat(this._items.slice(start, end));
+ }else{
+ this._result = this._items.slice(userRequest.start, typeof userRequest.count == "number" ?
+ userRequest.start + userRequest.count : this._items.length);
+ }
+ if(this._result.length >= userRequest.count || this._hasReachedStoreEnd()){
+ //We already have had enough items, or we have to stop fetching because there's nothing more to fetch.
+ this._completeQuery(userRequest);
+ }else{
+ //User's request hasn't been finished yet. Fetch more.
+ if(!filterRequest){
+ //Initially, we've got to create a new request object.
+ filterRequest = shallowClone(userRequest);
+ //Use our own onBegin function to remember the total size of the original store.
+ filterRequest.onBegin = dojo.hitch(this, this._onFetchBegin);
+ filterRequest.onComplete = dojo.hitch(this, function(items, req){
+ //We've fetched some more, so march ahead!
+ this._nextUnfetchedIdx += items.length;
+ //Actual filtering work goes here. Survived items are added to our cache.
+ //req is our own request object.
+ this._doFilter(items, req.start, userRequest);
+ //Recursively call this function. Let's do this again!
+ this._fetch(userRequest, req);
+ });
+ }
+ //Fetch starts from the next unfetched item.
+ filterRequest.start = this._nextUnfetchedIdx;
+ //If store is small, we should only fetch once.
+ if(this._fetchAll){
+ delete filterRequest.count;
+ }
+ //Remember we've (maybe) already added something to our result array, so next time we should not start over again.
+ filterRequest._nextResultItemIdx = end < this._items.length ? end : this._items.length;
+ //Actual fetch work goes here.
+ this.originFetch(filterRequest);
+ }
+ }catch(e){
+ if(userRequest.onError){
+ hitchIfCan(userRequest.scope, userRequest.onError)(e, userRequest);
+ }else{
+ throw e;
+ }
+ }
+ return userRequest;
+ },
+ _hasReachedStoreEnd: function(){
+ // summary:
+ // Check whether all the items in the original store have been fetched.
+ // tags:
+ // private
+ return this._storeSize >= 0 && this._nextUnfetchedIdx >= this._storeSize; //Boolean
+ },
+ _applyFilter: function(/* data item */datarow,/* Integer */rowIndex){
+ // summary:
+ // Apply the filter to a row of data
+ // tags:
+ // private
+ // returns:
+ // whether this row survived the filter.
+ var g = this._getter, s = this._store;
+ try{
+ return !!(this._filter.applyRow(datarow, function(item, arg){
+ return g(item, arg, rowIndex, s);
+ }).getValue());
+ }catch(e){
+ console.warn("FilterLayer._applyFilter() error: ", e);
+ return false;
+ }
+ },
+ _doFilter: function(/* Array */items,/* Integer */startIdx,/* object */userRequest){
+ // summary:
+ // Use the filter expression to filter items. Survived items are stored in this._items.
+ // The given items start from "startIdx" in the original store.
+ // tags:
+ // private
+ for(var i = 0, cnt = 0; i < items.length; ++i){
+ if(this._applyFilter(items[i], startIdx + i)){
+ hitchIfCan(userRequest.scope, userRequest.onItem)(items[i], userRequest);
+ cnt += this._addCachedItems(items[i], this._items.length);
+ this._indexMap.push(startIdx + i);
+ }
+ }
+ },
+ _onFetchBegin: function(/* Integer */size,/* request object */req){
+ // summary:
+ // This function is used to replace the user's onFetchBegin in store.fetch
+ // tags:
+ // private
+ this._storeSize = size;
+ },
+ _completeQuery: function(/* request object */userRequest){
+ // summary:
+ // Logically, the user's query is completed here, i.e., all the filtered results are ready.
+ // (or their index mappings are ready)
+ // tags:
+ // private
+ var size = this._items.length;
+ if(this._nextUnfetchedIdx < this._storeSize){
+ //FIXME: There's still some items in the original store that are not fetched & filtered.
+ //So we have to estimate a little bigger size to allow scrolling to these unfetched items.
+ //However, this behavior is ONLY correct in Grid! Any better way to do this?
+ size++;
+ }
+ hitchIfCan(userRequest.scope, userRequest.onBegin)(size,userRequest);
+ this.onFiltered(this._items.length, this._storeSize);
+ hitchIfCan(userRequest.scope, userRequest.onComplete)(this._result, userRequest);
+ },
+ _addCachedItems: function(/* Array */items,/* Integer */filterStartIdx){
+ // summary:
+ // Add data items to the cache. The insert point is at *filterStartIdx*
+ // tags:
+ // private
+ // items: Array
+ // Data items to add.
+ // filterStartIdx: Integer
+ // The start point to insert in the cache.
+ if(!dojo.isArray(items)){
+ items = [items];
+ }
+ for(var k = 0; k < items.length; ++k){
+ this._items[filterStartIdx + k] = items[k];
+ }
+ return items.length;
+ },
+ onRowMappingChange: function(mapping){
+ //This function runs in FilterLayer scope!
+ if(this._filter){
+ var m = dojo.clone(mapping),
+ alreadyUpdated = {};
+ for(var r in m){
+ r = parseInt(r, 10);
+ mapping[this._indexMap[r]] = this._indexMap[m[r]];
+ if(!alreadyUpdated[this._indexMap[r]]){
+ alreadyUpdated[this._indexMap[r]] = true;
+ }
+ if(!alreadyUpdated[r]){
+ alreadyUpdated[r] = true;
+ delete mapping[r];
+ }
+ }
+ }
+ }
+ });
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterLayer.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterLayer.xd.js
new file mode 100644
index 0000000..e4306ec
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterLayer.xd.js
@@ -0,0 +1,421 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.filter.FilterLayer"],
+["require", "dojox.grid.enhanced.plugins.filter._FilterExpr"],
+["require", "dojox.grid.enhanced.plugins._StoreLayer"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterLayer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterLayer"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter.FilterLayer");
+
+dojo.require("dojox.grid.enhanced.plugins.filter._FilterExpr");
+dojo.require("dojox.grid.enhanced.plugins._StoreLayer");
+
+(function(){
+var ns = dojox.grid.enhanced.plugins,
+ cmdSetFilter = "filter",
+ cmdClearFilter = "clear",
+ hitchIfCan = function(scope, func){
+ return func ? dojo.hitch(scope || dojo.global, func) : function(){};
+ },
+ shallowClone = function(obj){
+ var res = {};
+ if(obj && dojo.isObject(obj)){
+ for(var name in obj){
+ res[name] = obj[name];
+ }
+ }
+ return res;
+ };
+ dojo.declare("dojox.grid.enhanced.plugins.filter._FilterLayerMixin", null, {
+/*=====
+ // _filter: _ConditionExpr
+ // The filter definition
+ _filter: null,
+
+ filterDef: function(filter){
+ // summary:
+ // Get/set/clear the filter definition
+ // tags:
+ // public
+ // filter: (_ConditionExpr|null)?
+ // null: clear filter definition
+ // undefined: it's getter
+ // returns:
+ // A filter definition if it's getter.
+ },
+=====*/
+ tags: ["sizeChange"],
+ name: function(){
+ // summary:
+ // override from _StoreLayer.name
+ return "filter"; //string
+ },
+ onFilterDefined: function(filter){},
+
+ onFiltered: function(filteredSize, totalSize){
+ // summary:
+ // Called when store data is filtered. This event is before *onComplete*, after *onBegin*.
+ // tags:
+ // callback extension
+ // filteredSize: Integer
+ // The number of remaining fetched items after filtering.
+ // totalSize: Integer
+ // The number of original fetched items.
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.ServerSideFilterLayer", [ns._ServerSideLayer, ns.filter._FilterLayerMixin], {
+ constructor: function(args){
+ this._onUserCommandLoad = args.setupFilterQuery || this._onUserCommandLoad;
+ this.filterDef(null);
+ },
+ filterDef: function(/* (_ConditionExpr|null)? */filter){
+ // summary:
+ // See _FilterLayerMixin.filterDef
+ if(filter){
+ this._filter = filter;
+ var obj = filter.toObject();
+ //Stateless implementation will need to parse the filter object.
+ this.command(cmdSetFilter, this._isStateful ? dojo.toJson(obj) : obj);
+ this.command(cmdClearFilter, null);
+ this.useCommands(true);
+ this.onFilterDefined(filter);
+ }else if(filter === null){
+ this._filter = null;
+ this.command(cmdSetFilter, null);
+ this.command(cmdClearFilter, true);
+ this.useCommands(true);
+ this.onFilterDefined(null);
+ }
+ return this._filter; //_ConditionExpr
+ },
+ onCommandLoad: function(/* (in)string */responce, /* (in|out)keywordArgs */ userRequest){
+ // summary:
+ // override from _ServerSideLayer.onCommandLoad
+ this.inherited(arguments);
+ var oldOnBegin = userRequest.onBegin;
+ if(this._isStateful){
+ var filteredSize;
+ if(responce){
+ this.command(cmdSetFilter, null);
+ this.command(cmdClearFilter, null);
+ this.useCommands(false);
+ var sizes = responce.split(',');
+ if(sizes.length >= 2){
+ filteredSize = this._filteredSize = parseInt(sizes[0], 10);
+ this.onFiltered(filteredSize, parseInt(sizes[1], 10));
+ }else{
+ //Error here.
+ return;
+ }
+ }else{
+ filteredSize = this._filteredSize;
+ }
+ if(this.enabled()){
+ userRequest.onBegin = function(size, req){
+ hitchIfCan(userRequest.scope, oldOnBegin)(filteredSize, req);
+ };
+ }
+ }else{
+ var _this = this;
+ userRequest.onBegin = function(size, req){
+ if(!_this._filter){
+ _this._storeSize = size;
+ }
+ _this.onFiltered(size, _this._storeSize || size);
+ req.onBegin = oldOnBegin;
+ hitchIfCan(userRequest.scope, oldOnBegin)(size, req);
+ };
+ }
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.ClientSideFilterLayer", [ns._StoreLayer, ns.filter._FilterLayerMixin], {
+ // summary:
+ // Add a client side filter layer on top of the data store,
+ // so any filter expression can be applied to the store.
+/*=====
+ //_items: Array,
+ // Cached items (may contain holes)
+ _items: [],
+
+ //_result: Array,
+ // Current fetch result
+ _result: [],
+
+ //_resultStartIdx: Integer,
+ // The index in cache of the first result item
+ _resultStartIdx: 0,
+
+ //_indexMap: Array,
+ // A map from the row index of this._items to the row index of the original store.
+ _indexMap: null,
+
+ //_getter: function(datarow, colArg, rowIndex, store);
+ // A user defined way to get data from store
+ _getter: null,
+
+ // _nextUnfetchedIdx: Integer
+ // The index of the next item in the store that is never fetched.
+ _nextUnfetchedIdx: 0,
+=====*/
+ // _storeSize: Integer
+ // The actual size of the original store
+ _storeSize: -1,
+
+ // _fetchAll
+ // If the store is small or store size must be correct when onBegin is called,
+ // we should fetch and filter all the items on the first query.
+ _fetchAll: true,
+
+ constructor: function(args){
+ this.filterDef(null);
+ args = dojo.isObject(args) ? args : {};
+ this.fetchAllOnFirstFilter(args.fetchAll);
+ this._getter = dojo.isFunction(args.getter) ? args.getter : this._defaultGetter;
+ },
+ _defaultGetter: function(datarow, colName, rowIndex, store){
+ return store.getValue(datarow, colName);
+ },
+ filterDef: function(/* (_ConditionExpr|null)? */filter){
+ // summary:
+ // See _FilterLayerMixin.filterDef
+ if(filter !== undefined){
+ this._filter = filter;
+ this.invalidate();
+ this.onFilterDefined(filter);
+ }
+ return this._filter; //_ConditionExpr
+ },
+ setGetter: function(/* function */getter){
+ // summary:
+ // Set the user defined way to retrieve data from store.
+ // tags:
+ // public
+ // getter: function(datarow, colArg, rowIndex, store);
+ if(dojo.isFunction(getter)){
+ this._getter = getter;
+ }
+ },
+ fetchAllOnFirstFilter: function(/* bool? */toFetchAll){
+ // summary:
+ // The get/set function for fetchAll.
+ // tags:
+ // public
+ // toFetchAll: boolean?
+ // If provided, it's a set function, otherwise it's a get function.
+ // returns:
+ // Whether fetch all on first filter if this is a getter
+ if(toFetchAll !== undefined){
+ this._fetchAll = !!toFetchAll;
+ }
+ return this._fetchAll; //Boolean
+ },
+ invalidate: function(){
+ // summary:
+ // Clear all the status information of this layer
+ // tags:
+ // private
+ this._items = [];
+ this._nextUnfetchedIdx = 0;
+ this._result = [];
+ this._indexMap = [];
+ this._resultStartIdx = 0;
+ },
+ //----------------Private Functions-----------------------------
+ _fetch: function(userRequest,filterRequest){
+ // summary:
+ // Implement _StoreLayer._fetch
+ // tags:
+ // private callback
+ // filterRequest: dojo.data.api.Request
+ // The actual request used in store.fetch.
+ // This function is called recursively to fill the result store items
+ // until the user specified item count is reached. Only in recursive calls,
+ // this parameter is valid.
+ if(!this._filter){
+ //If we don't have any filter, use the original request and fetch.
+ var old_onbegin = userRequest.onBegin, _this = this;
+ userRequest.onBegin = function(size, r){
+ hitchIfCan(userRequest.scope, old_onbegin)(size, r);
+ _this.onFiltered(size, size);
+ };
+ this.originFetch(userRequest);
+ return userRequest;
+ }
+ try{
+ //If the fetch is at the beginning, user's start position is used;
+ //If we are in a recursion, our own request is used.
+ var start = filterRequest ? filterRequest._nextResultItemIdx : userRequest.start;
+ start = start || 0;
+ if(!filterRequest){
+ //Initially, we have no results.
+ this._result = [];
+ this._resultStartIdx = start;
+ var sortStr;
+ if(dojo.isArray(userRequest.sort) && userRequest.sort.length > 0 &&
+ //Sort info will stay here in every re-fetch, so remember it!
+ (sortStr = dojo.toJson(userRequest.sort)) != this._lastSortInfo){
+ //If we should sort data, all the old caches are no longer valid.
+ this.invalidate();
+ this._lastSortInfo = sortStr;
+ }
+ }
+ //this._result contains the current fetch result (of every recursion).
+ var end = typeof userRequest.count == "number" ?
+ start + userRequest.count - this._result.length : this._items.length;
+ //Try to retrieve all the items from our cache.
+ //Only need items after userRequest.start, test it in case start is smaller.
+ if(this._result.length){
+ this._result = this._result.concat(this._items.slice(start, end));
+ }else{
+ this._result = this._items.slice(userRequest.start, typeof userRequest.count == "number" ?
+ userRequest.start + userRequest.count : this._items.length);
+ }
+ if(this._result.length >= userRequest.count || this._hasReachedStoreEnd()){
+ //We already have had enough items, or we have to stop fetching because there's nothing more to fetch.
+ this._completeQuery(userRequest);
+ }else{
+ //User's request hasn't been finished yet. Fetch more.
+ if(!filterRequest){
+ //Initially, we've got to create a new request object.
+ filterRequest = shallowClone(userRequest);
+ //Use our own onBegin function to remember the total size of the original store.
+ filterRequest.onBegin = dojo.hitch(this, this._onFetchBegin);
+ filterRequest.onComplete = dojo.hitch(this, function(items, req){
+ //We've fetched some more, so march ahead!
+ this._nextUnfetchedIdx += items.length;
+ //Actual filtering work goes here. Survived items are added to our cache.
+ //req is our own request object.
+ this._doFilter(items, req.start, userRequest);
+ //Recursively call this function. Let's do this again!
+ this._fetch(userRequest, req);
+ });
+ }
+ //Fetch starts from the next unfetched item.
+ filterRequest.start = this._nextUnfetchedIdx;
+ //If store is small, we should only fetch once.
+ if(this._fetchAll){
+ delete filterRequest.count;
+ }
+ //Remember we've (maybe) already added something to our result array, so next time we should not start over again.
+ filterRequest._nextResultItemIdx = end < this._items.length ? end : this._items.length;
+ //Actual fetch work goes here.
+ this.originFetch(filterRequest);
+ }
+ }catch(e){
+ if(userRequest.onError){
+ hitchIfCan(userRequest.scope, userRequest.onError)(e, userRequest);
+ }else{
+ throw e;
+ }
+ }
+ return userRequest;
+ },
+ _hasReachedStoreEnd: function(){
+ // summary:
+ // Check whether all the items in the original store have been fetched.
+ // tags:
+ // private
+ return this._storeSize >= 0 && this._nextUnfetchedIdx >= this._storeSize; //Boolean
+ },
+ _applyFilter: function(/* data item */datarow,/* Integer */rowIndex){
+ // summary:
+ // Apply the filter to a row of data
+ // tags:
+ // private
+ // returns:
+ // whether this row survived the filter.
+ var g = this._getter, s = this._store;
+ try{
+ return !!(this._filter.applyRow(datarow, function(item, arg){
+ return g(item, arg, rowIndex, s);
+ }).getValue());
+ }catch(e){
+ console.warn("FilterLayer._applyFilter() error: ", e);
+ return false;
+ }
+ },
+ _doFilter: function(/* Array */items,/* Integer */startIdx,/* object */userRequest){
+ // summary:
+ // Use the filter expression to filter items. Survived items are stored in this._items.
+ // The given items start from "startIdx" in the original store.
+ // tags:
+ // private
+ for(var i = 0, cnt = 0; i < items.length; ++i){
+ if(this._applyFilter(items[i], startIdx + i)){
+ hitchIfCan(userRequest.scope, userRequest.onItem)(items[i], userRequest);
+ cnt += this._addCachedItems(items[i], this._items.length);
+ this._indexMap.push(startIdx + i);
+ }
+ }
+ },
+ _onFetchBegin: function(/* Integer */size,/* request object */req){
+ // summary:
+ // This function is used to replace the user's onFetchBegin in store.fetch
+ // tags:
+ // private
+ this._storeSize = size;
+ },
+ _completeQuery: function(/* request object */userRequest){
+ // summary:
+ // Logically, the user's query is completed here, i.e., all the filtered results are ready.
+ // (or their index mappings are ready)
+ // tags:
+ // private
+ var size = this._items.length;
+ if(this._nextUnfetchedIdx < this._storeSize){
+ //FIXME: There's still some items in the original store that are not fetched & filtered.
+ //So we have to estimate a little bigger size to allow scrolling to these unfetched items.
+ //However, this behavior is ONLY correct in Grid! Any better way to do this?
+ size++;
+ }
+ hitchIfCan(userRequest.scope, userRequest.onBegin)(size,userRequest);
+ this.onFiltered(this._items.length, this._storeSize);
+ hitchIfCan(userRequest.scope, userRequest.onComplete)(this._result, userRequest);
+ },
+ _addCachedItems: function(/* Array */items,/* Integer */filterStartIdx){
+ // summary:
+ // Add data items to the cache. The insert point is at *filterStartIdx*
+ // tags:
+ // private
+ // items: Array
+ // Data items to add.
+ // filterStartIdx: Integer
+ // The start point to insert in the cache.
+ if(!dojo.isArray(items)){
+ items = [items];
+ }
+ for(var k = 0; k < items.length; ++k){
+ this._items[filterStartIdx + k] = items[k];
+ }
+ return items.length;
+ },
+ onRowMappingChange: function(mapping){
+ //This function runs in FilterLayer scope!
+ if(this._filter){
+ var m = dojo.clone(mapping),
+ alreadyUpdated = {};
+ for(var r in m){
+ r = parseInt(r, 10);
+ mapping[this._indexMap[r]] = this._indexMap[m[r]];
+ if(!alreadyUpdated[this._indexMap[r]]){
+ alreadyUpdated[this._indexMap[r]] = true;
+ }
+ if(!alreadyUpdated[r]){
+ alreadyUpdated[r] = true;
+ delete mapping[r];
+ }
+ }
+ }
+ }
+ });
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js
new file mode 100644
index 0000000..c16ec58
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js
@@ -0,0 +1,150 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterStatusTip"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterStatusTip"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter.FilterStatusTip");
+
+dojo.requireLocalization("dojox.grid.enhanced", "Filter", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ru,sl,sv,th,tr,zh,zh-tw");
+dojo.require("dijit.TooltipDialog");
+dojo.require("dijit._base.popup");
+dojo.require("dijit.form.Button");
+dojo.require("dojo.string");
+dojo.require("dojo.date.locale");
+
+(function(){
+var gridCssCls = "", headerCssCls = "", cellCssCls = "", rowCssCls = "",
+ oddRowCssCls = "dojoxGridFStatusTipOddRow",
+ handleHolderCssCls = "dojoxGridFStatusTipHandle",
+ conditionCssCls = "dojoxGridFStatusTipCondition",
+ _removeRuleIconCls = "dojoxGridFStatusTipDelRuleBtnIcon",
+ _statusFooter = "</tbody></table>";
+
+ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterStatusTip", null, {
+ // summary:
+ // Create the status tip UI.
+ constructor: function(args){
+ var plugin = this.plugin = args.plugin;
+ this._statusHeader = ["<table border='0' cellspacing='0' class='",
+ gridCssCls, "'><thead><tr class='",
+ headerCssCls, "'><th class='",
+ cellCssCls, "'><div>", plugin.nls["statusTipHeaderColumn"], "</div></th><th class='",
+ cellCssCls, " lastColumn'><div>", plugin.nls["statusTipHeaderCondition"], "</div></th></tr></thead><tbody>"
+ ].join('');
+ this._removedCriterias = [];
+ this._rules = [];
+ this.statusPane = new dojox.grid.enhanced.plugins.filter.FilterStatusPane();
+ this._dlg = new dijit.TooltipDialog({
+ "class": "dojoxGridFStatusTipDialog",
+ content: this.statusPane,
+ autofocus: false,
+ onMouseLeave: dojo.hitch(this,function(){
+ this.closeDialog();
+ })
+ });
+ this._dlg.connect(this._dlg.domNode,"click", dojo.hitch(this, this._modifyFilter));
+ },
+ destroy: function(){
+ this._dlg.destroyRecursive();
+ },
+ //-----------------Public Functions------------------------
+ showDialog: function(/* int */pos_x,/* int */pos_y, columnIdx){
+ this._pos = {x:pos_x,y:pos_y};
+ dijit.popup.close(this._dlg);
+ this._removedCriterias = [];
+ this._rules = [];
+ this._updateStatus(columnIdx);
+ dijit.popup.open({
+ popup: this._dlg,
+ parent: this.plugin.filterBar,
+ x:pos_x - 12,
+ y:pos_y - 3
+ });
+ },
+ closeDialog: function(){
+ dijit.popup.close(this._dlg);
+ if(this._removedCriterias.length){
+ this.plugin.filterDefDialog.removeCriteriaBoxes(this._removedCriterias);
+ this._removedCriterias = [];
+ this.plugin.filterDefDialog.onFilter();
+ }
+ },
+ //-----------------Private Functions---------------------------
+ _updateStatus: function(columnIdx){
+ var res, p = this.plugin,
+ nls = p.nls,
+ sp = this.statusPane,
+ fdg = p.filterDefDialog;
+ if(fdg.getCriteria() === 0){
+ sp.statusTitle.innerHTML = nls["statusTipTitleNoFilter"];
+ sp.statusRel.innerHTML = sp.statusRelPre.innerHTML = sp.statusRelPost.innerHTML = "";
+ var cell = p.grid.layout.cells[columnIdx];
+ var colName = cell ? "'" + (cell.name || cell.field) + "'" : nls["anycolumn"];
+ res = dojo.string.substitute(nls["statusTipMsg"], [colName]);
+ }else{
+ sp.statusTitle.innerHTML = nls["statusTipTitleHasFilter"];
+ sp.statusRelPre.innerHTML = nls["statusTipRelPre"] + "&nbsp;";
+ sp.statusRelPost.innerHTML = "&nbsp;" + nls["statusTipRelPost"];
+ sp.statusRel.innerHTML = fdg._relOpCls == "logicall" ? nls["all"] : nls["any"];
+
+ this._rules = [];
+ var i = 0, c = fdg.getCriteria(i++);
+ while(c){
+ c.index = i - 1;
+ this._rules.push(c);
+ c = fdg.getCriteria(i++);
+ }
+ res = this._createStatusDetail();
+ }
+ sp.statusDetailNode.innerHTML = res;
+ this._addButtonForRules();
+ },
+ _createStatusDetail: function(){
+ return this._statusHeader + dojo.map(this._rules, function(rule, i){
+ return this._getCriteriaStr(rule, i);
+ }, this).join('') + _statusFooter;
+ },
+ _addButtonForRules: function(){
+ if(this._rules.length > 1){
+ dojo.query("." + handleHolderCssCls, this.statusPane.statusDetailNode).forEach(dojo.hitch(this, function(nd, idx){
+ (new dijit.form.Button({
+ label: this.plugin.nls["removeRuleButton"],
+ showLabel: false,
+ iconClass: _removeRuleIconCls,
+ onClick: dojo.hitch(this, function(e){
+ e.stopPropagation();
+ this._removedCriterias.push(this._rules[idx].index);
+ this._rules.splice(idx,1);
+ this.statusPane.statusDetailNode.innerHTML = this._createStatusDetail();
+ this._addButtonForRules();
+ })
+ })).placeAt(nd, "last");
+ }));
+ }
+ },
+ _getCriteriaStr: function(/* object */c, /* int */rowIdx){
+ var res = ["<tr class='", rowCssCls,
+ " ", (rowIdx % 2 ? oddRowCssCls : ""),
+ "'><td class='", cellCssCls, "'>", c.colTxt,
+ "</td><td class='", cellCssCls,
+ "'><div class='", handleHolderCssCls, "'><span class='", conditionCssCls,
+ "'>", c.condTxt, "&nbsp;</span>",
+ c.formattedVal, "</div></td></tr>"];
+ return res.join('');
+ },
+ _modifyFilter: function(){
+ this.closeDialog();
+ var p = this.plugin;
+ p.filterDefDialog.showDialog(p.filterBar.getColumnIdx(this._pos.x));
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterStatusPane", [dijit._Widget, dijit._Templated], {
+ templateString: dojo.cache("dojox.grid", "enhanced/templates/FilterStatusPane.html", "<div class=\"dojoxGridFStatusTip\">\r\n\t<div class=\"dojoxGridFStatusTipHead\">\r\n\t\t<span class=\"dojoxGridFStatusTipTitle\" dojoAttachPoint=\"statusTitle\"></span\r\n\t\t><span class=\"dojoxGridFStatusTipRelPre\" dojoAttachPoint=\"statusRelPre\"></span\r\n\t\t><span class=\"dojoxGridFStatusTipRel\" dojoAttachPoint=\"statusRel\"></span\r\n\t\t><span class=\"dojoxGridFStatusTipRelPost\" dojoAttachPoint=\"statusRelPost\"></span>\r\n\t</div>\r\n\t<div class=\"dojoxGridFStatusTipDetail\" dojoAttachPoint=\"statusDetailNode\"></div>\r\n</div>\r\n")
+ });
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterStatusTip.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterStatusTip.xd.js
new file mode 100644
index 0000000..715e51c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/FilterStatusTip.xd.js
@@ -0,0 +1,160 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.filter.FilterStatusTip"],
+["requireLocalization", "dojox.grid.enhanced", "Filter", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ru,sl,sv,th,tr,zh,zh-tw", "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ru,sl,sv,th,tr,zh,zh-tw"],
+["require", "dijit.TooltipDialog"],
+["require", "dijit._base.popup"],
+["require", "dijit.form.Button"],
+["require", "dojo.string"],
+["require", "dojo.date.locale"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterStatusTip"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter.FilterStatusTip"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter.FilterStatusTip");
+
+;
+dojo.require("dijit.TooltipDialog");
+dojo.require("dijit._base.popup");
+dojo.require("dijit.form.Button");
+dojo.require("dojo.string");
+dojo.require("dojo.date.locale");
+
+(function(){
+var gridCssCls = "", headerCssCls = "", cellCssCls = "", rowCssCls = "",
+ oddRowCssCls = "dojoxGridFStatusTipOddRow",
+ handleHolderCssCls = "dojoxGridFStatusTipHandle",
+ conditionCssCls = "dojoxGridFStatusTipCondition",
+ _removeRuleIconCls = "dojoxGridFStatusTipDelRuleBtnIcon",
+ _statusFooter = "</tbody></table>";
+
+ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterStatusTip", null, {
+ // summary:
+ // Create the status tip UI.
+ constructor: function(args){
+ var plugin = this.plugin = args.plugin;
+ this._statusHeader = ["<table border='0' cellspacing='0' class='",
+ gridCssCls, "'><thead><tr class='",
+ headerCssCls, "'><th class='",
+ cellCssCls, "'><div>", plugin.nls["statusTipHeaderColumn"], "</div></th><th class='",
+ cellCssCls, " lastColumn'><div>", plugin.nls["statusTipHeaderCondition"], "</div></th></tr></thead><tbody>"
+ ].join('');
+ this._removedCriterias = [];
+ this._rules = [];
+ this.statusPane = new dojox.grid.enhanced.plugins.filter.FilterStatusPane();
+ this._dlg = new dijit.TooltipDialog({
+ "class": "dojoxGridFStatusTipDialog",
+ content: this.statusPane,
+ autofocus: false,
+ onMouseLeave: dojo.hitch(this,function(){
+ this.closeDialog();
+ })
+ });
+ this._dlg.connect(this._dlg.domNode,"click", dojo.hitch(this, this._modifyFilter));
+ },
+ destroy: function(){
+ this._dlg.destroyRecursive();
+ },
+ //-----------------Public Functions------------------------
+ showDialog: function(/* int */pos_x,/* int */pos_y, columnIdx){
+ this._pos = {x:pos_x,y:pos_y};
+ dijit.popup.close(this._dlg);
+ this._removedCriterias = [];
+ this._rules = [];
+ this._updateStatus(columnIdx);
+ dijit.popup.open({
+ popup: this._dlg,
+ parent: this.plugin.filterBar,
+ x:pos_x - 12,
+ y:pos_y - 3
+ });
+ },
+ closeDialog: function(){
+ dijit.popup.close(this._dlg);
+ if(this._removedCriterias.length){
+ this.plugin.filterDefDialog.removeCriteriaBoxes(this._removedCriterias);
+ this._removedCriterias = [];
+ this.plugin.filterDefDialog.onFilter();
+ }
+ },
+ //-----------------Private Functions---------------------------
+ _updateStatus: function(columnIdx){
+ var res, p = this.plugin,
+ nls = p.nls,
+ sp = this.statusPane,
+ fdg = p.filterDefDialog;
+ if(fdg.getCriteria() === 0){
+ sp.statusTitle.innerHTML = nls["statusTipTitleNoFilter"];
+ sp.statusRel.innerHTML = sp.statusRelPre.innerHTML = sp.statusRelPost.innerHTML = "";
+ var cell = p.grid.layout.cells[columnIdx];
+ var colName = cell ? "'" + (cell.name || cell.field) + "'" : nls["anycolumn"];
+ res = dojo.string.substitute(nls["statusTipMsg"], [colName]);
+ }else{
+ sp.statusTitle.innerHTML = nls["statusTipTitleHasFilter"];
+ sp.statusRelPre.innerHTML = nls["statusTipRelPre"] + "&nbsp;";
+ sp.statusRelPost.innerHTML = "&nbsp;" + nls["statusTipRelPost"];
+ sp.statusRel.innerHTML = fdg._relOpCls == "logicall" ? nls["all"] : nls["any"];
+
+ this._rules = [];
+ var i = 0, c = fdg.getCriteria(i++);
+ while(c){
+ c.index = i - 1;
+ this._rules.push(c);
+ c = fdg.getCriteria(i++);
+ }
+ res = this._createStatusDetail();
+ }
+ sp.statusDetailNode.innerHTML = res;
+ this._addButtonForRules();
+ },
+ _createStatusDetail: function(){
+ return this._statusHeader + dojo.map(this._rules, function(rule, i){
+ return this._getCriteriaStr(rule, i);
+ }, this).join('') + _statusFooter;
+ },
+ _addButtonForRules: function(){
+ if(this._rules.length > 1){
+ dojo.query("." + handleHolderCssCls, this.statusPane.statusDetailNode).forEach(dojo.hitch(this, function(nd, idx){
+ (new dijit.form.Button({
+ label: this.plugin.nls["removeRuleButton"],
+ showLabel: false,
+ iconClass: _removeRuleIconCls,
+ onClick: dojo.hitch(this, function(e){
+ e.stopPropagation();
+ this._removedCriterias.push(this._rules[idx].index);
+ this._rules.splice(idx,1);
+ this.statusPane.statusDetailNode.innerHTML = this._createStatusDetail();
+ this._addButtonForRules();
+ })
+ })).placeAt(nd, "last");
+ }));
+ }
+ },
+ _getCriteriaStr: function(/* object */c, /* int */rowIdx){
+ var res = ["<tr class='", rowCssCls,
+ " ", (rowIdx % 2 ? oddRowCssCls : ""),
+ "'><td class='", cellCssCls, "'>", c.colTxt,
+ "</td><td class='", cellCssCls,
+ "'><div class='", handleHolderCssCls, "'><span class='", conditionCssCls,
+ "'>", c.condTxt, "&nbsp;</span>",
+ c.formattedVal, "</div></td></tr>"];
+ return res.join('');
+ },
+ _modifyFilter: function(){
+ this.closeDialog();
+ var p = this.plugin;
+ p.filterDefDialog.showDialog(p.filterBar.getColumnIdx(this._pos.x));
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterStatusPane", [dijit._Widget, dijit._Templated], {
+ templateString: dojo.cache("dojox.grid", "enhanced/templates/FilterStatusPane.html", "<div class=\"dojoxGridFStatusTip\">\r\n\t<div class=\"dojoxGridFStatusTipHead\">\r\n\t\t<span class=\"dojoxGridFStatusTipTitle\" dojoAttachPoint=\"statusTitle\"></span\r\n\t\t><span class=\"dojoxGridFStatusTipRelPre\" dojoAttachPoint=\"statusRelPre\"></span\r\n\t\t><span class=\"dojoxGridFStatusTipRel\" dojoAttachPoint=\"statusRel\"></span\r\n\t\t><span class=\"dojoxGridFStatusTipRelPost\" dojoAttachPoint=\"statusRelPost\"></span>\r\n\t</div>\r\n\t<div class=\"dojoxGridFStatusTipDetail\" dojoAttachPoint=\"statusDetailNode\"></div>\r\n</div>\r\n")
+ });
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js
new file mode 100644
index 0000000..cf1c4e3
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js
@@ -0,0 +1,226 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter._ConditionExpr"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter._ConditionExpr"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter._ConditionExpr");
+
+(function(){
+ var fns = dojox.grid.enhanced.plugins.filter;
+
+dojo.declare("dojox.grid.enhanced.plugins.filter._ConditionExpr",null,{
+ // summary:
+ // The most abstract class for all condition expressions.
+ // A condition expression can be applied on a data row (e.g. an item in a store)
+ // and generate a result condition expression.
+ // tags:
+ // abstract
+
+ _name: "expr",
+ applyRow: function(/* data item */datarow,/* function(row,colArg) */getter){
+ // summary:
+ // *Unimplemented Interface*
+ // Apply this condition expression on the given datarow, return a result expression.
+ // taqs:
+ // public extension
+ // datarow: object
+ // A data item of a store.
+ // getter: function(datarow, colArg)
+ // A user defined function that extract cell data from *datarow*.
+ // *colArg* is an argument that provides a kind of column information.
+ // It is defined by user in the constructor of a _DataExpr object.
+ // returns:
+ // MUST return a _ConditionExpr object
+ throw new Error("_ConditionExpr.applyRow: unimplemented interface");
+ },
+ toObject: function(){
+ // summary:
+ // Convert this data expression to a simple object. Mainly used for serialization.
+ // tags:
+ // public extension
+ // returns:
+ // An object for serialization.
+ return {}; //Object
+ },
+ getName: function(){
+ // summary:
+ // Get the name of this kind of expression.
+ // tags:
+ // public extension
+ // returns:
+ // the name of this kind of expression
+ return this._name; //String
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter._DataExpr", fns._ConditionExpr, {
+ // summary:
+ // The most abstract class for all data expressions.
+ // A _DataExpr is a condition expression for a single data value.
+ // If the data value to be represent is a pure value (literal value, like string/number/Date/...)
+ // this _DataExpr is nothing more than a simple wrapper.
+ // If the data value to be represent is in a store, then _DataExpr is responsible to extract it
+ // from the store when this condition is applied to a data row.
+ // private fields:
+ // _value: anything
+ // _colArg: anything
+ _name: "data",
+ constructor: function(/* anything */dataValue,/* bool */isColumn, /* object */convertArgs){
+ // summary:
+ // If a _DataExpr is constructed with only one argument, this argument is regarded as a pure value.
+ // If the second argument is exactly a boolean true (no implict type transformation,
+ // so as to allow derived classes accept more arguments while retain *isColumn* to be optional),
+ // then this _DataExpr represents a column, and it's applyRow method is not a no-op.
+ // dataValue: anything
+ // If *isColumn* is a boolean true, then it should be a kind of column information, like field name
+ // or column index. Otherwise, it is regarded as a pure value, and the getValue method will simply
+ // return it.
+ // isColumn: boolean?
+ // Optional. To specify whether this _DataExpr represents a column or a pure value.
+ this._convertArgs = convertArgs || {};
+ if(dojo.isFunction(this._convertArgs.convert)){
+ this._convertData = dojo.hitch(this._convertArgs.scope, this._convertArgs.convert);
+ }
+ if(isColumn){
+ this._colArg = dataValue;
+ }else{
+ this._value = this._convertData(dataValue, this._convertArgs);
+ }
+ },
+ getValue: function(){
+ // summary:
+ // If this is a pure value wrapper, simply return the value.
+ // Otherwise (it's a column), return is undefined.
+ // tags:
+ // public
+ // returns:
+ // the value of this data expression.
+ return this._value; //String
+ },
+ applyRow: function(/* data item */datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Implement _ConditionExpr.applyRow.
+ // If this is a pure value, simply return self.
+ // Otherwise, extract the cell data from datarow using the given getter function,
+ // and then convert this cell data to a _DataExpr and return the expression.
+ return typeof this._colArg == "undefined" ? this : //_ConditionExpr
+ new (dojo.getObject(this.declaredClass))(
+ this._convertData(getter(datarow, this._colArg), this._convertArgs)
+ );
+ },
+ _convertData: function(/* anything */dataValue){
+ // summary:
+ //
+ // tags:
+ // protected extension
+ // dataValue: anything
+ // This argument should come from a store.
+ // returns:
+ return dataValue;
+ },
+ toObject: function(){
+ // summary:
+ // Overrided from _ConditionExpr.toObject
+ return { //String
+ op: this.getName(),
+ data: this._colArg === undefined ? this._value : this._colArg,
+ isCol: this._colArg !== undefined
+ };
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter._OperatorExpr", fns._ConditionExpr, {
+ // summary:
+ // The most abstract class for all operator expressions.
+ // An operator expression is a _ConditionExpr that represents an operation.
+ _name: "operator",
+ constructor: function(/* Array | operand1,operand2,... */){
+ // summary:
+ // The arguments are operands (or an array of operands, if the first argument
+ // is an Array) of this operator, ordering from left to right.
+ // Every operand should be a _ConditionExpr.
+ if(dojo.isArray(arguments[0])){
+ this._operands = arguments[0];
+ }else{
+ this._operands = [];
+ for(var i = 0; i < arguments.length; ++i){
+ this._operands.push(arguments[i]);
+ }
+ }
+ },
+ toObject: function(){
+ // summary:
+ // Overrided from _ConditionExpr.toObject
+ return { //Object
+ op: this.getName(),
+ data: dojo.map(this._operands,function(operand){
+ return operand.toObject();
+ })
+ };
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter._UniOpExpr", fns._OperatorExpr, {
+ // summary:
+ // The most abstract class for all uni-operator expressions.
+ // A uni-operator expression is an _OperatorExpr that only allow one operand.
+ _name: "uniOperator",
+ applyRow: function(/* data item */datarow,/* function(row,colArg) */getter){
+ // summary:
+ // Implement _ConditionExpr.applyRow.
+ // Apply the restriction of "only one operand" and confirm the operand is a valid _ConditionExpr.
+ // Then do the calculation of this operator.
+ if(!(this._operands[0] instanceof fns._ConditionExpr)){
+ throw new Error("_UniOpExpr: operand is not expression.");
+ }
+ return this._calculate(this._operands[0],datarow,getter); //_ConditionExpr
+ },
+ _calculate: function(/* _ConditionExpr */operand,/* data item*/datarow,/* function(row,colArg) */getter){
+ // summary:
+ // *Unimplemented Interface*
+ // Do the actrual work of applyRow here.
+ // tags:
+ // protected extension
+ // operand: _ConditionExpr
+ // datarow: object
+ // getter: function(row,colArg)
+ // returns:
+ // MUST return a _ConditionExpr object.
+ throw new Error("_UniOpExpr._calculate: unimplemented interface");
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter._BiOpExpr", fns._OperatorExpr, {
+ // summary:
+ // The most abstract class for all bi-operator expressions.
+ // A bi-operator expression is an _OperatorExpr that allow and only allow two operands.
+ _name: "biOperator",
+ applyRow: function(/* data item */datarow,/* function(row,colArg) */getter){
+ // summary:
+ // Implement _ConditionExpr.applyRow.
+ // Apply the restriction of "two operands" and confirm operands are valid _ConditionExpr's.
+ if(!(this._operands[0] instanceof fns._ConditionExpr)){
+ throw new Error("_BiOpExpr: left operand is not expression.");
+ }else if(!(this._operands[1] instanceof fns._ConditionExpr)){
+ throw new Error("_BiOpExpr: right operand is not expression.");
+ }
+ return this._calculate(this._operands[0],this._operands[1],datarow,getter);
+ },
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,/* data item*/datarow,/* function(row,colArg) */getter){
+ // summary:
+ // *Unimplemented Interface*
+ // Do the actrual work of applyRow here.
+ // tags:
+ // protected extension
+ // left_operand: _ConditionExpr
+ // right_operand: _ConditionExpr
+ // datarow: object
+ // getter: function(row,colArg)
+ // returns:
+ // MUST return a _ConditionExpr object.
+ throw new Error("_BiOpExpr._calculate: unimplemented interface");
+ }
+});
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_ConditionExpr.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_ConditionExpr.xd.js
new file mode 100644
index 0000000..552d8b8
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_ConditionExpr.xd.js
@@ -0,0 +1,230 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.filter._ConditionExpr"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter._ConditionExpr"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter._ConditionExpr"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter._ConditionExpr");
+
+(function(){
+ var fns = dojox.grid.enhanced.plugins.filter;
+
+dojo.declare("dojox.grid.enhanced.plugins.filter._ConditionExpr",null,{
+ // summary:
+ // The most abstract class for all condition expressions.
+ // A condition expression can be applied on a data row (e.g. an item in a store)
+ // and generate a result condition expression.
+ // tags:
+ // abstract
+
+ _name: "expr",
+ applyRow: function(/* data item */datarow,/* function(row,colArg) */getter){
+ // summary:
+ // *Unimplemented Interface*
+ // Apply this condition expression on the given datarow, return a result expression.
+ // taqs:
+ // public extension
+ // datarow: object
+ // A data item of a store.
+ // getter: function(datarow, colArg)
+ // A user defined function that extract cell data from *datarow*.
+ // *colArg* is an argument that provides a kind of column information.
+ // It is defined by user in the constructor of a _DataExpr object.
+ // returns:
+ // MUST return a _ConditionExpr object
+ throw new Error("_ConditionExpr.applyRow: unimplemented interface");
+ },
+ toObject: function(){
+ // summary:
+ // Convert this data expression to a simple object. Mainly used for serialization.
+ // tags:
+ // public extension
+ // returns:
+ // An object for serialization.
+ return {}; //Object
+ },
+ getName: function(){
+ // summary:
+ // Get the name of this kind of expression.
+ // tags:
+ // public extension
+ // returns:
+ // the name of this kind of expression
+ return this._name; //String
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter._DataExpr", fns._ConditionExpr, {
+ // summary:
+ // The most abstract class for all data expressions.
+ // A _DataExpr is a condition expression for a single data value.
+ // If the data value to be represent is a pure value (literal value, like string/number/Date/...)
+ // this _DataExpr is nothing more than a simple wrapper.
+ // If the data value to be represent is in a store, then _DataExpr is responsible to extract it
+ // from the store when this condition is applied to a data row.
+ // private fields:
+ // _value: anything
+ // _colArg: anything
+ _name: "data",
+ constructor: function(/* anything */dataValue,/* bool */isColumn, /* object */convertArgs){
+ // summary:
+ // If a _DataExpr is constructed with only one argument, this argument is regarded as a pure value.
+ // If the second argument is exactly a boolean true (no implict type transformation,
+ // so as to allow derived classes accept more arguments while retain *isColumn* to be optional),
+ // then this _DataExpr represents a column, and it's applyRow method is not a no-op.
+ // dataValue: anything
+ // If *isColumn* is a boolean true, then it should be a kind of column information, like field name
+ // or column index. Otherwise, it is regarded as a pure value, and the getValue method will simply
+ // return it.
+ // isColumn: boolean?
+ // Optional. To specify whether this _DataExpr represents a column or a pure value.
+ this._convertArgs = convertArgs || {};
+ if(dojo.isFunction(this._convertArgs.convert)){
+ this._convertData = dojo.hitch(this._convertArgs.scope, this._convertArgs.convert);
+ }
+ if(isColumn){
+ this._colArg = dataValue;
+ }else{
+ this._value = this._convertData(dataValue, this._convertArgs);
+ }
+ },
+ getValue: function(){
+ // summary:
+ // If this is a pure value wrapper, simply return the value.
+ // Otherwise (it's a column), return is undefined.
+ // tags:
+ // public
+ // returns:
+ // the value of this data expression.
+ return this._value; //String
+ },
+ applyRow: function(/* data item */datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Implement _ConditionExpr.applyRow.
+ // If this is a pure value, simply return self.
+ // Otherwise, extract the cell data from datarow using the given getter function,
+ // and then convert this cell data to a _DataExpr and return the expression.
+ return typeof this._colArg == "undefined" ? this : //_ConditionExpr
+ new (dojo.getObject(this.declaredClass))(
+ this._convertData(getter(datarow, this._colArg), this._convertArgs)
+ );
+ },
+ _convertData: function(/* anything */dataValue){
+ // summary:
+ //
+ // tags:
+ // protected extension
+ // dataValue: anything
+ // This argument should come from a store.
+ // returns:
+ return dataValue;
+ },
+ toObject: function(){
+ // summary:
+ // Overrided from _ConditionExpr.toObject
+ return { //String
+ op: this.getName(),
+ data: this._colArg === undefined ? this._value : this._colArg,
+ isCol: this._colArg !== undefined
+ };
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter._OperatorExpr", fns._ConditionExpr, {
+ // summary:
+ // The most abstract class for all operator expressions.
+ // An operator expression is a _ConditionExpr that represents an operation.
+ _name: "operator",
+ constructor: function(/* Array | operand1,operand2,... */){
+ // summary:
+ // The arguments are operands (or an array of operands, if the first argument
+ // is an Array) of this operator, ordering from left to right.
+ // Every operand should be a _ConditionExpr.
+ if(dojo.isArray(arguments[0])){
+ this._operands = arguments[0];
+ }else{
+ this._operands = [];
+ for(var i = 0; i < arguments.length; ++i){
+ this._operands.push(arguments[i]);
+ }
+ }
+ },
+ toObject: function(){
+ // summary:
+ // Overrided from _ConditionExpr.toObject
+ return { //Object
+ op: this.getName(),
+ data: dojo.map(this._operands,function(operand){
+ return operand.toObject();
+ })
+ };
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter._UniOpExpr", fns._OperatorExpr, {
+ // summary:
+ // The most abstract class for all uni-operator expressions.
+ // A uni-operator expression is an _OperatorExpr that only allow one operand.
+ _name: "uniOperator",
+ applyRow: function(/* data item */datarow,/* function(row,colArg) */getter){
+ // summary:
+ // Implement _ConditionExpr.applyRow.
+ // Apply the restriction of "only one operand" and confirm the operand is a valid _ConditionExpr.
+ // Then do the calculation of this operator.
+ if(!(this._operands[0] instanceof fns._ConditionExpr)){
+ throw new Error("_UniOpExpr: operand is not expression.");
+ }
+ return this._calculate(this._operands[0],datarow,getter); //_ConditionExpr
+ },
+ _calculate: function(/* _ConditionExpr */operand,/* data item*/datarow,/* function(row,colArg) */getter){
+ // summary:
+ // *Unimplemented Interface*
+ // Do the actrual work of applyRow here.
+ // tags:
+ // protected extension
+ // operand: _ConditionExpr
+ // datarow: object
+ // getter: function(row,colArg)
+ // returns:
+ // MUST return a _ConditionExpr object.
+ throw new Error("_UniOpExpr._calculate: unimplemented interface");
+ }
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter._BiOpExpr", fns._OperatorExpr, {
+ // summary:
+ // The most abstract class for all bi-operator expressions.
+ // A bi-operator expression is an _OperatorExpr that allow and only allow two operands.
+ _name: "biOperator",
+ applyRow: function(/* data item */datarow,/* function(row,colArg) */getter){
+ // summary:
+ // Implement _ConditionExpr.applyRow.
+ // Apply the restriction of "two operands" and confirm operands are valid _ConditionExpr's.
+ if(!(this._operands[0] instanceof fns._ConditionExpr)){
+ throw new Error("_BiOpExpr: left operand is not expression.");
+ }else if(!(this._operands[1] instanceof fns._ConditionExpr)){
+ throw new Error("_BiOpExpr: right operand is not expression.");
+ }
+ return this._calculate(this._operands[0],this._operands[1],datarow,getter);
+ },
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,/* data item*/datarow,/* function(row,colArg) */getter){
+ // summary:
+ // *Unimplemented Interface*
+ // Do the actrual work of applyRow here.
+ // tags:
+ // protected extension
+ // left_operand: _ConditionExpr
+ // right_operand: _ConditionExpr
+ // datarow: object
+ // getter: function(row,colArg)
+ // returns:
+ // MUST return a _ConditionExpr object.
+ throw new Error("_BiOpExpr._calculate: unimplemented interface");
+ }
+});
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_DataExprs.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_DataExprs.js
new file mode 100644
index 0000000..dc1ff36
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_DataExprs.js
@@ -0,0 +1,89 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter._DataExprs"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter._DataExprs"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter._DataExprs");
+
+dojo.require("dojox.grid.enhanced.plugins.filter._ConditionExpr");
+dojo.require("dojo.date.locale");
+
+(function(){
+ var fns = dojox.grid.enhanced.plugins.filter;
+
+ dojo.declare("dojox.grid.enhanced.plugins.filter.BooleanExpr", fns._DataExpr, {
+ // summary:
+ // A condition expression wrapper for boolean values
+ _name: "bool",
+ _convertData: function(/* anything */dataValue){
+ // summary:
+ // override from _DataExpr
+ return !!dataValue; //Boolean
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.StringExpr", fns._DataExpr, {
+ // summary:
+ // A condition expression wrapper for string values
+ _name: "string",
+ _convertData: function(/* anything */dataValue){
+ // summary:
+ // override from _DataExpr
+ return String(dataValue); //String
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.NumberExpr", fns._DataExpr, {
+ // summary:
+ // A condition expression wrapper for number values
+ _name: "number",
+ _convertDataToExpr: function(/* anything */dataValue){
+ // summary:
+ // override from _DataExpr
+ return parseFloat(dataValue); //Number
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.DateExpr", fns._DataExpr, {
+ // summary:
+ // A condition expression wrapper for date values
+ _name: "date",
+ _convertData: function(/* anything */dataValue){
+ // summary:
+ // override from _DataExpr
+ if(dataValue instanceof Date){
+ return dataValue;
+ }else if(typeof dataValue == "number"){
+ return new Date(dataValue);
+ }else{
+ var res = dojo.date.locale.parse(String(dataValue), dojo.mixin({selector: this._name}, this._convertArgs));
+ if(!res){
+ throw new Error("Datetime parse failed: " + dataValue);
+ }
+ return res;
+ }
+ },
+ toObject: function(){
+ // summary:
+ // Overrided from _DataExpr.toObject
+ if(this._value instanceof Date){
+ var tmp = this._value;
+ this._value = this._value.valueOf();
+ var res = this.inherited(arguments);
+ this._value = tmp;
+ return res;
+ }else{
+ return this.inherited(arguments);
+ }
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.TimeExpr", fns.DateExpr, {
+ // summary:
+ // A condition expression wrapper for time values
+ _name: "time"
+ });
+})();
+
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_DataExprs.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_DataExprs.xd.js
new file mode 100644
index 0000000..227cc90
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_DataExprs.xd.js
@@ -0,0 +1,95 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.filter._DataExprs"],
+["require", "dojox.grid.enhanced.plugins.filter._ConditionExpr"],
+["require", "dojo.date.locale"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter._DataExprs"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter._DataExprs"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter._DataExprs");
+
+dojo.require("dojox.grid.enhanced.plugins.filter._ConditionExpr");
+dojo.require("dojo.date.locale");
+
+(function(){
+ var fns = dojox.grid.enhanced.plugins.filter;
+
+ dojo.declare("dojox.grid.enhanced.plugins.filter.BooleanExpr", fns._DataExpr, {
+ // summary:
+ // A condition expression wrapper for boolean values
+ _name: "bool",
+ _convertData: function(/* anything */dataValue){
+ // summary:
+ // override from _DataExpr
+ return !!dataValue; //Boolean
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.StringExpr", fns._DataExpr, {
+ // summary:
+ // A condition expression wrapper for string values
+ _name: "string",
+ _convertData: function(/* anything */dataValue){
+ // summary:
+ // override from _DataExpr
+ return String(dataValue); //String
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.NumberExpr", fns._DataExpr, {
+ // summary:
+ // A condition expression wrapper for number values
+ _name: "number",
+ _convertDataToExpr: function(/* anything */dataValue){
+ // summary:
+ // override from _DataExpr
+ return parseFloat(dataValue); //Number
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.DateExpr", fns._DataExpr, {
+ // summary:
+ // A condition expression wrapper for date values
+ _name: "date",
+ _convertData: function(/* anything */dataValue){
+ // summary:
+ // override from _DataExpr
+ if(dataValue instanceof Date){
+ return dataValue;
+ }else if(typeof dataValue == "number"){
+ return new Date(dataValue);
+ }else{
+ var res = dojo.date.locale.parse(String(dataValue), dojo.mixin({selector: this._name}, this._convertArgs));
+ if(!res){
+ throw new Error("Datetime parse failed: " + dataValue);
+ }
+ return res;
+ }
+ },
+ toObject: function(){
+ // summary:
+ // Overrided from _DataExpr.toObject
+ if(this._value instanceof Date){
+ var tmp = this._value;
+ this._value = this._value.valueOf();
+ var res = this.inherited(arguments);
+ this._value = tmp;
+ return res;
+ }else{
+ return this.inherited(arguments);
+ }
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.TimeExpr", fns.DateExpr, {
+ // summary:
+ // A condition expression wrapper for time values
+ _name: "time"
+ });
+})();
+
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_FilterExpr.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_FilterExpr.js
new file mode 100644
index 0000000..397913c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_FilterExpr.js
@@ -0,0 +1,239 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter._FilterExpr"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter._FilterExpr"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter._FilterExpr");
+//This is the main file that should be 'required' if filter expression facility is necessary.
+
+dojo.require("dojox.grid.enhanced.plugins.filter._DataExprs");
+dojo.require("dojo.date");
+
+(function(){
+ var fns = dojox.grid.enhanced.plugins.filter;
+ /* Logic Operations */
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LogicAND", fns._BiOpExpr, {
+ // summary:
+ // A logic AND condition expression.
+ _name: "and",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = left_operand.applyRow(datarow, getter).getValue() &&
+ right_operand.applyRow(datarow, getter).getValue();
+ return new fns.BooleanExpr(res); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LogicOR", fns._BiOpExpr, {
+ // summary:
+ // A logic OR condition expression.
+ _name: "or",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = left_operand.applyRow(datarow, getter).getValue() ||
+ right_operand.applyRow(datarow, getter).getValue();
+ return new fns.BooleanExpr(res); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LogicXOR", fns._BiOpExpr, {
+ // summary:
+ // A logic XOR condition expression.
+ _name: "xor",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var left_res = left_operand.applyRow(datarow, getter).getValue();
+ var right_res = right_operand.applyRow(datarow, getter).getValue();
+ return new fns.BooleanExpr((!!left_res) != (!!right_res)); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LogicNOT", fns._UniOpExpr, {
+ // summary:
+ // A logic NOT condition expression.
+ _name: "not",
+ _calculate: function(/* _ConditionExpr */operand,/* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _UniOpExpr
+ return new fns.BooleanExpr(!operand.applyRow(datarow, getter).getValue()); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LogicALL", fns._OperatorExpr, {
+ // summary:
+ // A logic ALL condition expression, equals a sequence of logic ANDs
+ _name: "all",
+ applyRow: function(/* data item */datarow,/* function(row,colIdx) */ getter){
+ // summary:
+ // Override from _ConditionExpr
+ for(var i = 0, res = true; res && (this._operands[i] instanceof fns._ConditionExpr); ++i){
+ res = this._operands[i].applyRow(datarow,getter).getValue();
+ }
+ return new fns.BooleanExpr(res); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LogicANY", fns._OperatorExpr, {
+ // summary:
+ // A logic ANY condition expression, equals a sequence of logic ORs
+ _name: "any",
+ applyRow: function(/* data item */datarow,/* function(row,colIdx) */ getter){
+ for(var i = 0,res = false; !res && (this._operands[i] instanceof fns._ConditionExpr); ++i){
+ res = this._operands[i].applyRow(datarow,getter).getValue();
+ }
+ return new fns.BooleanExpr(res); //_ConditionExpr
+ }
+ });
+
+ /* Comparison Operations */
+ function compareFunc(left,right,row,getter){
+ left = left.applyRow(row, getter);
+ right = right.applyRow(row, getter);
+ var left_res = left.getValue();
+ var right_res = right.getValue();
+ if(left instanceof fns.TimeExpr){
+ return dojo.date.compare(left_res,right_res,"time");
+ }else if(left instanceof fns.DateExpr){
+ return dojo.date.compare(left_res,right_res,"date");
+ }else{
+ if(left instanceof fns.StringExpr){
+ left_res = left_res.toLowerCase();
+ right_res = String(right_res).toLowerCase();
+ }
+ return left_res == right_res ? 0 : (left_res < right_res ? -1 : 1);
+ }
+ }
+ dojo.declare("dojox.grid.enhanced.plugins.filter.EqualTo", fns._BiOpExpr, {
+ // summary:
+ // An "equal to" condition expression.
+ _name: "equal",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = compareFunc(left_operand,right_operand,datarow,getter);
+ return new fns.BooleanExpr(res === 0); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LessThan", fns._BiOpExpr, {
+ // summary:
+ // A "less than" condition expression.
+ _name: "less",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = compareFunc(left_operand,right_operand,datarow,getter);
+ return new fns.BooleanExpr(res < 0); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LessThanOrEqualTo", fns._BiOpExpr, {
+ // summary:
+ // A "less than or equal to" condition expression.
+ _name: "lessEqual",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = compareFunc(left_operand,right_operand,datarow,getter);
+ return new fns.BooleanExpr(res <= 0); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LargerThan", fns._BiOpExpr, {
+ // summary:
+ // A "larger than" condition expression.
+ _name: "larger",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = compareFunc(left_operand,right_operand,datarow,getter);
+ return new fns.BooleanExpr(res > 0); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LargerThanOrEqualTo", fns._BiOpExpr, {
+ // summary:
+ // A "larger than or equal to" condition expression.
+ _name: "largerEqual",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = compareFunc(left_operand,right_operand,datarow,getter);
+ return new fns.BooleanExpr(res >= 0); //_ConditionExpr
+ }
+ });
+
+ /* String Operations */
+ dojo.declare("dojox.grid.enhanced.plugins.filter.Contains", fns._BiOpExpr, {
+ // summary:
+ // A "contains" condition expression.
+ _name: "contains",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var left_res = String(left_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ var right_res = String(right_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ return new fns.BooleanExpr(left_res.indexOf(right_res) >= 0); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.StartsWith", fns._BiOpExpr, {
+ // summary:
+ // A "starts with" condition expression.
+ _name: "startsWith",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var left_res = String(left_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ var right_res = String(right_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ return new fns.BooleanExpr(left_res.substring(0, right_res.length) == right_res); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.EndsWith", fns._BiOpExpr, {
+ // summary:
+ // An "ends with" condition expression.
+ _name: "endsWith",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var left_res = String(left_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ var right_res = String(right_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ return new fns.BooleanExpr(left_res.substring(left_res.length - right_res.length) == right_res); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.Matches", fns._BiOpExpr, {
+ // summary:
+ // A "regular expression match" condition expression.
+ // The second operand's value will be regarded as an regular expression string.
+ _name: "matches",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var left_res = String(left_operand.applyRow(datarow, getter).getValue());
+ var right_res = new RegExp(right_operand.applyRow(datarow, getter).getValue());
+ return new fns.BooleanExpr(left_res.search(right_res) >= 0); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.IsEmpty", fns._UniOpExpr, {
+ // summary:
+ // Check empty
+ _name: "isEmpty",
+ _calculate: function(/* _ConditionExpr */operand,/* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = operand.applyRow(datarow, getter).getValue();
+ return new fns.BooleanExpr(res === "" || res == null);
+ }
+ });
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_FilterExpr.xd.js b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_FilterExpr.xd.js
new file mode 100644
index 0000000..5e8b738
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/plugins/filter/_FilterExpr.xd.js
@@ -0,0 +1,245 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.enhanced.plugins.filter._FilterExpr"],
+["require", "dojox.grid.enhanced.plugins.filter._DataExprs"],
+["require", "dojo.date"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.enhanced.plugins.filter._FilterExpr"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced.plugins.filter._FilterExpr"] = true;
+dojo.provide("dojox.grid.enhanced.plugins.filter._FilterExpr");
+//This is the main file that should be 'required' if filter expression facility is necessary.
+
+dojo.require("dojox.grid.enhanced.plugins.filter._DataExprs");
+dojo.require("dojo.date");
+
+(function(){
+ var fns = dojox.grid.enhanced.plugins.filter;
+ /* Logic Operations */
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LogicAND", fns._BiOpExpr, {
+ // summary:
+ // A logic AND condition expression.
+ _name: "and",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = left_operand.applyRow(datarow, getter).getValue() &&
+ right_operand.applyRow(datarow, getter).getValue();
+ return new fns.BooleanExpr(res); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LogicOR", fns._BiOpExpr, {
+ // summary:
+ // A logic OR condition expression.
+ _name: "or",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = left_operand.applyRow(datarow, getter).getValue() ||
+ right_operand.applyRow(datarow, getter).getValue();
+ return new fns.BooleanExpr(res); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LogicXOR", fns._BiOpExpr, {
+ // summary:
+ // A logic XOR condition expression.
+ _name: "xor",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var left_res = left_operand.applyRow(datarow, getter).getValue();
+ var right_res = right_operand.applyRow(datarow, getter).getValue();
+ return new fns.BooleanExpr((!!left_res) != (!!right_res)); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LogicNOT", fns._UniOpExpr, {
+ // summary:
+ // A logic NOT condition expression.
+ _name: "not",
+ _calculate: function(/* _ConditionExpr */operand,/* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _UniOpExpr
+ return new fns.BooleanExpr(!operand.applyRow(datarow, getter).getValue()); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LogicALL", fns._OperatorExpr, {
+ // summary:
+ // A logic ALL condition expression, equals a sequence of logic ANDs
+ _name: "all",
+ applyRow: function(/* data item */datarow,/* function(row,colIdx) */ getter){
+ // summary:
+ // Override from _ConditionExpr
+ for(var i = 0, res = true; res && (this._operands[i] instanceof fns._ConditionExpr); ++i){
+ res = this._operands[i].applyRow(datarow,getter).getValue();
+ }
+ return new fns.BooleanExpr(res); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LogicANY", fns._OperatorExpr, {
+ // summary:
+ // A logic ANY condition expression, equals a sequence of logic ORs
+ _name: "any",
+ applyRow: function(/* data item */datarow,/* function(row,colIdx) */ getter){
+ for(var i = 0,res = false; !res && (this._operands[i] instanceof fns._ConditionExpr); ++i){
+ res = this._operands[i].applyRow(datarow,getter).getValue();
+ }
+ return new fns.BooleanExpr(res); //_ConditionExpr
+ }
+ });
+
+ /* Comparison Operations */
+ function compareFunc(left,right,row,getter){
+ left = left.applyRow(row, getter);
+ right = right.applyRow(row, getter);
+ var left_res = left.getValue();
+ var right_res = right.getValue();
+ if(left instanceof fns.TimeExpr){
+ return dojo.date.compare(left_res,right_res,"time");
+ }else if(left instanceof fns.DateExpr){
+ return dojo.date.compare(left_res,right_res,"date");
+ }else{
+ if(left instanceof fns.StringExpr){
+ left_res = left_res.toLowerCase();
+ right_res = String(right_res).toLowerCase();
+ }
+ return left_res == right_res ? 0 : (left_res < right_res ? -1 : 1);
+ }
+ }
+ dojo.declare("dojox.grid.enhanced.plugins.filter.EqualTo", fns._BiOpExpr, {
+ // summary:
+ // An "equal to" condition expression.
+ _name: "equal",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = compareFunc(left_operand,right_operand,datarow,getter);
+ return new fns.BooleanExpr(res === 0); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LessThan", fns._BiOpExpr, {
+ // summary:
+ // A "less than" condition expression.
+ _name: "less",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = compareFunc(left_operand,right_operand,datarow,getter);
+ return new fns.BooleanExpr(res < 0); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LessThanOrEqualTo", fns._BiOpExpr, {
+ // summary:
+ // A "less than or equal to" condition expression.
+ _name: "lessEqual",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = compareFunc(left_operand,right_operand,datarow,getter);
+ return new fns.BooleanExpr(res <= 0); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LargerThan", fns._BiOpExpr, {
+ // summary:
+ // A "larger than" condition expression.
+ _name: "larger",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = compareFunc(left_operand,right_operand,datarow,getter);
+ return new fns.BooleanExpr(res > 0); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.LargerThanOrEqualTo", fns._BiOpExpr, {
+ // summary:
+ // A "larger than or equal to" condition expression.
+ _name: "largerEqual",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = compareFunc(left_operand,right_operand,datarow,getter);
+ return new fns.BooleanExpr(res >= 0); //_ConditionExpr
+ }
+ });
+
+ /* String Operations */
+ dojo.declare("dojox.grid.enhanced.plugins.filter.Contains", fns._BiOpExpr, {
+ // summary:
+ // A "contains" condition expression.
+ _name: "contains",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var left_res = String(left_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ var right_res = String(right_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ return new fns.BooleanExpr(left_res.indexOf(right_res) >= 0); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.StartsWith", fns._BiOpExpr, {
+ // summary:
+ // A "starts with" condition expression.
+ _name: "startsWith",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var left_res = String(left_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ var right_res = String(right_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ return new fns.BooleanExpr(left_res.substring(0, right_res.length) == right_res); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.EndsWith", fns._BiOpExpr, {
+ // summary:
+ // An "ends with" condition expression.
+ _name: "endsWith",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var left_res = String(left_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ var right_res = String(right_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ return new fns.BooleanExpr(left_res.substring(left_res.length - right_res.length) == right_res); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.Matches", fns._BiOpExpr, {
+ // summary:
+ // A "regular expression match" condition expression.
+ // The second operand's value will be regarded as an regular expression string.
+ _name: "matches",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var left_res = String(left_operand.applyRow(datarow, getter).getValue());
+ var right_res = new RegExp(right_operand.applyRow(datarow, getter).getValue());
+ return new fns.BooleanExpr(left_res.search(right_res) >= 0); //_ConditionExpr
+ }
+ });
+ dojo.declare("dojox.grid.enhanced.plugins.filter.IsEmpty", fns._UniOpExpr, {
+ // summary:
+ // Check empty
+ _name: "isEmpty",
+ _calculate: function(/* _ConditionExpr */operand,/* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = operand.applyRow(datarow, getter).getValue();
+ return new fns.BooleanExpr(res === "" || res == null);
+ }
+ });
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/Common.css b/js/dojo-1.6/dojox/grid/enhanced/resources/Common.css
new file mode 100644
index 0000000..d2842f1
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/Common.css
@@ -0,0 +1,36 @@
+.dojoxGrid {
+ border:1px solid #DBDBDB;
+}
+.dojoxGridCellContent {
+ padding:3px;
+}
+.dojoxGridSortNode {
+ padding:3px;
+}
+.dojoxGridInProgress {
+ cursor:progress;
+}
+/* Indirect Selection */
+.dojoxGridRowSelectorStatusText{
+ visibility:hidden;
+}
+.dijit_a11y .dojoxGridRowSelected {
+ opacity:0.8 !important;
+}
+.dijit_a11y .dojoxGridBorderDIV {
+ border:2px solid #000 !important;
+}
+.dijit_a11y .dojoxGridRowSelector {
+ height:100% !important;
+}
+.dijit_a11y .dojoxGridRowSelectorStatusText{
+ font-size:larger !important;
+ visibility:visible;
+}
+.dijit_a11y .dijitCheckBox .dojoxGridRowSelectorStatusText{
+ font-weight:bolder !important;
+ font-size:x-large !important;
+}
+.dijit_a11y .dijitCheckBoxChecked .dojoxGridRowSelectorStatusText{
+ font-size:small !important;
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/Common_rtl.css b/js/dojo-1.6/dojox/grid/enhanced/resources/Common_rtl.css
new file mode 100644
index 0000000..796e935
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/Common_rtl.css
@@ -0,0 +1,15 @@
+.dojoxGridRtl .dojoxGridLoading,
+.dojoxGridRtl .dojoxGridError,
+.dojoxGridRtl .dojoxGridNoData {
+ background-position:right;
+ padding-right:25px;
+ padding-left:0px;
+}
+.dojoxGridRtl .dojoxGridHeader {
+ margin-left: 0;
+ margin-right: -1px;
+}
+
+.dojoxGridRtl .dojoxGridCell {
+ text-align: right;
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/DnD.css b/js/dojo-1.6/dojox/grid/enhanced/resources/DnD.css
new file mode 100644
index 0000000..c364b0e
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/DnD.css
@@ -0,0 +1,78 @@
+.dojoxGridBorderDIV {
+ width:2px;
+ background-color: gray;
+ font-size:0em;
+ position:absolute;
+ z-index:9999;
+}
+.dojoxGridCellBorderDIV {
+ position:absolute;
+ background-color: transparent;
+ border: none;
+}
+.dojoxGridCellBorderLeftTopDIV {
+ position: absolute;
+ left: 0;
+ top: 0;
+ border-style: solid;
+ border-width: 2px 0 0 2px;
+ border-color: gray transparent transparent gray;
+}
+.dojoxGridCellBorderRightBottomDIV {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ border-style: solid;
+ border-width: 0 2px 2px 0;
+ border-color: transparent gray gray transparent;
+}
+.dojoxGridDnDItemIcon {
+ background-image: url("images/sprite_icons.png");
+}
+.dojoxGridDnDIconRowSingle {
+ background-position: -256px 5px;
+}
+.dojoxGridDnDIconRowMulti {
+ background-position: -256px -16px;
+}
+.dojoxGridDnDIconColSingle {
+ background-position: -277px 3px;
+}
+.dojoxGridDnDIconColMulti {
+ background-position: -277px -17px;
+}
+.dojoxGridDnDIconCellSingle {
+ background-position: -235px 5px;
+}
+.dojoxGridDnDIconCellMulti {
+ background-position: -236px -16px;
+}
+.dojoxGridDndAvatar {
+ background-color:white;
+ border: 1px solid #CCCCCC;
+ padding: 0px;
+ -moz-box-shadow: 5px 5px 7px #999;
+ -webkit-box-shadow: 5px 5px 7px #999;
+ box-shadow: 5px 5px 7px #999;
+ z-index: 999;
+}
+.dojoxGridDndAvatar td {
+ padding: 3px;
+}
+.dojoxGridDnDIcon,
+.dojoxGridDnDItemIcon {
+ width: 16px;
+ height: 16px;
+}
+.dojoDndMove .dojoxGridDnDIcon {
+ background: url(../../../../dojo/resources/images/dndNoMove.png) no-repeat center center;
+}
+.dojoDndCopy .dojoxGridDnDIcon {
+ background: url(../../../../dojo/resources/images/dndNoCopy.png) no-repeat center center;
+}
+.dojoDndMove .dojoDndAvatarCanDrop .dojoxGridDnDIcon {
+ background: url(../../../../dojo/resources/images/dndMove.png) no-repeat center center;
+}
+.dojoDndCopy .dojoDndAvatarCanDrop .dojoxGridDnDIcon {
+ background: url(../../../../dojo/resources/images/dndCopy.png) no-repeat center center;
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/DnD_rtl.css b/js/dojo-1.6/dojox/grid/enhanced/resources/DnD_rtl.css
new file mode 100644
index 0000000..d7f270f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/DnD_rtl.css
@@ -0,0 +1,12 @@
+.dojoxGridRtl .dojoxGridCellBorderLeftTopDIV{
+ left: auto;
+ right: 0;
+ border-width: 2px 2px 0 0;
+ border-color: gray gray transparent transparent;
+}
+.dojoxGridRtl .dojoxGridCellBorderRightBottomDIV{
+ right: auto;
+ left: 0;
+ border-width: 0 0 2px 2px;
+ border-color: transparent transparent gray gray;
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/EnhancedGrid.css b/js/dojo-1.6/dojox/grid/enhanced/resources/EnhancedGrid.css
new file mode 100644
index 0000000..7f02773
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/EnhancedGrid.css
@@ -0,0 +1,8 @@
+@import url("Common.css");
+@import url("Filter.css");
+@import url("Pagination.css");
+@import url("DnD.css");
+@import url("Sorter.css");
+@import url("../../../widget/Toaster/Toaster.css");
+@import url("../../../html/resources/ellipsis.css");
+
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css b/js/dojo-1.6/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css
new file mode 100644
index 0000000..0aae662
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css
@@ -0,0 +1,6 @@
+@import url("../../resources/Grid_rtl.css");
+@import url("Common_rtl.css");
+@import url("Filter_rtl.css");
+@import url("Pagination_rtl.css");
+@import url("DnD_rtl.css");
+@import url("Sorter_rtl.css");
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/Filter.css b/js/dojo-1.6/dojox/grid/enhanced/resources/Filter.css
new file mode 100644
index 0000000..1c7039c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/Filter.css
@@ -0,0 +1,292 @@
+/* filter bar */
+.dojoxGridFBar {
+ width: 100%;
+ cursor: pointer;
+}
+.dojoxGridFBar .dojoxGridFBarBtn {
+ margin: 0;
+}
+.dojoxGridFBarBtnTD {
+ width: 38px;
+}
+.dojoxGridFBar .dojoxGridFBarBtn .dijitButtonNode {
+ -moz-border-radius: 1px;
+ -webkit-border-radius: 1px;
+ padding-top: 0;
+ padding-bottom: 0;
+ padding-right: 2px;
+}
+.dojoxGridFBarDefFilterBtnIcon {
+ background: url("images/sprite_icons.png") no-repeat;
+ background-position: -100px -18px;
+ width: 14px;
+ height: 14px;
+}
+.dj_ie .dojoxGridFBarInner{
+ display: inline-block;
+ width: 100%;
+}
+.dojoxGridFBarStatus {
+ margin-left: 9px;
+ float: left;
+}
+.dojoxGridFBarClearFilterBtn {
+ margin: 0 0 0 10px;
+ vertical-align: top;
+ float: left;
+}
+.dojoxGridFBarInfoTD .dojoxGridFBarClearFilterBtn .dijitButtonNode,
+.dojoxGridFBarInfoTD .dojoxGridFBarCloseBtn .dijitButtonNode,
+.dojoxGridFDPane .dijitAccordionTitle .dijitButtonNode,
+.dojoxGridFStatusTipDetail .dijitButton .dijitButtonNode {
+ -moz-border-radius: 0;
+ -moz-box-shadow: none;
+ -webkit-border-radius: 0;
+ -webkit-box-shadow: none;
+ background-image: none;
+ background-color: transparent;
+ margin: 0;
+ padding: 0;
+ border: none;
+}
+.dj_ie .dojoxGridFBarInner {
+ position: relative;
+}
+.dojoxGridFBarCloseBtn {
+ margin: 0 4px 0 0;
+ float: right;
+}
+.dj_ie .dojoxGridFBarCloseBtn {
+ float: none;
+ position: absolute;
+ right: 0;
+}
+.dojoxGridFBarCloseBtnIcon {
+ background: url("images/sprite_icons.png") no-repeat;
+ background-position: -119px -20px;
+ width: 14px;
+ height: 14px;
+}
+.dijitButtonHover .dojoxGridFBarCloseBtnIcon {
+ background-position: -140px -20px;
+}
+.dijitButtonActive .dojoxGridFBarCloseBtnIcon {
+ background-position: -160px -20px;
+}
+
+/* filter def dialog */
+.dojoxGridFDTitlePane {
+ width: 316px;
+ height: 330px;
+}
+.dijit_a11y .dojoxGridFDTitlePane .dijitArrowButtonInner{
+ /* This should be fixed in dijit */
+ display:none !important;
+}
+.dojoxGridFDTitlePane .dijitDialogPaneContent {
+ padding: 7px 5px 9px 5px;
+ height: 290px !important;
+}
+.dojoxGridFDTitlePane .dijitTitlePaneTitle {
+ cursor: move;
+}
+.dojoxGridFDPaneRelation {
+ margin: 0 0 3px 4px;
+}
+.dojoxGridFDPane {
+ width: 100%;
+ height: 100%;
+ position: relative;
+}
+.dojoxGridFDPaneRulePane {
+ height: 222px;
+ overflow: auto;
+ /* for ie6/7 only */
+ position: relative;
+}
+.dj_ie6 .dojoxGridFDPaneRulePane {
+ width: 100%;
+}
+.dojoxGridFDPane .dijitAccordionContainer .dijitContentPane {
+ padding: 6px 9px;
+}
+.dojoxGridFDPane .dijitAccordionTitle {
+ position: relative;
+ /* for non-claro theme, this can ensure a correct height change when adding/removing child */
+ min-height: 17px;
+}
+.dojoxGridFDPane .dijitAccordionTitle .dijitButton {
+ position: absolute;
+ margin: 0;
+ right: 3px;
+ top: 4px;
+}
+.dj_ie6 .dojoxGridFDPane .dijitAccordionTitle .dijitButton {
+ top: 2px;
+}
+.dojoxGridFDPane .dijitAccordionTitleFocus {
+ margin-right: 14px;
+}
+.dojoxGridFDPane .dijitAccordionText {
+ display: inline-block;
+ position: relative;
+}
+.dojoxGridFCBoxRemoveCBoxBtnIcon {
+ background-image: url("images/sprite_icons.png");
+ background-position: -198px -18px;
+ width: 16px;
+ height: 16px;
+}
+.dijitButtonHover .dojoxGridFCBoxRemoveCBoxBtnIcon {
+ background-position: -198px 2px;
+}
+.dojoxGridRuleTitleCondition {
+ font-style: italic;
+}
+.dojoxGridFDPaneModes .dijitSelect {
+ position: relative;
+}
+.dojoxGridFDPaneBtns {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+}
+.dj_ie7 .dojoxGridFDPaneBtns,
+.dj_ie6 .dojoxGridFDPaneBtns {
+ z-index: -1;
+}
+.dojoxGridFDPaneBtns .dijitButton {
+ float: right;
+}
+.dojoxGridFDPaneAddCBoxBtn {
+ margin-top: 9px;
+}
+.dojoxGridFDPaneAddCBoxBtnIcon {
+ background-image: url("images/sprite_icons.png");
+ background-position: -218px 2px;
+ width: 16px;
+ height: 16px;
+}
+.dijitButtonDisabled .dojoxGridFDPaneAddCBoxBtnIcon {
+ background-position: -218px -18px;
+}
+
+/* criteria box */
+.dojoxGridFCBox {
+ height: 125px;
+}
+.dojoxGridFCBoxSelCol,
+.dojoxGridFCBoxCondition {
+ height: 40px;
+}
+.dojoxGridFCBox .dojoxGridFCBoxColSelect,
+.dojoxGridFCBox .dojoxGridFCBoxCondSelect,
+.dojoxGridFCBox .dojoxGridFCBoxValueBox {
+ margin: 5px 0 0 0;
+ width: 100%;
+ /* inherited is inline-block this will cause width "error" in non IE for html tables */
+ display: inline-table;
+}
+.dojoxGridFCBoxCondSelectAlt {
+ width: 100%;
+ padding: 5px 0 0 0;
+ font-weight: bold;
+}
+.dojoxGridFCBox .dijitSelect .dijitArrowButton {
+ width: 18px;
+}
+.dojoxGridFCBoxStartValue {
+ width: 45%;
+}
+.dojoxGridFCBoxEndValue {
+ float: right;
+ width: 45%;
+}
+.dojoxGridFCBoxRangeValueTxt {
+ margin-left: 4px;
+}
+
+/* status tip */
+.dojoxGridFStatusTipDialog .dijitTooltipContainer {
+ padding: 9px 5px;
+}
+.dojoxGridFStatusTip thead,
+.dojoxGridFStatusTip tr {
+ height: 19px;
+}
+.dojoxGridFStatusTip th {
+ max-width: 150px;
+ width: expression(this.clientWidth > 150 ? "150px" : "auto");
+}
+.dojoxGridFStatusTip th div {
+ padding: 2px 5px;
+}
+.dojoxGridFStatusTip td {
+ padding: 2px 6px;
+ max-width: 150px;
+ overflow: hidden;
+ width: expression(this.clientWidth > 150 ? "150px" : "auto");
+}
+.dojoxGridFStatusTipHead {
+ margin-bottom: 9px;
+}
+.dojoxGridFStatusTipTitle {
+ font-weight: bold;
+ margin-right: 1em;
+}
+.dojoxGridFStatusTipHandle {
+ position: relative;
+ padding-right: 16px;
+}
+.dojoxGridFStatusTipDetail .dijitButton {
+ position: absolute;
+ margin: 0;
+ padding: 0;
+ top: -1px;
+ right:0;
+}
+.dojoxGridFStatusTipDelRuleBtnIcon {
+ background-image: url("images/sprite_icons.png");
+ background-position: -198px -18px;
+ height: 16px;
+ width: 16px;
+}
+.dijitButtonHover .dojoxGridFStatusTipDelRuleBtnIcon {
+ background-position: -198px 2px;
+}
+
+/* clear dlg */
+.dj_ie7 .dojoxGridClearFilterConfirm,
+.dj_ie6 .dojoxGridClearFilterConfirm {
+ width: 300px;
+}
+.dojoxGridClearFilterBtns{
+ padding: 10px;
+ height: 18px;
+}
+.dojoxGridClearFilterBtns .dijitButton {
+ float: right;
+}
+
+/* bool value box */
+.dojoxGridTrueBox {
+ float: left;
+ width: 49%;
+}
+.dojoxGridFalseBox {
+ float: left;
+ width: 49%;
+}
+.dojoxGridBoolValueBox .dijitRadio {
+ vertical-align: middle;
+}
+.dojoxGridTrueLabel,
+.dojoxGridFalseLabel {
+ width: 116px;
+ display:inline-block;
+ vertical-align: middle;
+}
+.dj_ie7 .dojoxGridTrueLabel,
+.dj_ie7 .dojoxGridFalseLabel {
+ display: inline;
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/Filter_rtl.css b/js/dojo-1.6/dojox/grid/enhanced/resources/Filter_rtl.css
new file mode 100644
index 0000000..60f34a7
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/Filter_rtl.css
@@ -0,0 +1,78 @@
+/* filter bar */
+.dojoxGridRtl .dojoxGridFBarStatus {
+ margin-left: 0;
+ margin-right: 9px;
+}
+.dojoxGridRtl .dojoxGridFBarClearFilterBtn {
+ margin-left: 0;
+ margin-right: 10px;
+}
+.dojoxGridRtl .dojoxGridFBarCloseBtn {
+ margin: 0 0 0 4px;
+ float: left;
+}
+.dj_ie .dojoxGridRtl .dojoxGridFBarCloseBtn {
+ left: 2px;
+ right: auto;
+}
+/* filter def dialog */
+.dijitRtl .dojoxGridFDPaneRelation {
+ margin: 0 4px 3px 0;
+}
+.dijitRtl .dojoxGridFDPane .dijitAccordionTitleFocus {
+ margin-right: 0;
+ margin-left: 14px;
+}
+.dijitRtl .dojoxGridFDPane .dijitAccordionTitle .dijitButton {
+ left: 3px;
+ right: auto;
+}
+.dj_ie6 .dijitRtl .dojoxGridFDPane .dijitAccordionTitle .dijitButton{
+ left: -290px;
+}
+.dijitRtl .dojoxGridFDPaneBtns {
+ left: 0;
+ right: auto;
+}
+.dijitRtl .dojoxGridFDPaneBtns .dijitButton,
+.dijitRtl .dojoxGridClearFilterBtns .dijitButton,
+.dijitRtl .dojoxGridFCBoxEndValue {
+ float: left;
+}
+.dijitRtl .dojoxGridFCBoxRangeValueTxt {
+ margin-left: 0;
+ margin-right: 4px;
+}
+
+/* status tip */
+.dijitRtl .dojoxGridFStatusTipTitle {
+ margin-left: 1em;
+ margin-right: 0;
+}
+.dijitRtl .dojoxGridFStatusTipHandle {
+ padding-left: 16px;
+ padding-right: 0;
+}
+.dijitRtl .dojoxGridFStatusTipDetail .dijitButton {
+ left: 0;
+ right: auto;
+}
+
+/* bool value box */
+.dijitRtl .dojoxGridTrueBox,
+.dijitRtl .dojoxGridFalseBox {
+ float: right;
+}
+
+/* For Claro */
+.claro .dojoxGridRtl .dojoxGridFBar {
+ border-right: 1px solid white;
+}
+
+.claro .dijitRtl .dojoxGridFStatusTip th div {
+ border-left: 1px solid #BCBCBC;
+ border-right: 1px solid white;
+}
+.claro .dijitRtl .dojoxGridFStatusTip th.lastColumn div {
+ border-left: 1px solid #BCBCBC;
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/Pagination.css b/js/dojo-1.6/dojox/grid/enhanced/resources/Pagination.css
new file mode 100644
index 0000000..8eaa176
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/Pagination.css
@@ -0,0 +1,138 @@
+.dojoxGridPaginator {
+ border-top:1px #DBDBDB solid;
+ text-align:center;
+ width: 100%;
+ height: 24px;
+ table-layout : fixed;
+ background-color: #EAEAEA;
+}
+.dojoxGridDescriptionTd {
+ text-align: left;
+ width: 35%;
+}
+.dojoxGridDescription {
+ text-align: left;
+ margin-left: 9px;
+ overflow: hidden;
+}
+.dojoxGridPaginatorFastStep {
+ text-align: right;
+ width: 35%;
+ overflow: hidden;
+}
+.dojoxGridPaginatorStep {
+ float: right;
+}
+.dojoxGridPaginatorGotoTd {
+ width: 20px!important;
+}
+.dojoxGridPaginatorGotoDiv {
+ cursor: pointer;
+ width: 12px!important;
+ height: 16px!important;
+ margin: 0 6px 0 2px;
+ background: url("images/sprite_icons.png") no-repeat -77px 4px;
+}
+.dojoxGridPaginatorGotoDivDisabled {
+ background: url("images/sprite_icons.png") no-repeat -77px -16px;
+}
+.dojoxGridWardButton {
+ margin-top: 2px;
+ width: 12px!important;
+ height: 12px!important;
+ float: left;
+ background: url("images/sprite_icons.png") no-repeat;
+}
+.dojoxGridWardButtonInner {
+ visibility: hidden;
+}
+.dijit_a11y .dojoxGridWardButtonInner {
+ visibility: visible;
+ margin-bottom: 8px;
+}
+.dojoxGridfirstPageBtn {
+ cursor: pointer;
+ margin-left: 1px;
+ background-position: -57px 3px;
+}
+.dojoxGridfirstPageBtnDisable {
+ margin-left: 1px;
+ background-position: -57px -17px;
+}
+.dojoxGridprevPageBtn {
+ cursor: pointer;
+ margin: 2px 2px 0 9px;
+ background-position: 3px 3px;
+}
+.dojoxGridprevPageBtnDisable {
+ margin: 2px 2px 0 9px;
+ background-position: 3px -17px;
+}
+.dojoxGridlastPageBtn {
+ cursor: pointer;
+ margin: 2px 9px 0 9px;
+ background-position: -37px 3px;
+}
+.dojoxGridlastPageBtnDisable {
+ margin: 2px 9px 0 9px;
+ background-position: -37px -17px;
+}
+
+.dojoxGridnextPageBtn {
+ cursor: pointer;
+ margin-left: 3px;
+ background-position: -17px 3px;
+}
+.dojoxGridnextPageBtnDisable {
+ margin-left: 3px;
+ background-position: -17px -17px;
+}
+.dojoxGridInactived {
+ font-weight: normal;
+ color: #5D88AF;
+ cursor: pointer;
+ margin: 1px 6px 0 5px;
+ float: left;
+ zoom: 1; /* for IE */
+}
+.dojoxGridActived {
+ font-weight: bold;
+ color: black;
+ margin: 1px 6px 0 5px;
+ float: left;
+ text-decoration: none!important;
+ zoom: 1; /* for IE */
+}
+.dojoxGridInactiveSwitch {
+ font-weight: normal;
+ color: #5D88AF;
+ float: left;
+ cursor: pointer;
+ margin: 1px 7px 0 7px;
+ zoom: 1; /* for IE */
+}
+.dojoxGridActivedSwitch {
+ font-weight: bold;
+ color: black;
+ float: left;
+ margin: 1px 7px 0 7px;
+ text-decoration: none!important;
+ zoom: 1; /* for IE */
+}
+.dojoxGridSeparator {
+ float: left;
+}
+.dojoxGridPageTextHover {
+ text-decoration: underline;
+}
+.dojoxGridDialogMargin {
+ width: 220px!important;
+ margin-bottom: 10px;
+}
+.dj_ie6 .dojoxGridDialogMargin {
+ position: relative;
+}
+.dojoxGridDialogButton {
+ width: 220px!important;
+ text-align: right;
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/Pagination_rtl.css b/js/dojo-1.6/dojox/grid/enhanced/resources/Pagination_rtl.css
new file mode 100644
index 0000000..9640319
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/Pagination_rtl.css
@@ -0,0 +1,52 @@
+.dojoxGridRtl .dojoxGridDescription {
+ text-align: right;
+ margin-right: 9px;
+}
+.dojoxGridRtl .dojoxGridPaginatorStep {
+ float: left;
+}
+.dojoxGridRtl .dojoxGridPaginatorGotoDiv {
+ margin: 0 2px 0 6px;
+}
+.dojoxGridRtl .dojoxGridWardButton {
+ float: right;
+}
+.dojoxGridRtl .dojoxGridfirstPageBtn {
+ margin-right: 1px;
+}
+.dojoxGridRtl .dojoxGridfirstPageBtnDisable {
+ margin-left: 1px;
+}
+.dojoxGridRtl .dojoxGridprevPageBtn {
+ margin: 2px 9px 0 5px;
+}
+.dojoxGridRtl .dojoxGridprevPageBtnDisable {
+ margin: 2px 9px 0 5px;
+}
+.dojoxGridRtl .dojoxGridnextPageBtn {
+ margin-right: 3px;
+}
+.dojoxGridRtl .dojoxGridnextPageBtnDisable {
+ margin-right: 3px;
+}
+.dojoxGridRtl .dojoxGridInactived {
+ margin: 1px 5px 0 6px;
+ float: right;
+}
+.dojoxGridRtl .dojoxGridActived {
+ margin: 1px 5px 0 6px;
+ float: right;
+}
+.dijitRtl .dojoxGridDialogButton {
+ float: left;
+ margin-bottom: 10px;
+}
+.dijitRtl .dojoxGridInactiveSwitch {
+ float: right;
+}
+.dijitRtl .dojoxGridActivedSwitch {
+ float: right;
+}
+.dijitRtl .dojoxGridSeparator {
+ float: right;
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/Sorter.css b/js/dojo-1.6/dojox/grid/enhanced/resources/Sorter.css
new file mode 100644
index 0000000..fd16051
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/Sorter.css
@@ -0,0 +1,170 @@
+/*
+.dojoxGrid
+ Sorted, SingleSorted | NestSorted
+.dojoxGridCell
+ Over, SortFocus, ShowIndex
+.dojoxGridSortNode
+ Asc | Desc, Main|Sub
+.dojoxGridSortBtn
+ :hover, Single|Nested
+*/
+.dojoxGrid .dojoxGridSortNode {
+ position: relative;
+ border: 1px solid transparent;
+}
+.dj_ie6 .dojoxGrid .dojoxGridSortNode {
+ overflow: hidden;
+ width:100%;
+}
+.dojoxGrid .dojoxGridSortNoWrap {
+ white-space:nowrap;
+ cursor: pointer;
+}
+.dojoxGridSortBtn {
+ width: 10px;
+ height:100%;
+ visibility: hidden;
+ top: 0;
+ display:block;
+ position: absolute;
+ color: #000;
+ background: #DFEAF1 url(images/sprite_icons.png) no-repeat 100px 0;
+ text-decoration: none;
+ outline: none;
+ right: 0;
+ border: 1px solid transparent;
+ box-sizing: border-box; /* css3 rec */
+ -moz-box-sizing: border-box; /* ff */
+ -ms-box-sizing: border-box; /* ie8 */
+ -webkit-box-sizing: border-box; /* safari3 */
+ -khtml-box-sizing: border-box; /* konqueror */
+}
+.dj_ie6 .dojoxGridSortBtn,
+.dj_ie6 .dojoxGrid .dojoxGridSortNode {
+ border: none;
+}
+.dojoxGridSortBtnNested {
+ right: 10px;
+}
+.dojoxGridCellSortFocus .dojoxGridSortBtn {
+ border-left: 1px solid #999999;
+ background-color: #DFEAF1;
+}
+.dojoxGridCellOver .dojoxGridSortBtn {
+ border-left: 1px solid #999999;
+ background-color: #9dcfff;
+}
+.dojoxGridSortNode {
+ outline: none;
+}
+
+/*Control the title node width*/
+.dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode,
+.dojoxGridCellSortFocus .dojoxGridSortNode,
+.dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellOver .dojoxGridSortNodeMain,
+.dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellSortFocus .dojoxGridSortNodeMain {
+ margin-right: 5px;
+}
+.dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode,
+.dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNode {
+ margin-right: 24px;
+}
+/*html > body used for !dj_ie6, TBD - a better way*/
+html > body .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnSingle {
+ right: -5px;
+}
+html > body .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnSingle,
+html > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+html > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+ right: -10px;
+}
+html > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnSingle,
+html > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle,
+html > body .dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+html > body .dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+ right: -28px;
+}
+html > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnNested,
+html > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+ right: -17px;
+}
+
+.dojoxGrid .dojoxGridHeader .dojoxGridRowTable .dojoxGridNoSort .dojoxGridSortNode {
+ margin:0!important;
+}
+
+/*Focus border*/
+/*Control visibility*/
+.dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnSingle, /* single sort btn is always visible when mouseover*/
+.dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnSingle,
+.dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnNested, /* in a sorted grid, nest btn is always visible when mouseover (except 1)*/
+.dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnNested,
+.dojoxGrid .dojoxGridCellShowIndex .dojoxGridSortNode .dojoxGridSortBtnNested, /* in a single sort grid, when mouseover other columns, show 1 on the main sort column*/
+.dojoxGrid .dojoxGridSortNodeSorted .dojoxGridSortBtn { /* in a sorted column, single or nested sort btn are always visible (except 2)*/
+ visibility: visible;
+}
+.dojoxGridSingleSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnNested, /*(1)in a single sorted grid, nest btn is hidden in sort column when mouseover*/
+.dojoxGridSingleSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnNested,
+.dojoxGridSingleSorted .dojoxGridSortNode .dojoxGridSortBtnNested { /*(2)all nested btn is hidden in single sort grid without mouse over*/
+ visibility: hidden;
+}
+
+/*
+-119 asc
+-99 desc
+-159 do asc
+-139 do desc
+-179 no sort
+*/
+/*Control background image*/
+.dojoxGridSortNodeAsc .dojoxGridSortBtnSingle {
+ background-position: -119px 5px;
+ visibility: visible;
+}
+.dojoxGridSortNodeDesc .dojoxGridSortBtnSingle {
+ background-position: -99px 5px;
+ visibility: visible;
+}
+/*hover single sort*/
+.dojoxGridCellOver .dojoxGridSortBtnSingle,
+.dojoxGridCellSortFocus .dojoxGridSortBtnSingle {
+ background-position: -159px 5px;
+}
+.dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle,
+.dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle,
+.dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnAsc,
+.dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnAsc {
+ background-position: -139px 5px;
+}
+.dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle,
+.dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle,
+.dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnDesc,
+.dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnDesc {
+ background-position: -179px 5px;
+}
+/*hover nested sort*/
+.dojoxGridCellOver .dojoxGridSortBtnNested,
+.dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+ background-position: -149px 5px;
+ width: 19px;
+}
+.dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnNested,
+.dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnNested {
+ background-position: -129px 5px;
+}
+.dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnNested,
+.dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnNested {
+ background-position: -169px 5px;
+}
+.dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortBtnSingle,
+.dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle {
+ background-position: -159px 5px;
+}
+.dojoxGridCellOver .dojoxGridSortBtn:hover {
+ background-color:#A3E4FF;
+}
+.dojoxGrid .dojoxGridSortNodeFocus,
+.dojoxGridCellSortFocus .dojoxGridRowSelector,
+.dojoxGridCellSortFocus .dojoxGridSortBtnFocus {
+ border: 1px dashed #666;
+} \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/Sorter_rtl.css b/js/dojo-1.6/dojox/grid/enhanced/resources/Sorter_rtl.css
new file mode 100644
index 0000000..3faaedb
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/Sorter_rtl.css
@@ -0,0 +1,78 @@
+.dojoxGridRtl .dojoxGridSortBtnSingle {
+ right: auto;
+ left: 0px;
+}
+.dojoxGridRtl .dojoxGridSortBtnNested {
+ right: auto;
+ left: 10px;
+}
+
+.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtn,
+.dj_ie6 dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtn,
+.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtn {
+ border-left: none;
+ border-right: 1px solid #999999;
+}
+
+/*Control the title node width*/
+.dijitRtl .dojoxGridCellOver .dojoxGridSortNode,
+.dijitRtl .dojoxGridCellSortFocus .dojoxGridSortNode,
+.dijitRtl .dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellOver .dojoxGridSortNodeMain,
+.dijitRtl .dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellSortFocus .dojoxGridSortNodeMain {
+ margin-right: auto;
+ margin-left: 10px;
+}
+.dijitRtl .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode,
+.dijitRtl .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNode {
+ margin-right: auto;
+ margin-left: 24px;
+}
+/*html > body used for !dj_ie6, TBD - a better way*/
+html.dijitRtl > body .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnSingle {
+ right: auto;
+ left: -10px;
+}
+html.dijitRtl > body .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnSingle,
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+ right: auto;
+ left: -10px;
+}
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnSingle,
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle,
+html.dijitRtl > body .dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+html.dijitRtl > body .dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+ right: auto;
+ left: -28px;
+}
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnNested,
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+ right: auto;
+ left: -17px;
+}
+.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtnNested,
+.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+ background-position: -159px 5px;
+ padding-left:8px;
+}
+.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnNested,
+.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnNested {
+ background-position: -139px 5px;
+}
+
+.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnNested,
+.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnNested {
+ background-position: -179px 5px;
+}
+.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtnNested,
+.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+ padding-left: 8px;
+ padding-right: 0;
+}
+
+.dj_ie6 .dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtnNested,
+.dj_ie6 .dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtnNested,
+.dj_ie6 .dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtnNested,
+.dj_ie6 .dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+ padding-left:0px;
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/claro/Common.css b/js/dojo-1.6/dojox/grid/enhanced/resources/claro/Common.css
new file mode 100644
index 0000000..102f703
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/claro/Common.css
@@ -0,0 +1,99 @@
+/* overwrite claroGrid.css */
+.claro .dojoxGridMasterHeader .dojoxGridRowTable {
+ border-left: 1px solid #BCBCBC;
+ border-right: 1px solid white;
+ background-color: transparent;
+}
+.claro .dojoxGridHeader tr:first-child .dojoxGridCell {
+ border-top: 1px solid transparent;
+}
+.claro .dojoxGridHeader:first-child .dojoxGridRowTable {
+ border-left-width: 0;
+}
+.claro .dojoxGridMasterHeader {
+ background: url("../../../resources/images/header.png") #EDF2F7 repeat-x bottom;
+ background: -moz-linear-gradient(top, #EDF2F7, #D0DFEA);
+ background: -webkit-gradient(linear, left top, left bottom, from(#EDF2F7), to(#D0DFEA));
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#FFEDF2F7, endColorstr=#FFD0DFEA);
+ border-bottom: 1px solid white;
+ border-left: 1px solid white;
+ border-top: 1px solid white;
+}
+.claro .dojoxGridCell {
+ padding: 3px 5px;
+ border-color: transparent #E5DAC8 #E5DAC8 transparent;
+}
+.dj_ie6 .claro .dojoxGridCell{
+ border-color:#F5F5F5;
+}
+.claro .dojoxGridHeader {
+ background: transparent;
+ margin-left: -2px;
+}
+.claro .dojoxGridHeader:first-child {
+ margin-left: -1px;
+}
+.claro .dojoxGridHeader .dojoxGridCell{
+ padding: 2px 5px;
+ background: transparent;
+ border-bottom: 1px solid #BCBCBC;
+ border-top: 1px solid white;
+ border-left: 1px solid white;
+ border-right: 1px solid #BCBCBC;
+ vertical-align: top;
+}
+.claro .dojoxGridHeader .dojoxGridCellOver {
+ background:#9dcfff;
+}
+.claro .dojoxGridSortNode{
+ white-space: normal;
+ background: none;
+ border: none;
+ padding: 0;
+}
+.claro .dojoxGridHeader .dojoxGridRowTable tr {
+ background:none;
+}
+.claro .dojoxGridCellContent {
+ padding:4px 6px 4px 6px;
+}
+.dj_webkit .claro th.dojoxGridCell > .dojoxGridCellContent {
+ padding: 4px 0;
+}
+.claro .dojoxGridRowbarInner {
+ width:20px;
+}
+/* end overwrite */
+
+.claro .dojoxGridHeaderSelected .dojoxGridHeaderActive {
+ background-color:#91c9fe;
+}
+.claro td.dojoxGridRowSelected {
+ border-collapse:separate;
+ background:url("../../../resources/images/row_back.png") #CEE6FA repeat-x;
+}
+.claro .dojoxGridRowOver td.dojoxGridRowSelected {
+ border-top:1px solid #769DC0;
+ border-bottom:1px solid #769DC0;
+}
+.claro .dojoxGridRowActive td.dojoxGridRowSelected {
+ background-image:url("../../../resources/images/td_button_down.png");
+}
+.dj_ie6 .claro .dojoxGridRowOver .dojoxGridCell {
+ border-color: #ABD6FF;
+}
+.dj_ie6 .claro .dojoxGridRowActive .dojoxGridCell {
+ border-color: #7DBEFA;
+}
+
+/* Don't need any explicit outlines */
+.claro .dojoxGridCell,
+.claro .dojoxGridCellFocus {
+ outline: none;
+}
+
+/* Pagination */
+.claro .dojoxGridPaginator{
+ background: url("../../../resources/images/header_shadow.png") repeat-x scroll center bottom #E5EDF4;
+ /*background-color: #EAF1F6;*/
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/claro/EnhancedGrid.css b/js/dojo-1.6/dojox/grid/enhanced/resources/claro/EnhancedGrid.css
new file mode 100644
index 0000000..5c3b1a6
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/claro/EnhancedGrid.css
@@ -0,0 +1,4 @@
+@import url("../../../resources/claroGrid.css");
+@import url("../EnhancedGrid.css");
+@import url("Common.css");
+@import url("Filter.css");
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/claro/Filter.css b/js/dojo-1.6/dojox/grid/enhanced/resources/claro/Filter.css
new file mode 100644
index 0000000..4574142
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/claro/Filter.css
@@ -0,0 +1,59 @@
+.claro .dojoxGridFBarInfoTD {
+ background: url("../../../resources/images/header_shadow.png") #F2F9FF repeat-x bottom;
+ background: -moz-linear-gradient(top, #F2F9FF, #EAF5FF);
+ background: -webkit-gradient(linear, left top, left bottom, from(#F2F9FF), to(#EAF5FF));
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#FFF2F9FF, endColorstr=#FFEAF5FF);
+}
+.claro .dojoxGridFBarHover .dojoxGridFBarInfoTD {
+ background: url("../../../resources/images/header_shadow.png") #F2F9FF repeat-x bottom;
+ background: -moz-linear-gradient(top, #ECF6FF 2px, #F2F9FF, #EAF5FF 6px);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0.1, #ECF6FF), color-stop(0.6, #F2F9FF), color-stop(0.8, #EAF5FF));
+}
+.dj_gecko .claro .dojoxGridFBarInfoTD,
+.dj_webkit .claro .dojoxGridFBarInfoTD {
+ border-top: 1px solid #BFD6EB;
+ border-bottom: 1px solid #BFD6EB;
+}
+.dj_ie .claro .dojoxGridFBarInner{
+ border-top: 1px solid #BFD6EB;
+ border-bottom: 1px solid #BFD6EB;
+ display:inline-block;
+ width: 100%;
+}
+.claro .dojoxGridFBarClearFilterBtn {
+ color: #5B83B6;
+}
+.claro .dojoxGridFBarInfoTD .dojoxGridFBarClearFilterBtn.dijitButtonHover .dijitButtonText {
+ text-decoration: underline;
+}
+.claro .dojoxGridFBar {
+ border-left: 1px solid white;
+}
+.claro .dojoxGridFStatusTip table {
+ border: 1px solid #BCBCBC;
+}
+.claro .dojoxGridFStatusTip th {
+ background-color: #E8EFF4;
+ border-bottom: 1px solid #BCBCBC;
+}
+.claro .dojoxGridFStatusTip th div {
+ background-color: #E8EFF4;
+ border-left: 1px solid white;
+ border-right: 1px solid #BCBCBC;
+ border-top: 1px solid white;
+ border-bottom: 1px solid white;
+}
+.claro .dojoxGridFStatusTip th.lastColumn div {
+ border-right: 1px solid white;
+}
+.claro .dojoxGridFStatusTip td {
+ border-top: 1px solid white;
+ border-bottom: 1px solid white;
+}
+.claro .dojoxGridFStatusTipRel,
+.claro .dojoxGridFStatusTipCondition {
+ font-style: italic;
+}
+.claro .dojoxGridFStatusTipOddRow {
+ background-color: #F1F8FF;
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/images/sprite_icons.png b/js/dojo-1.6/dojox/grid/enhanced/resources/images/sprite_icons.png
new file mode 100644
index 0000000..565e63f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/images/sprite_icons.png
Binary files differ
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/tundra/Common.css b/js/dojo-1.6/dojox/grid/enhanced/resources/tundra/Common.css
new file mode 100644
index 0000000..81287aa
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/tundra/Common.css
@@ -0,0 +1,40 @@
+/* overwrite */
+.tundra .dojoxGridHeader .dojoxGridCell{
+ background: #fafafa url(../../../../../dijit/themes/tundra/images/titleBar.png) repeat-x bottom left;
+ border-top: 1px solid #bfbfbf;
+ /*border-left-width: 0px;*/
+}
+.tundra .dojoxGridCell {
+ padding:0px;
+ /*display:inline;*/
+ /*position:relative;*/
+ /*border-left-width: 0px;*/
+}
+.dj_ie6 .tundra .dojoxGridMasterView .dojoxGridCellOver{
+ border: 1px dashed #e9e9e9;
+}
+.dj_ie6 .tundra .dojoxGridHeader .dojoxGridCellOver{
+ border-bottom: none !important;
+ border-right: 1px solid #D5CDB5 !important;
+ border-top: 1px solid #D5CDB5 !important;
+}
+.tundra .dojoxGridRowbarInner {
+ width:20px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortNode,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNode {
+ cursor:pointer;
+ background: #f8fafd url("../../../../../dijit/themes/tundra/images/accordionItemHover.gif") bottom repeat-x;
+}
+/* end overwrite */
+
+/* fix safari focus border - overwrite */
+.dj_webkit .tundra .dojoxGridCell,
+.dj_webkit .tundra .dojoxGridCellFocus {
+ outline: none;
+}
+
+/*Pagination*/
+.tundra .dojoxGridPaginator {
+ background: url("../../../../../dijit/themes/tundra/images/titleBar.png") repeat-x top left;
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/tundra/EnhancedGrid.css b/js/dojo-1.6/dojox/grid/enhanced/resources/tundra/EnhancedGrid.css
new file mode 100644
index 0000000..f8159c8
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/tundra/EnhancedGrid.css
@@ -0,0 +1,5 @@
+@import url("../../../resources/tundraGrid.css");
+@import url("../EnhancedGrid.css");
+@import url("Common.css");
+@import url("Filter.css");
+@import url("Sorter.css");
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/tundra/Filter.css b/js/dojo-1.6/dojox/grid/enhanced/resources/tundra/Filter.css
new file mode 100644
index 0000000..b7b7b83
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/tundra/Filter.css
@@ -0,0 +1,38 @@
+.tundra .dojoxGridFBar {
+ background-color: #eeeeee;
+ border: 1px solid #bfbfbf;
+}
+.tundra .dojoxGridFBarFiltered {
+ background: #fafafa url(../../../../../dijit/themes/tundra/images/titleBar.png) repeat-x bottom left;
+}
+.tundra .dojoxGridFBarHover {
+ background-color: #cccccc;
+ background-image: none;
+}
+.tundra .dojoxGridFStatusTip table {
+ border: 1px solid #eeeeee;
+}
+.tundra .dojoxGridFStatusTip th {
+ background: #fafafa url(../../../../../dijit/themes/tundra/images/titleBar.png) repeat-x bottom left;
+ border-bottom: 1px solid #eeeeee;
+}
+.tundra .dojoxGridFStatusTip th div {
+ border-left: 1px solid white;
+ border-right: 1px solid #eeeeee;
+ border-top: 1px solid white;
+ border-bottom: 1px solid white;
+}
+.tundra .dojoxGridFStatusTip th.lastColumn div {
+ border-right: 1px solid white;
+}
+.tundra .dojoxGridFStatusTip td {
+ border-top: 1px solid white;
+ border-bottom: 1px solid white;
+}
+.tundra .dojoxGridFStatusTipRel,
+.tundra .dojoxGridFStatusTipCondition {
+ font-style: italic;
+}
+.tundra .dojoxGridFStatusTipOddRow {
+ background-color: #f2f5f9;
+}
diff --git a/js/dojo-1.6/dojox/grid/enhanced/resources/tundra/Sorter.css b/js/dojo-1.6/dojox/grid/enhanced/resources/tundra/Sorter.css
new file mode 100644
index 0000000..480dd7e
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/resources/tundra/Sorter.css
@@ -0,0 +1,83 @@
+.tundra .dojoxGridSortBtn {
+ padding-top: 3px;
+}
+.tundra .dojoxGridSortBtnNested {
+ right: 11px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortBtn,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortBtn {
+ background-color: #ccc;
+}
+
+/*Control the title node width*/
+.tundra .dojoxGridCellOver .dojoxGridSortNode,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNode,
+.tundra .dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellOver .dojoxGridSortNodeMain,
+.tundra .dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellSortFocus .dojoxGridSortNodeMain {
+ margin-right: 12px;
+}
+.tundra .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode,
+.tundra .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNode {
+ margin-right: 31px;
+}
+
+/*ie 6 doesn't need below*/
+.tundra .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnSingle,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnSingle,
+.tundra .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+.tundra .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+ right: -12px;
+}
+.tundra .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnSingle,
+.tundra .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle,
+.tundra .dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+.tundra .dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+ right: -31px;
+}
+.tundra .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnNested,
+.tundra .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+ right: -20px;
+}
+/*ie6 hack end*/
+
+/*Control background image*/
+.tundra .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle {
+ background-position: -119px 8px;
+}
+.tundra .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle {
+ background-position: -99px 8px;
+}
+/*hover single sort*/
+.tundra .dojoxGridCellOver .dojoxGridSortBtnSingle,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortBtnSingle {
+ background-position: -159px 8px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle,
+.tundra .dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnAsc,
+.tundra .dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnAsc {
+ background-position: -139px 8px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle,
+.tundra .dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnDesc,
+.tundra .dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnDesc {
+ background-position: -179px 8px;
+}
+/*hover nested sort*/
+.tundra .dojoxGridCellOver .dojoxGridSortBtnNested,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+ background-position: -150px 8px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnNested,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnNested {
+ background-position: -130px 8px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnNested,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnNested {
+ background-position: -170px 8px;
+}
+.tundra .dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortBtnSingle,
+.tundra .dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle {
+ background-position: -159px 8px;
+} \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/enhanced/templates/ClearFilterConfirmPane.html b/js/dojo-1.6/dojox/grid/enhanced/templates/ClearFilterConfirmPane.html
new file mode 100644
index 0000000..1637b2e
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/templates/ClearFilterConfirmPane.html
@@ -0,0 +1,9 @@
+<div class="dojoxGridClearFilterConfirm">
+ <div class="dojoxGridClearFilterMsg">
+ ${_clearFilterMsg}
+ </div>
+ <div class="dojoxGridClearFilterBtns" dojoAttachPoint="btnsNode">
+ <span dojoType="dijit.form.Button" label="${_cancelBtnLabel}" dojoAttachPoint="cancelBtn" dojoAttachEvent="onClick:_onCancel"></span>
+ <span dojoType="dijit.form.Button" label="${_clearBtnLabel}" dojoAttachPoint="clearBtn" dojoAttachEvent="onClick:_onClear"></span>
+ </div>
+</div>
diff --git a/js/dojo-1.6/dojox/grid/enhanced/templates/CriteriaBox.html b/js/dojo-1.6/dojox/grid/enhanced/templates/CriteriaBox.html
new file mode 100644
index 0000000..ad9a1ec
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/templates/CriteriaBox.html
@@ -0,0 +1,20 @@
+<div class="dojoxGridFCBox">
+ <div class="dojoxGridFCBoxSelCol" dojoAttachPoint="selColNode">
+ <span class="dojoxGridFCBoxField">${_colSelectLabel}</span>
+ <select dojoAttachPoint="_colSelect" dojoType="dijit.form.Select"
+ class="dojoxGridFCBoxColSelect"
+ dojoAttachEvent="onChange:_onChangeColumn">
+ </select>
+ </div>
+ <div class="dojoxGridFCBoxCondition" dojoAttachPoint="condNode">
+ <span class="dojoxGridFCBoxField">${_condSelectLabel}</span>
+ <select dojoAttachPoint="_condSelect" dojoType="dijit.form.Select"
+ class="dojoxGridFCBoxCondSelect"
+ dojoAttachEvent="onChange:_onChangeCondition">
+ </select>
+ <div class="dojoxGridFCBoxCondSelectAlt" dojoAttachPoint="_condSelectAlt" style="display:none;"></div>
+ </div>
+ <div class="dojoxGridFCBoxValue" dojoAttachPoint="valueNode">
+ <span class="dojoxGridFCBoxField">${_valueBoxLabel}</span>
+ </div>
+</div>
diff --git a/js/dojo-1.6/dojox/grid/enhanced/templates/FilterBar.html b/js/dojo-1.6/dojox/grid/enhanced/templates/FilterBar.html
new file mode 100644
index 0000000..cbcb68d
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/templates/FilterBar.html
@@ -0,0 +1,15 @@
+<table class="dojoxGridFBar" border="0" cellspacing="0" dojoAttachEvent="onclick:_onClickFilterBar, onmouseenter:_onMouseEnter, onmouseleave:_onMouseLeave, onmousemove:_onMouseMove"
+ ><tr><td class="dojoxGridFBarBtnTD"
+ ><span dojoType="dijit.form.Button" class="dojoxGridFBarBtn" dojoAttachPoint="defineFilterButton" label="..." iconClass="dojoxGridFBarDefFilterBtnIcon" showLabel="true" dojoAttachEvent="onClick:_showFilterDefDialog, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton"></span
+ ></td><td class="dojoxGridFBarInfoTD"
+ ><span class="dojoxGridFBarInner"
+ ><span class="dojoxGridFBarStatus" dojoAttachPoint="statusBarNode">${_noFilterMsg}</span
+ ><span dojoType="dijit.form.Button" class="dojoxGridFBarClearFilterBtn" dojoAttachPoint="clearFilterButton"
+ label="${_filterBarClearBtnLabel}" iconClass="dojoxGridFBarClearFilterBtnIcon" showLabel="true"
+ dojoAttachEvent="onClick:_clearFilterDefDialog, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton"></span
+ ><span dojotype="dijit.form.Button" class="dojoxGridFBarCloseBtn" dojoAttachPoint="closeFilterBarButton"
+ label="${_closeFilterBarBtnLabel}" iconClass="dojoxGridFBarCloseBtnIcon" showLabel="false"
+ dojoAttachEvent="onClick:_closeFilterBar, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton"></span
+ ></span
+ ></td></tr
+></table>
diff --git a/js/dojo-1.6/dojox/grid/enhanced/templates/FilterBoolValueBox.html b/js/dojo-1.6/dojox/grid/enhanced/templates/FilterBoolValueBox.html
new file mode 100644
index 0000000..6779e70
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/templates/FilterBoolValueBox.html
@@ -0,0 +1,11 @@
+<div class="dojoxGridBoolValueBox">
+ <div class="dojoxGridTrueBox">
+ <input dojoType="dijit.form.RadioButton" type='radio' name='a1' id='${_baseId}_rbTrue' checked="true"
+ dojoAttachPoint="rbTrue" dojoAttachEvent="onChange: onChange"/>
+ <div class="dojoxGridTrueLabel" for='${_baseId}_rbTrue'>${_lblTrue}</div>
+ </div>
+ <div class="dojoxGridFalseBox">
+ <input dojoType="dijit.form.RadioButton" dojoAttachPoint="rbFalse" type='radio' name='a1' id='${_baseId}_rbFalse'/>
+ <div class="dojoxGridTrueLabel" for='${_baseId}_rbFalse'>${_lblFalse}</div>
+ </div>
+</div>
diff --git a/js/dojo-1.6/dojox/grid/enhanced/templates/FilterDefPane.html b/js/dojo-1.6/dojox/grid/enhanced/templates/FilterDefPane.html
new file mode 100644
index 0000000..5783f36
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/templates/FilterDefPane.html
@@ -0,0 +1,27 @@
+<div class="dojoxGridFDPane">
+ <div class="dojoxGridFDPaneRelation">${_relMsgFront}
+ <span class="dojoxGridFDPaneModes" dojoAttachPoint="criteriaModeNode">
+ <select dojoAttachPoint="_relSelect" dojoType="dijit.form.Select" dojoAttachEvent="onChange: _onRelSelectChange">
+ <option value="0">${_relAll}</option>
+ <option value="1">${_relAny}</option>
+ </select>
+ </span>
+ ${_relMsgTail}
+ </div>
+ <div dojoAttachPoint="criteriaPane" class="dojoxGridFDPaneRulePane"></div>
+ <div dojoAttachPoint="_addCBoxBtn" dojoType="dijit.form.Button"
+ class="dojoxGridFDPaneAddCBoxBtn" iconClass="dojoxGridFDPaneAddCBoxBtnIcon"
+ dojoAttachEvent="onClick:_onAddCBox" label="${_addRuleBtnLabel}" showLabel="false">
+ </div>
+ <div class="dojoxGridFDPaneBtns" dojoAttachPoint="buttonsPane">
+ <span dojoAttachPoint="_cancelBtn" dojoType="dijit.form.Button"
+ dojoAttachEvent="onClick:_onCancel" label="${_cancelBtnLabel}">
+ </span>
+ <span dojoAttachPoint="_clearFilterBtn" dojoType="dijit.form.Button"
+ dojoAttachEvent="onClick:_onClearFilter" label="${_clearBtnLabel}" disabled="true">
+ </span>
+ <span dojoAttachPoint="_filterBtn" dojoType="dijit.form.Button"
+ dojoAttachEvent="onClick:_onFilter" label="${_filterBtnLabel}" disabled="true">
+ </span>
+ </div>
+</div>
diff --git a/js/dojo-1.6/dojox/grid/enhanced/templates/FilterStatusPane.html b/js/dojo-1.6/dojox/grid/enhanced/templates/FilterStatusPane.html
new file mode 100644
index 0000000..f832b9b
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/templates/FilterStatusPane.html
@@ -0,0 +1,9 @@
+<div class="dojoxGridFStatusTip">
+ <div class="dojoxGridFStatusTipHead">
+ <span class="dojoxGridFStatusTipTitle" dojoAttachPoint="statusTitle"></span
+ ><span class="dojoxGridFStatusTipRelPre" dojoAttachPoint="statusRelPre"></span
+ ><span class="dojoxGridFStatusTipRel" dojoAttachPoint="statusRel"></span
+ ><span class="dojoxGridFStatusTipRelPost" dojoAttachPoint="statusRelPost"></span>
+ </div>
+ <div class="dojoxGridFStatusTipDetail" dojoAttachPoint="statusDetailNode"></div>
+</div>
diff --git a/js/dojo-1.6/dojox/grid/enhanced/templates/Pagination.html b/js/dojo-1.6/dojox/grid/enhanced/templates/Pagination.html
new file mode 100644
index 0000000..e26a8e5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/enhanced/templates/Pagination.html
@@ -0,0 +1,13 @@
+<div dojoAttachPoint="paginatorBar">
+ <table cellpadding="0" cellspacing="0" class="dojoxGridPaginator">
+ <tr>
+ <td dojoAttachPoint="descriptionTd" class="dojoxGridDescriptionTd">
+ <div dojoAttachPoint="descriptionDiv" class="dojoxGridDescription" />
+ </td>
+ <td dojoAttachPoint="sizeSwitchTd"></td>
+ <td dojoAttachPoint="pageStepperTd" class="dojoxGridPaginatorFastStep">
+ <div dojoAttachPoint="pageStepperDiv" class="dojoxGridPaginatorStep"></div>
+ </td>
+ </tr>
+ </table>
+</div>
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ROOT.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ROOT.js
new file mode 100644
index 0000000..56bceec
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ROOT.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ROOT");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ROOT");dijit.nls.loading.ROOT={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ROOT.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ROOT.xd.js
new file mode 100644
index 0000000..89e5a64
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ROOT.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_ROOT"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.ROOT"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_ROOT");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ROOT");dijit.nls.loading.ROOT={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ar.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ar.js
new file mode 100644
index 0000000..824ddd2
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ar.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ar");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ar");dijit.nls.loading.ar={"loadingState":"جاري التحميل...","errorState":"عفوا، حدث خطأ"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ar.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ar.xd.js
new file mode 100644
index 0000000..3eb4c2c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ar.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_ar"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.ar"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_ar");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ar");dijit.nls.loading.ar={"loadingState":"جاري التحميل...","errorState":"عفوا، حدث خطأ"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ca.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ca.js
new file mode 100644
index 0000000..a33495f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ca.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ca");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ca");dijit.nls.loading.ca={"loadingState":"S'està carregant...","errorState":"Ens sap greu. S'ha produït un error."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ca.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ca.xd.js
new file mode 100644
index 0000000..5cc8e90
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ca.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_ca"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.ca"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_ca");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ca");dijit.nls.loading.ca={"loadingState":"S'està carregant...","errorState":"Ens sap greu. S'ha produït un error."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_cs.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_cs.js
new file mode 100644
index 0000000..6a8c6e2
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_cs.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_cs");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.cs");dijit.nls.loading.cs={"loadingState":"Probíhá načítání...","errorState":"Omlouváme se, došlo k chybě"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_cs.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_cs.xd.js
new file mode 100644
index 0000000..5cebf6d
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_cs.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_cs"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.cs"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_cs");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.cs");dijit.nls.loading.cs={"loadingState":"Probíhá načítání...","errorState":"Omlouváme se, došlo k chybě"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_da.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_da.js
new file mode 100644
index 0000000..30968f0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_da.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_da");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.da");dijit.nls.loading.da={"loadingState":"Indlæser...","errorState":"Der er opstået en fejl"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_da.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_da.xd.js
new file mode 100644
index 0000000..29a7443
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_da.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_da"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.da"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_da");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.da");dijit.nls.loading.da={"loadingState":"Indlæser...","errorState":"Der er opstået en fejl"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_de-de.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_de-de.js
new file mode 100644
index 0000000..c2e6862
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_de-de.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_de-de");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.de_de");dijit.nls.loading.de_de={"loadingState":"Wird geladen...","errorState":"Es ist ein Fehler aufgetreten."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_de-de.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_de-de.xd.js
new file mode 100644
index 0000000..3db58fa
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_de-de.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_de-de"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.de_de"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_de-de");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.de_de");dijit.nls.loading.de_de={"loadingState":"Wird geladen...","errorState":"Es ist ein Fehler aufgetreten."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_de.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_de.js
new file mode 100644
index 0000000..7afaf9b
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_de.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_de");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.de");dijit.nls.loading.de={"loadingState":"Wird geladen...","errorState":"Es ist ein Fehler aufgetreten."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_de.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_de.xd.js
new file mode 100644
index 0000000..f4deec7
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_de.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_de"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.de"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_de");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.de");dijit.nls.loading.de={"loadingState":"Wird geladen...","errorState":"Es ist ein Fehler aufgetreten."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_el.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_el.js
new file mode 100644
index 0000000..c5bf528
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_el.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_el");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.el");dijit.nls.loading.el={"loadingState":"Φόρτωση...","errorState":"Σας ζητούμε συγνώμη, παρουσιάστηκε σφάλμα"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_el.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_el.xd.js
new file mode 100644
index 0000000..bd250a0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_el.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_el"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.el"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_el");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.el");dijit.nls.loading.el={"loadingState":"Φόρτωση...","errorState":"Σας ζητούμε συγνώμη, παρουσιάστηκε σφάλμα"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en-gb.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en-gb.js
new file mode 100644
index 0000000..7f3b1a0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en-gb.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_en-gb");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.en_gb");dijit.nls.loading.en_gb={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en-gb.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en-gb.xd.js
new file mode 100644
index 0000000..4cc23fe
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en-gb.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_en-gb"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.en_gb"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_en-gb");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.en_gb");dijit.nls.loading.en_gb={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en-us.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en-us.js
new file mode 100644
index 0000000..dfa0bde
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en-us.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_en-us");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.en_us");dijit.nls.loading.en_us={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en-us.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en-us.xd.js
new file mode 100644
index 0000000..fa2eb06
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en-us.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_en-us"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.en_us"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_en-us");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.en_us");dijit.nls.loading.en_us={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en.js
new file mode 100644
index 0000000..f40c9d5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_en");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.en");dijit.nls.loading.en={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en.xd.js
new file mode 100644
index 0000000..9a21666
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_en.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_en"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.en"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_en");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.en");dijit.nls.loading.en={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_es-es.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_es-es.js
new file mode 100644
index 0000000..f875122
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_es-es.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_es-es");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.es_es");dijit.nls.loading.es_es={"loadingState":"Cargando...","errorState":"Lo siento, se ha producido un error"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_es-es.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_es-es.xd.js
new file mode 100644
index 0000000..b83eaf5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_es-es.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_es-es"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.es_es"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_es-es");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.es_es");dijit.nls.loading.es_es={"loadingState":"Cargando...","errorState":"Lo siento, se ha producido un error"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_es.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_es.js
new file mode 100644
index 0000000..3a3970f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_es.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_es");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.es");dijit.nls.loading.es={"loadingState":"Cargando...","errorState":"Lo siento, se ha producido un error"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_es.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_es.xd.js
new file mode 100644
index 0000000..8d5adfa
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_es.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_es"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.es"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_es");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.es");dijit.nls.loading.es={"loadingState":"Cargando...","errorState":"Lo siento, se ha producido un error"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fi-fi.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fi-fi.js
new file mode 100644
index 0000000..038fe74
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fi-fi.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_fi-fi");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fi_fi");dijit.nls.loading.fi_fi={"loadingState":"Lataus on meneillään...","errorState":"On ilmennyt virhe."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fi-fi.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fi-fi.xd.js
new file mode 100644
index 0000000..1cee152
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fi-fi.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_fi-fi"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.fi_fi"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_fi-fi");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fi_fi");dijit.nls.loading.fi_fi={"loadingState":"Lataus on meneillään...","errorState":"On ilmennyt virhe."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fi.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fi.js
new file mode 100644
index 0000000..e84ab57
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fi.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_fi");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fi");dijit.nls.loading.fi={"loadingState":"Lataus on meneillään...","errorState":"On ilmennyt virhe."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fi.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fi.xd.js
new file mode 100644
index 0000000..1bf6ddc
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fi.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_fi"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.fi"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_fi");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fi");dijit.nls.loading.fi={"loadingState":"Lataus on meneillään...","errorState":"On ilmennyt virhe."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fr-fr.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fr-fr.js
new file mode 100644
index 0000000..4ede3c0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fr-fr.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_fr-fr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fr_fr");dijit.nls.loading.fr_fr={"loadingState":"Chargement...","errorState":"Une erreur est survenue"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fr-fr.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fr-fr.xd.js
new file mode 100644
index 0000000..d7c0458
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fr-fr.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_fr-fr"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.fr_fr"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_fr-fr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fr_fr");dijit.nls.loading.fr_fr={"loadingState":"Chargement...","errorState":"Une erreur est survenue"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fr.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fr.js
new file mode 100644
index 0000000..f001477
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fr.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_fr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fr");dijit.nls.loading.fr={"loadingState":"Chargement...","errorState":"Une erreur est survenue"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fr.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fr.xd.js
new file mode 100644
index 0000000..c33ce90
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_fr.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_fr"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.fr"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_fr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fr");dijit.nls.loading.fr={"loadingState":"Chargement...","errorState":"Une erreur est survenue"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_he-il.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_he-il.js
new file mode 100644
index 0000000..5debfb7
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_he-il.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_he-il");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.he_il");dijit.nls.loading.he_il={"loadingState":"טעינה...‏","errorState":"אירעה שגיאה"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_he-il.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_he-il.xd.js
new file mode 100644
index 0000000..d69d4d6
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_he-il.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_he-il"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.he_il"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_he-il");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.he_il");dijit.nls.loading.he_il={"loadingState":"טעינה...‏","errorState":"אירעה שגיאה"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_he.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_he.js
new file mode 100644
index 0000000..53990c4
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_he.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_he");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.he");dijit.nls.loading.he={"loadingState":"טעינה...‏","errorState":"אירעה שגיאה"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_he.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_he.xd.js
new file mode 100644
index 0000000..9f21096
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_he.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_he"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.he"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_he");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.he");dijit.nls.loading.he={"loadingState":"טעינה...‏","errorState":"אירעה שגיאה"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_hu.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_hu.js
new file mode 100644
index 0000000..08ecc2a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_hu.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_hu");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.hu");dijit.nls.loading.hu={"loadingState":"Betöltés...","errorState":"Sajnálom, hiba történt"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_hu.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_hu.xd.js
new file mode 100644
index 0000000..b658636
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_hu.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_hu"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.hu"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_hu");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.hu");dijit.nls.loading.hu={"loadingState":"Betöltés...","errorState":"Sajnálom, hiba történt"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_it-it.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_it-it.js
new file mode 100644
index 0000000..0ca8255
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_it-it.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_it-it");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.it_it");dijit.nls.loading.it_it={"loadingState":"Caricamento in corso...","errorState":"Si è verificato un errore"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_it-it.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_it-it.xd.js
new file mode 100644
index 0000000..0ec078f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_it-it.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_it-it"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.it_it"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_it-it");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.it_it");dijit.nls.loading.it_it={"loadingState":"Caricamento in corso...","errorState":"Si è verificato un errore"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_it.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_it.js
new file mode 100644
index 0000000..974c6e1
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_it.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_it");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.it");dijit.nls.loading.it={"loadingState":"Caricamento in corso...","errorState":"Si è verificato un errore"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_it.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_it.xd.js
new file mode 100644
index 0000000..1ae2656
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_it.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_it"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.it"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_it");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.it");dijit.nls.loading.it={"loadingState":"Caricamento in corso...","errorState":"Si è verificato un errore"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ja-jp.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ja-jp.js
new file mode 100644
index 0000000..8add310
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ja-jp.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ja-jp");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ja_jp");dijit.nls.loading.ja_jp={"loadingState":"ロード中...","errorState":"エラーが発生しました。"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ja-jp.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ja-jp.xd.js
new file mode 100644
index 0000000..5d84710
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ja-jp.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_ja-jp"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.ja_jp"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_ja-jp");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ja_jp");dijit.nls.loading.ja_jp={"loadingState":"ロード中...","errorState":"エラーが発生しました。"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ja.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ja.js
new file mode 100644
index 0000000..ffe742d
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ja.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ja");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ja");dijit.nls.loading.ja={"loadingState":"ロード中...","errorState":"エラーが発生しました。"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ja.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ja.xd.js
new file mode 100644
index 0000000..02d7580
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ja.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_ja"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.ja"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_ja");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ja");dijit.nls.loading.ja={"loadingState":"ロード中...","errorState":"エラーが発生しました。"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ko-kr.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ko-kr.js
new file mode 100644
index 0000000..5a9298e
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ko-kr.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ko-kr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ko_kr");dijit.nls.loading.ko_kr={"loadingState":"로드 중...","errorState":"죄송합니다. 오류가 발생했습니다."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ko-kr.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ko-kr.xd.js
new file mode 100644
index 0000000..0e6b898
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ko-kr.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_ko-kr"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.ko_kr"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_ko-kr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ko_kr");dijit.nls.loading.ko_kr={"loadingState":"로드 중...","errorState":"죄송합니다. 오류가 발생했습니다."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ko.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ko.js
new file mode 100644
index 0000000..52fa5c1
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ko.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ko");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ko");dijit.nls.loading.ko={"loadingState":"로드 중...","errorState":"죄송합니다. 오류가 발생했습니다."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ko.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ko.xd.js
new file mode 100644
index 0000000..cbdcd02
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ko.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_ko"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.ko"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_ko");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ko");dijit.nls.loading.ko={"loadingState":"로드 중...","errorState":"죄송합니다. 오류가 발생했습니다."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nb.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nb.js
new file mode 100644
index 0000000..0eaef0a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nb.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_nb");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.nb");dijit.nls.loading.nb={"loadingState":"Laster inn...","errorState":"Det oppsto en feil"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nb.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nb.xd.js
new file mode 100644
index 0000000..b7de8c9
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nb.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_nb"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.nb"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_nb");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.nb");dijit.nls.loading.nb={"loadingState":"Laster inn...","errorState":"Det oppsto en feil"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nl-nl.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nl-nl.js
new file mode 100644
index 0000000..98ac8cc
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nl-nl.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_nl-nl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.nl_nl");dijit.nls.loading.nl_nl={"loadingState":"Bezig met laden...","errorState":"Er is een fout opgetreden"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nl-nl.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nl-nl.xd.js
new file mode 100644
index 0000000..010f0d7
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nl-nl.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_nl-nl"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.nl_nl"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_nl-nl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.nl_nl");dijit.nls.loading.nl_nl={"loadingState":"Bezig met laden...","errorState":"Er is een fout opgetreden"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nl.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nl.js
new file mode 100644
index 0000000..af95380
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nl.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_nl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.nl");dijit.nls.loading.nl={"loadingState":"Bezig met laden...","errorState":"Er is een fout opgetreden"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nl.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nl.xd.js
new file mode 100644
index 0000000..1ee55de
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_nl.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_nl"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.nl"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_nl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.nl");dijit.nls.loading.nl={"loadingState":"Bezig met laden...","errorState":"Er is een fout opgetreden"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pl.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pl.js
new file mode 100644
index 0000000..d1ac6b6
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pl.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_pl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pl");dijit.nls.loading.pl={"loadingState":"Ładowanie...","errorState":"Niestety, wystąpił błąd"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pl.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pl.xd.js
new file mode 100644
index 0000000..d9b2513
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pl.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_pl"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.pl"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_pl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pl");dijit.nls.loading.pl={"loadingState":"Ładowanie...","errorState":"Niestety, wystąpił błąd"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt-br.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt-br.js
new file mode 100644
index 0000000..150dff9
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt-br.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_pt-br");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pt_br");dijit.nls.loading.pt_br={"loadingState":"Carregando...","errorState":"Desculpe, ocorreu um erro"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt-br.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt-br.xd.js
new file mode 100644
index 0000000..1a750bc
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt-br.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_pt-br"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.pt_br"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_pt-br");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pt_br");dijit.nls.loading.pt_br={"loadingState":"Carregando...","errorState":"Desculpe, ocorreu um erro"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt-pt.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt-pt.js
new file mode 100644
index 0000000..c50d06b
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt-pt.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_pt-pt");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pt_pt");dijit.nls.loading.pt_pt={"loadingState":"A carregar...","errorState":"Lamentamos, mas ocorreu um erro"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt-pt.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt-pt.xd.js
new file mode 100644
index 0000000..a2cb561
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt-pt.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_pt-pt"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.pt_pt"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_pt-pt");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pt_pt");dijit.nls.loading.pt_pt={"loadingState":"A carregar...","errorState":"Lamentamos, mas ocorreu um erro"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt.js
new file mode 100644
index 0000000..8cadca5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_pt");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pt");dijit.nls.loading.pt={"loadingState":"Carregando...","errorState":"Desculpe, ocorreu um erro"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt.xd.js
new file mode 100644
index 0000000..0a19266
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_pt.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_pt"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.pt"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_pt");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pt");dijit.nls.loading.pt={"loadingState":"Carregando...","errorState":"Desculpe, ocorreu um erro"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ru.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ru.js
new file mode 100644
index 0000000..45ebb10
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ru.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ru");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ru");dijit.nls.loading.ru={"loadingState":"Загрузка...","errorState":"Извините, возникла ошибка"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ru.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ru.xd.js
new file mode 100644
index 0000000..d81a875
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_ru.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_ru"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.ru"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_ru");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ru");dijit.nls.loading.ru={"loadingState":"Загрузка...","errorState":"Извините, возникла ошибка"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sk.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sk.js
new file mode 100644
index 0000000..63a6057
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sk.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_sk");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.sk");dijit.nls.loading.sk={"loadingState":"Zavádzanie...","errorState":"Nastala chyba"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sk.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sk.xd.js
new file mode 100644
index 0000000..a8f089d
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sk.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_sk"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.sk"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_sk");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.sk");dijit.nls.loading.sk={"loadingState":"Zavádzanie...","errorState":"Nastala chyba"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sl.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sl.js
new file mode 100644
index 0000000..8ad9d45
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sl.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_sl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.sl");dijit.nls.loading.sl={"loadingState":"Nalaganje ...","errorState":"Oprostite, prišlo je do napake."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sl.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sl.xd.js
new file mode 100644
index 0000000..1a1d60c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sl.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_sl"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.sl"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_sl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.sl");dijit.nls.loading.sl={"loadingState":"Nalaganje ...","errorState":"Oprostite, prišlo je do napake."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sv.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sv.js
new file mode 100644
index 0000000..7d6bca7
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sv.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_sv");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.sv");dijit.nls.loading.sv={"loadingState":"Läser in...","errorState":"Det uppstod ett fel."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sv.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sv.xd.js
new file mode 100644
index 0000000..7bfd770
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_sv.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_sv"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.sv"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_sv");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.sv");dijit.nls.loading.sv={"loadingState":"Läser in...","errorState":"Det uppstod ett fel."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_th.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_th.js
new file mode 100644
index 0000000..6149c69
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_th.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_th");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.th");dijit.nls.loading.th={"loadingState":"กำลังโหลด...","errorState":"ขออภัย เกิดข้อผิดพลาด"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_th.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_th.xd.js
new file mode 100644
index 0000000..7407419
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_th.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_th"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.th"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_th");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.th");dijit.nls.loading.th={"loadingState":"กำลังโหลด...","errorState":"ขออภัย เกิดข้อผิดพลาด"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_tr.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_tr.js
new file mode 100644
index 0000000..73fbf2b
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_tr.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_tr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.tr");dijit.nls.loading.tr={"loadingState":"Yükleniyor...","errorState":"Üzgünüz, bir hata oluştu"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_tr.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_tr.xd.js
new file mode 100644
index 0000000..f4345a8
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_tr.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_tr"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.tr"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_tr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.tr");dijit.nls.loading.tr={"loadingState":"Yükleniyor...","errorState":"Üzgünüz, bir hata oluştu"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_xx.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_xx.js
new file mode 100644
index 0000000..3cbeb4c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_xx.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_xx");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.xx");dijit.nls.loading.xx={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_xx.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_xx.xd.js
new file mode 100644
index 0000000..f9c15b4
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_xx.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_xx"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.xx"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_xx");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.xx");dijit.nls.loading.xx={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh-cn.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh-cn.js
new file mode 100644
index 0000000..31f1851
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh-cn.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_zh-cn");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.zh_cn");dijit.nls.loading.zh_cn={"loadingState":"正在加载...","errorState":"对不起,发生了错误"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh-cn.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh-cn.xd.js
new file mode 100644
index 0000000..f7a1ebe
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh-cn.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_zh-cn"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.zh_cn"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_zh-cn");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.zh_cn");dijit.nls.loading.zh_cn={"loadingState":"正在加载...","errorState":"对不起,发生了错误"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh-tw.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh-tw.js
new file mode 100644
index 0000000..be7f496
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh-tw.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_zh-tw");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.zh_tw");dijit.nls.loading.zh_tw={"loadingState":"載入中...","errorState":"抱歉,發生錯誤"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh-tw.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh-tw.xd.js
new file mode 100644
index 0000000..69396c2
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh-tw.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_zh-tw"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.zh_tw"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_zh-tw");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.zh_tw");dijit.nls.loading.zh_tw={"loadingState":"載入中...","errorState":"抱歉,發生錯誤"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh.js
new file mode 100644
index 0000000..daae9e8
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_zh");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.zh");dijit.nls.loading.zh={"loadingState":"正在加载...","errorState":"对不起,发生了错误"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh.xd.js
new file mode 100644
index 0000000..915be99
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid.xd_zh.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_zh"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.zh"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_zh");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.zh");dijit.nls.loading.zh={"loadingState":"正在加载...","errorState":"对不起,发生了错误"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_ROOT.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_ROOT.js
new file mode 100644
index 0000000..56bceec
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_ROOT.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ROOT");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ROOT");dijit.nls.loading.ROOT={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_ROOT.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_ROOT.xd.js
new file mode 100644
index 0000000..89e5a64
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_ROOT.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_ROOT"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.ROOT"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_ROOT");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ROOT");dijit.nls.loading.ROOT={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_ar.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_ar.js
new file mode 100644
index 0000000..824ddd2
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_ar.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ar");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ar");dijit.nls.loading.ar={"loadingState":"جاري التحميل...","errorState":"عفوا، حدث خطأ"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_ar.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_ar.xd.js
new file mode 100644
index 0000000..3eb4c2c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_ar.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_ar"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.ar"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_ar");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ar");dijit.nls.loading.ar={"loadingState":"جاري التحميل...","errorState":"عفوا، حدث خطأ"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_ca.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_ca.js
new file mode 100644
index 0000000..a33495f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_ca.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ca");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ca");dijit.nls.loading.ca={"loadingState":"S'està carregant...","errorState":"Ens sap greu. S'ha produït un error."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_ca.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_ca.xd.js
new file mode 100644
index 0000000..5cc8e90
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_ca.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_ca"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.ca"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_ca");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ca");dijit.nls.loading.ca={"loadingState":"S'està carregant...","errorState":"Ens sap greu. S'ha produït un error."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_cs.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_cs.js
new file mode 100644
index 0000000..6a8c6e2
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_cs.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_cs");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.cs");dijit.nls.loading.cs={"loadingState":"Probíhá načítání...","errorState":"Omlouváme se, došlo k chybě"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_cs.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_cs.xd.js
new file mode 100644
index 0000000..5cebf6d
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_cs.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_cs"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.cs"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_cs");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.cs");dijit.nls.loading.cs={"loadingState":"Probíhá načítání...","errorState":"Omlouváme se, došlo k chybě"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_da.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_da.js
new file mode 100644
index 0000000..30968f0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_da.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_da");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.da");dijit.nls.loading.da={"loadingState":"Indlæser...","errorState":"Der er opstået en fejl"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_da.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_da.xd.js
new file mode 100644
index 0000000..29a7443
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_da.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_da"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.da"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_da");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.da");dijit.nls.loading.da={"loadingState":"Indlæser...","errorState":"Der er opstået en fejl"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_de-de.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_de-de.js
new file mode 100644
index 0000000..c2e6862
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_de-de.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_de-de");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.de_de");dijit.nls.loading.de_de={"loadingState":"Wird geladen...","errorState":"Es ist ein Fehler aufgetreten."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_de-de.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_de-de.xd.js
new file mode 100644
index 0000000..3db58fa
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_de-de.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_de-de"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.de_de"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_de-de");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.de_de");dijit.nls.loading.de_de={"loadingState":"Wird geladen...","errorState":"Es ist ein Fehler aufgetreten."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_de.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_de.js
new file mode 100644
index 0000000..7afaf9b
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_de.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_de");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.de");dijit.nls.loading.de={"loadingState":"Wird geladen...","errorState":"Es ist ein Fehler aufgetreten."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_de.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_de.xd.js
new file mode 100644
index 0000000..f4deec7
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_de.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_de"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.de"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_de");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.de");dijit.nls.loading.de={"loadingState":"Wird geladen...","errorState":"Es ist ein Fehler aufgetreten."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_el.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_el.js
new file mode 100644
index 0000000..c5bf528
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_el.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_el");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.el");dijit.nls.loading.el={"loadingState":"Φόρτωση...","errorState":"Σας ζητούμε συγνώμη, παρουσιάστηκε σφάλμα"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_el.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_el.xd.js
new file mode 100644
index 0000000..bd250a0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_el.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_el"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.el"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_el");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.el");dijit.nls.loading.el={"loadingState":"Φόρτωση...","errorState":"Σας ζητούμε συγνώμη, παρουσιάστηκε σφάλμα"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_en-gb.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_en-gb.js
new file mode 100644
index 0000000..7f3b1a0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_en-gb.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_en-gb");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.en_gb");dijit.nls.loading.en_gb={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_en-gb.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_en-gb.xd.js
new file mode 100644
index 0000000..4cc23fe
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_en-gb.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_en-gb"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.en_gb"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_en-gb");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.en_gb");dijit.nls.loading.en_gb={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_en-us.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_en-us.js
new file mode 100644
index 0000000..dfa0bde
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_en-us.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_en-us");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.en_us");dijit.nls.loading.en_us={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_en-us.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_en-us.xd.js
new file mode 100644
index 0000000..fa2eb06
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_en-us.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_en-us"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.en_us"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_en-us");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.en_us");dijit.nls.loading.en_us={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_en.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_en.js
new file mode 100644
index 0000000..f40c9d5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_en.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_en");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.en");dijit.nls.loading.en={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_en.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_en.xd.js
new file mode 100644
index 0000000..9a21666
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_en.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_en"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.en"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_en");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.en");dijit.nls.loading.en={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_es-es.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_es-es.js
new file mode 100644
index 0000000..f875122
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_es-es.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_es-es");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.es_es");dijit.nls.loading.es_es={"loadingState":"Cargando...","errorState":"Lo siento, se ha producido un error"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_es-es.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_es-es.xd.js
new file mode 100644
index 0000000..b83eaf5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_es-es.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_es-es"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.es_es"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_es-es");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.es_es");dijit.nls.loading.es_es={"loadingState":"Cargando...","errorState":"Lo siento, se ha producido un error"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_es.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_es.js
new file mode 100644
index 0000000..3a3970f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_es.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_es");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.es");dijit.nls.loading.es={"loadingState":"Cargando...","errorState":"Lo siento, se ha producido un error"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_es.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_es.xd.js
new file mode 100644
index 0000000..8d5adfa
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_es.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_es"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.es"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_es");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.es");dijit.nls.loading.es={"loadingState":"Cargando...","errorState":"Lo siento, se ha producido un error"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_fi-fi.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_fi-fi.js
new file mode 100644
index 0000000..038fe74
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_fi-fi.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_fi-fi");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fi_fi");dijit.nls.loading.fi_fi={"loadingState":"Lataus on meneillään...","errorState":"On ilmennyt virhe."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_fi-fi.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_fi-fi.xd.js
new file mode 100644
index 0000000..1cee152
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_fi-fi.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_fi-fi"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.fi_fi"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_fi-fi");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fi_fi");dijit.nls.loading.fi_fi={"loadingState":"Lataus on meneillään...","errorState":"On ilmennyt virhe."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_fi.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_fi.js
new file mode 100644
index 0000000..e84ab57
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_fi.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_fi");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fi");dijit.nls.loading.fi={"loadingState":"Lataus on meneillään...","errorState":"On ilmennyt virhe."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_fi.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_fi.xd.js
new file mode 100644
index 0000000..1bf6ddc
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_fi.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_fi"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.fi"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_fi");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fi");dijit.nls.loading.fi={"loadingState":"Lataus on meneillään...","errorState":"On ilmennyt virhe."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_fr-fr.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_fr-fr.js
new file mode 100644
index 0000000..4ede3c0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_fr-fr.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_fr-fr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fr_fr");dijit.nls.loading.fr_fr={"loadingState":"Chargement...","errorState":"Une erreur est survenue"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_fr-fr.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_fr-fr.xd.js
new file mode 100644
index 0000000..d7c0458
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_fr-fr.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_fr-fr"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.fr_fr"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_fr-fr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fr_fr");dijit.nls.loading.fr_fr={"loadingState":"Chargement...","errorState":"Une erreur est survenue"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_fr.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_fr.js
new file mode 100644
index 0000000..f001477
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_fr.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_fr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fr");dijit.nls.loading.fr={"loadingState":"Chargement...","errorState":"Une erreur est survenue"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_fr.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_fr.xd.js
new file mode 100644
index 0000000..c33ce90
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_fr.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_fr"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.fr"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_fr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fr");dijit.nls.loading.fr={"loadingState":"Chargement...","errorState":"Une erreur est survenue"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_he-il.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_he-il.js
new file mode 100644
index 0000000..5debfb7
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_he-il.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_he-il");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.he_il");dijit.nls.loading.he_il={"loadingState":"טעינה...‏","errorState":"אירעה שגיאה"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_he-il.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_he-il.xd.js
new file mode 100644
index 0000000..d69d4d6
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_he-il.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_he-il"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.he_il"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_he-il");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.he_il");dijit.nls.loading.he_il={"loadingState":"טעינה...‏","errorState":"אירעה שגיאה"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_he.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_he.js
new file mode 100644
index 0000000..53990c4
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_he.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_he");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.he");dijit.nls.loading.he={"loadingState":"טעינה...‏","errorState":"אירעה שגיאה"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_he.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_he.xd.js
new file mode 100644
index 0000000..9f21096
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_he.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_he"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.he"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_he");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.he");dijit.nls.loading.he={"loadingState":"טעינה...‏","errorState":"אירעה שגיאה"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_hu.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_hu.js
new file mode 100644
index 0000000..08ecc2a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_hu.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_hu");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.hu");dijit.nls.loading.hu={"loadingState":"Betöltés...","errorState":"Sajnálom, hiba történt"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_hu.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_hu.xd.js
new file mode 100644
index 0000000..b658636
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_hu.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_hu"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.hu"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_hu");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.hu");dijit.nls.loading.hu={"loadingState":"Betöltés...","errorState":"Sajnálom, hiba történt"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_it-it.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_it-it.js
new file mode 100644
index 0000000..0ca8255
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_it-it.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_it-it");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.it_it");dijit.nls.loading.it_it={"loadingState":"Caricamento in corso...","errorState":"Si è verificato un errore"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_it-it.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_it-it.xd.js
new file mode 100644
index 0000000..0ec078f
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_it-it.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_it-it"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.it_it"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_it-it");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.it_it");dijit.nls.loading.it_it={"loadingState":"Caricamento in corso...","errorState":"Si è verificato un errore"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_it.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_it.js
new file mode 100644
index 0000000..974c6e1
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_it.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_it");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.it");dijit.nls.loading.it={"loadingState":"Caricamento in corso...","errorState":"Si è verificato un errore"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_it.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_it.xd.js
new file mode 100644
index 0000000..1ae2656
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_it.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_it"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.it"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_it");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.it");dijit.nls.loading.it={"loadingState":"Caricamento in corso...","errorState":"Si è verificato un errore"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_ja-jp.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_ja-jp.js
new file mode 100644
index 0000000..8add310
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_ja-jp.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ja-jp");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ja_jp");dijit.nls.loading.ja_jp={"loadingState":"ロード中...","errorState":"エラーが発生しました。"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_ja-jp.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_ja-jp.xd.js
new file mode 100644
index 0000000..5d84710
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_ja-jp.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_ja-jp"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.ja_jp"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_ja-jp");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ja_jp");dijit.nls.loading.ja_jp={"loadingState":"ロード中...","errorState":"エラーが発生しました。"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_ja.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_ja.js
new file mode 100644
index 0000000..ffe742d
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_ja.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ja");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ja");dijit.nls.loading.ja={"loadingState":"ロード中...","errorState":"エラーが発生しました。"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_ja.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_ja.xd.js
new file mode 100644
index 0000000..02d7580
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_ja.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_ja"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.ja"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_ja");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ja");dijit.nls.loading.ja={"loadingState":"ロード中...","errorState":"エラーが発生しました。"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_ko-kr.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_ko-kr.js
new file mode 100644
index 0000000..5a9298e
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_ko-kr.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ko-kr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ko_kr");dijit.nls.loading.ko_kr={"loadingState":"로드 중...","errorState":"죄송합니다. 오류가 발생했습니다."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_ko-kr.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_ko-kr.xd.js
new file mode 100644
index 0000000..0e6b898
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_ko-kr.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_ko-kr"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.ko_kr"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_ko-kr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ko_kr");dijit.nls.loading.ko_kr={"loadingState":"로드 중...","errorState":"죄송합니다. 오류가 발생했습니다."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_ko.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_ko.js
new file mode 100644
index 0000000..52fa5c1
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_ko.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ko");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ko");dijit.nls.loading.ko={"loadingState":"로드 중...","errorState":"죄송합니다. 오류가 발생했습니다."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_ko.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_ko.xd.js
new file mode 100644
index 0000000..cbdcd02
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_ko.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_ko"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.ko"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_ko");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ko");dijit.nls.loading.ko={"loadingState":"로드 중...","errorState":"죄송합니다. 오류가 발생했습니다."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_nb.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_nb.js
new file mode 100644
index 0000000..0eaef0a
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_nb.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_nb");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.nb");dijit.nls.loading.nb={"loadingState":"Laster inn...","errorState":"Det oppsto en feil"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_nb.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_nb.xd.js
new file mode 100644
index 0000000..b7de8c9
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_nb.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_nb"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.nb"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_nb");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.nb");dijit.nls.loading.nb={"loadingState":"Laster inn...","errorState":"Det oppsto en feil"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_nl-nl.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_nl-nl.js
new file mode 100644
index 0000000..98ac8cc
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_nl-nl.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_nl-nl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.nl_nl");dijit.nls.loading.nl_nl={"loadingState":"Bezig met laden...","errorState":"Er is een fout opgetreden"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_nl-nl.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_nl-nl.xd.js
new file mode 100644
index 0000000..010f0d7
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_nl-nl.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_nl-nl"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.nl_nl"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_nl-nl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.nl_nl");dijit.nls.loading.nl_nl={"loadingState":"Bezig met laden...","errorState":"Er is een fout opgetreden"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_nl.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_nl.js
new file mode 100644
index 0000000..af95380
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_nl.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_nl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.nl");dijit.nls.loading.nl={"loadingState":"Bezig met laden...","errorState":"Er is een fout opgetreden"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_nl.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_nl.xd.js
new file mode 100644
index 0000000..1ee55de
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_nl.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_nl"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.nl"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_nl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.nl");dijit.nls.loading.nl={"loadingState":"Bezig met laden...","errorState":"Er is een fout opgetreden"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_pl.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_pl.js
new file mode 100644
index 0000000..d1ac6b6
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_pl.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_pl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pl");dijit.nls.loading.pl={"loadingState":"Ładowanie...","errorState":"Niestety, wystąpił błąd"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_pl.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_pl.xd.js
new file mode 100644
index 0000000..d9b2513
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_pl.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_pl"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.pl"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_pl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pl");dijit.nls.loading.pl={"loadingState":"Ładowanie...","errorState":"Niestety, wystąpił błąd"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_pt-br.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_pt-br.js
new file mode 100644
index 0000000..150dff9
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_pt-br.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_pt-br");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pt_br");dijit.nls.loading.pt_br={"loadingState":"Carregando...","errorState":"Desculpe, ocorreu um erro"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_pt-br.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_pt-br.xd.js
new file mode 100644
index 0000000..1a750bc
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_pt-br.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_pt-br"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.pt_br"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_pt-br");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pt_br");dijit.nls.loading.pt_br={"loadingState":"Carregando...","errorState":"Desculpe, ocorreu um erro"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_pt-pt.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_pt-pt.js
new file mode 100644
index 0000000..c50d06b
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_pt-pt.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_pt-pt");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pt_pt");dijit.nls.loading.pt_pt={"loadingState":"A carregar...","errorState":"Lamentamos, mas ocorreu um erro"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_pt-pt.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_pt-pt.xd.js
new file mode 100644
index 0000000..a2cb561
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_pt-pt.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_pt-pt"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.pt_pt"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_pt-pt");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pt_pt");dijit.nls.loading.pt_pt={"loadingState":"A carregar...","errorState":"Lamentamos, mas ocorreu um erro"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_pt.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_pt.js
new file mode 100644
index 0000000..8cadca5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_pt.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_pt");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pt");dijit.nls.loading.pt={"loadingState":"Carregando...","errorState":"Desculpe, ocorreu um erro"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_pt.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_pt.xd.js
new file mode 100644
index 0000000..0a19266
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_pt.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_pt"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.pt"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_pt");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pt");dijit.nls.loading.pt={"loadingState":"Carregando...","errorState":"Desculpe, ocorreu um erro"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_ru.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_ru.js
new file mode 100644
index 0000000..45ebb10
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_ru.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ru");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ru");dijit.nls.loading.ru={"loadingState":"Загрузка...","errorState":"Извините, возникла ошибка"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_ru.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_ru.xd.js
new file mode 100644
index 0000000..d81a875
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_ru.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_ru"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.ru"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_ru");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ru");dijit.nls.loading.ru={"loadingState":"Загрузка...","errorState":"Извините, возникла ошибка"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_sk.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_sk.js
new file mode 100644
index 0000000..63a6057
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_sk.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_sk");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.sk");dijit.nls.loading.sk={"loadingState":"Zavádzanie...","errorState":"Nastala chyba"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_sk.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_sk.xd.js
new file mode 100644
index 0000000..a8f089d
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_sk.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_sk"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.sk"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_sk");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.sk");dijit.nls.loading.sk={"loadingState":"Zavádzanie...","errorState":"Nastala chyba"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_sl.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_sl.js
new file mode 100644
index 0000000..8ad9d45
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_sl.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_sl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.sl");dijit.nls.loading.sl={"loadingState":"Nalaganje ...","errorState":"Oprostite, prišlo je do napake."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_sl.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_sl.xd.js
new file mode 100644
index 0000000..1a1d60c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_sl.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_sl"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.sl"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_sl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.sl");dijit.nls.loading.sl={"loadingState":"Nalaganje ...","errorState":"Oprostite, prišlo je do napake."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_sv.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_sv.js
new file mode 100644
index 0000000..7d6bca7
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_sv.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_sv");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.sv");dijit.nls.loading.sv={"loadingState":"Läser in...","errorState":"Det uppstod ett fel."};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_sv.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_sv.xd.js
new file mode 100644
index 0000000..7bfd770
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_sv.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_sv"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.sv"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_sv");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.sv");dijit.nls.loading.sv={"loadingState":"Läser in...","errorState":"Det uppstod ett fel."};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_th.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_th.js
new file mode 100644
index 0000000..6149c69
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_th.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_th");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.th");dijit.nls.loading.th={"loadingState":"กำลังโหลด...","errorState":"ขออภัย เกิดข้อผิดพลาด"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_th.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_th.xd.js
new file mode 100644
index 0000000..7407419
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_th.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_th"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.th"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_th");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.th");dijit.nls.loading.th={"loadingState":"กำลังโหลด...","errorState":"ขออภัย เกิดข้อผิดพลาด"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_tr.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_tr.js
new file mode 100644
index 0000000..73fbf2b
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_tr.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_tr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.tr");dijit.nls.loading.tr={"loadingState":"Yükleniyor...","errorState":"Üzgünüz, bir hata oluştu"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_tr.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_tr.xd.js
new file mode 100644
index 0000000..f4345a8
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_tr.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_tr"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.tr"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_tr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.tr");dijit.nls.loading.tr={"loadingState":"Yükleniyor...","errorState":"Üzgünüz, bir hata oluştu"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_xx.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_xx.js
new file mode 100644
index 0000000..3cbeb4c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_xx.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_xx");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.xx");dijit.nls.loading.xx={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_xx.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_xx.xd.js
new file mode 100644
index 0000000..f9c15b4
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_xx.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_xx"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.xx"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_xx");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.xx");dijit.nls.loading.xx={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_zh-cn.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_zh-cn.js
new file mode 100644
index 0000000..31f1851
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_zh-cn.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_zh-cn");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.zh_cn");dijit.nls.loading.zh_cn={"loadingState":"正在加载...","errorState":"对不起,发生了错误"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_zh-cn.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_zh-cn.xd.js
new file mode 100644
index 0000000..f7a1ebe
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_zh-cn.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_zh-cn"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.zh_cn"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_zh-cn");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.zh_cn");dijit.nls.loading.zh_cn={"loadingState":"正在加载...","errorState":"对不起,发生了错误"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_zh-tw.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_zh-tw.js
new file mode 100644
index 0000000..be7f496
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_zh-tw.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_zh-tw");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.zh_tw");dijit.nls.loading.zh_tw={"loadingState":"載入中...","errorState":"抱歉,發生錯誤"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_zh-tw.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_zh-tw.xd.js
new file mode 100644
index 0000000..69396c2
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_zh-tw.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_zh-tw"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.zh_tw"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_zh-tw");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.zh_tw");dijit.nls.loading.zh_tw={"loadingState":"載入中...","errorState":"抱歉,發生錯誤"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_zh.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_zh.js
new file mode 100644
index 0000000..daae9e8
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_zh.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_zh");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.zh");dijit.nls.loading.zh={"loadingState":"正在加载...","errorState":"对不起,发生了错误"};
diff --git a/js/dojo-1.6/dojox/grid/nls/DataGrid_zh.xd.js b/js/dojo-1.6/dojox/grid/nls/DataGrid_zh.xd.js
new file mode 100644
index 0000000..915be99
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/nls/DataGrid_zh.xd.js
@@ -0,0 +1,7 @@
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.nls.DataGrid_zh"],
+["provide", "dijit.nls.loading"],
+["provide", "dijit.nls.loading.zh"]],
+defineResource: function(dojo, dijit, dojox){dojo.provide("dojox.grid.nls.DataGrid_zh");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.zh");dijit.nls.loading.zh={"loadingState":"正在加载...","errorState":"对不起,发生了错误"};
+
+}};}); \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/resources/Expando.html b/js/dojo-1.6/dojox/grid/resources/Expando.html
new file mode 100644
index 0000000..c7e7c22
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/Expando.html
@@ -0,0 +1,5 @@
+<div class="dojoxGridExpando"
+ ><div class="dojoxGridExpandoNode" dojoAttachEvent="onclick:onToggle"
+ ><div class="dojoxGridExpandoNodeInner" dojoAttachPoint="expandoInner"></div
+ ></div
+></div>
diff --git a/js/dojo-1.6/dojox/grid/resources/Grid.css b/js/dojo-1.6/dojox/grid/resources/Grid.css
new file mode 100644
index 0000000..037d906
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/Grid.css
@@ -0,0 +1,415 @@
+.dojoxGrid {
+ position: relative;
+ background-color: #EBEADB;
+ font-family: Geneva, Arial, Helvetica, sans-serif;
+ -moz-outline-style: none;
+ outline: none;
+ overflow: hidden;
+ height: 0;
+}
+
+.dojoxGrid table {
+ padding: 0;
+}
+
+.dojoxGrid td {
+ -moz-outline: none;
+}
+
+/* master header */
+
+.dojoxGridMasterHeader {
+ position: relative;
+}
+
+/* master view */
+
+.dojoxGridMasterView {
+ position: relative;
+}
+
+/* master messages */
+
+.dojoxGridMasterMessages {
+ position: relative;
+ padding: 1em;
+ text-align: center;
+ background-color: white;
+}
+
+/* views */
+
+.dojoxGridView {
+ position: absolute;
+ overflow: hidden;
+}
+
+/* header */
+
+.dojoxGridHeader {
+ position: absolute;
+ overflow: hidden;
+ cursor: default;
+}
+
+.dojoxGridHeader {
+ background-color: #E8E1CF;
+}
+
+.dojoxGridHeader table {
+ text-align: center;
+}
+
+.dojoxGridHeader .dojoxGridCell {
+ border: 1px solid;
+ border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+ background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+ padding-bottom: 2px;
+}
+
+.dojoxGridHeader .dojoxGridCellOver {
+ background-image: none;
+ background-color: white;
+ border-bottom-color: #FEBE47;
+ margin-bottom: 0;
+ padding-bottom: 0;
+ border-bottom-width: 3px;
+}
+
+.dojoxGridHeader .dojoxGridCellFocus {
+ border: 1px dashed blue;
+}
+
+.dojoxGridHeader.dojoxGridCellFocus.dojoxGridCellOver {
+ background-image: none;
+ background-color: white;
+ border-bottom-color: #FEBE47;
+ margin-bottom: 0;
+ padding-bottom: 0;
+ border-bottom-width: 3px;
+}
+.dojoxGridArrowButtonNode {
+ display: none;
+ padding-left: 16px;
+}
+.dojoxGridArrowButtonChar {
+ display:inline;
+}
+
+/* Need to explicitly define how to treat hovering over the arrow on IE */
+.dojoxGridArrowButtonNode:hover {
+ cursor: default;
+}
+.dojoxGridArrowButtonChar:hover {
+ cursor: default;
+}
+.dojoxGridSortUp:hover {
+ cursor: default;
+}
+.dojoxGridSortDown:hover {
+ cursor: default;
+}
+
+.dijit_a11y .dojoxGridArrowButtonChar {
+ display:inline !important;
+}
+
+/* content */
+
+.dojoxGridScrollbox {
+ position: relative;
+ overflow: auto;
+ background-color: white;
+ width: 100%;
+}
+
+.dojoxGridContent {
+ position: relative;
+ overflow: hidden;
+ -moz-outline-style: none;
+ outline: none;
+}
+
+/* rowbar */
+
+.dojoxGridRowbar {
+ border: 1px solid;
+ border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+ border-top: none;
+ background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+}
+
+.dojoxGridRowbarInner {
+ border-top: 1px solid #F6F4EB;
+}
+
+.dojoxGridRowbarOver {
+ background-image: none;
+ background-color: white;
+ border-top-color: #FEBE47;
+ border-bottom-color: #FEBE47;
+}
+
+.dojoxGridRowbarSelected {
+ background-color: #D9E8F9;
+}
+
+/* rows */
+
+.dojoxGridRow {
+ position: relative;
+ width: 9000em;
+}
+
+.dojoxGridRow {
+ /*border: 1px solid #E8E4D8;*/
+ border: 1px solid #E8E4D8;
+ border-color: #F8F7F1;
+ /*padding: 0 0 1px 0;*/
+ border-left: none;
+ border-right: none;
+ background-color: white;
+ border-top: none;
+}
+
+.dojoxGridRowOver {
+ border-top-color: #FEBE47;
+ border-bottom-color: #FEBE47;
+ /*border-bottom-width: 2px;
+ padding-bottom: 0;*/
+ /*background-color: #FFDD9D;*/
+ /*background-color: #FDFDFD;*/
+}
+
+.dojoxGridRowOdd {
+ background-color: #FFFDF3;
+ /*background-color: #F9F7E8;*/
+}
+
+.dojoxGridRowSelected {
+ background-color: #D9E8F9;
+}
+
+.dojoxGridRowTable {
+ table-layout: fixed;
+ width: 0;
+ empty-cells: show;
+}
+.dj_ie .dojoxGridRowTable {
+ border-collapse: collapse;
+}
+
+.dojoxGridInvisible {
+ visibility: hidden;
+}
+
+.Xdojo-ie .dojoxGridInvisible {
+ display: none;
+}
+
+.dojoxGridInvisible td, .dojoxGridHeader .dojoxGridInvisible td {
+ border-top-width: 0;
+ border-bottom-width: 0;
+ padding-top: 0;
+ padding-bottom: 0;
+ height: 0;
+ overflow: hidden;
+}
+
+/* cells */
+
+.dojoxGridCell {
+ border: 1px solid;
+ border-color: #EBEADB;
+ border-right-color: #D5CDB5;
+ padding: 3px 3px 3px 3px;
+ text-align: left;
+ overflow: hidden;
+}
+
+.dojoxGridCellFocus {
+ border: 1px dashed blue;
+}
+
+.dojoxGridCellOver {
+ border: 1px dotted #FEBE47;
+}
+
+.dojoxGridCellFocus.dojoxGridCellOver {
+ border: 1px dashed green;
+}
+
+/* editing */
+
+.dojoxGridRowEditing td {
+ background-color: #F4FFF4;
+}
+
+.dojoxGridRow-inserting td {
+ background-color: #F4FFF4;
+}
+.dojoxGridRow-inflight td {
+ background-color: #F2F7B7;
+}
+.dojoxGridRow-error td {
+ background-color: #F8B8B6;
+}
+
+.dojoxGridInput, .dojoxGridSelect, .dojoxGridTextarea {
+ margin: 0;
+ padding: 0;
+ border-style: none;
+ width: 100%;
+ font-size: 100%;
+ font-family: inherit;
+}
+
+.dojoxGridHiddenFocus {
+ position: absolute;
+ top: -1000px;
+ height: 0;
+ width: 0;
+}
+
+.dijit_a11y .dojoxGridRowbarSelected {
+ border-top: 1px solid white;
+ border-bottom: 1px dashed black;
+ border-top: 0;
+ background: none;
+}
+
+.dijit_a11y .dojoxGridRowbarSelected .dojoxGridRowbarInner {
+ border: 0;
+ border-top: 1px solid white;
+}
+
+.dijit_a11y .dojoxGridRowSelected {
+ border: 1px solid black !important;
+}
+
+/* Drag and Drop */
+.dojoxGridDndAvatar {
+ font-size: 100%;
+}
+.dojoxGrid .dojoDndItemBefore {
+ border-left-color: red;
+}
+.dojoxGrid .dojoDndItemAfter {
+ border-right-color: red;
+}
+.dijit_a11y .dojoDndItemBefore {
+ border-left: double;
+}
+.dijit_a11y .dojoDndItemAfter {
+ border-right: double;
+}
+.dojoxGridDndAvatarItem td {
+ border: 1px solid;
+ border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+ background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+ padding: 0pt;
+ margin: 0pt;
+}
+.dojoxGridDndAvatarItem td.dojoxGridDndAvatarItemImage {
+ border: 0;
+ border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+ background-color: transparent;
+ padding: 3px;
+ padding-bottom: 2px;
+ margin: 0;
+}
+.dojoDndMove .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+ background-image: url(../../../dojo/resources/images/dndNoMove.png);
+ background-repeat: no-repeat;
+ background-position: center center;
+}
+.dojoDndCopy .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+ background-image: url(../../../dojo/resources/images/dndNoCopy.png);
+ background-repeat: no-repeat;
+ background-position: center center;
+}
+.dojoDndMove .dojoDndAvatarCanDrop .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+ background-image: url(../../../dojo/resources/images/dndMove.png);
+ background-repeat: no-repeat;
+ background-position: center center;
+}
+.dojoDndCopy .dojoDndAvatarCanDrop .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+ background-image: url(../../../dojo/resources/images/dndCopy.png);
+ background-repeat: no-repeat;
+ background-position: center center;
+}
+
+.dojoxGridColPlaceBottom {
+ background: transparent url(images/grid_sort_up.gif) no-repeat scroll left top;
+}
+.dojoxGridColPlaceTop {
+ background: transparent url(images/grid_sort_down.gif) no-repeat scroll left top;
+}
+
+.dojoxGridColPlaceTop, .dojoxGridColPlaceBottom {
+ font-size:1px;
+ height:6px;
+ z-index:10000;
+ top:0;
+ overflow:hidden;
+ position:absolute;
+ line-height:1px;
+ width:8px;
+}
+.dojoxGridResizeColLine {
+ width: 1px;
+ background-color: #777;
+ position: absolute;
+ cursor: col-resize;
+ z-index:10000;
+}
+.dojoxGridColNoResize,
+.dojoxGridColNoResize .dojoDndItemOver {
+ cursor: not-allowed !important;
+}
+.dojoxGridColResize,
+.dojoxGridColResize .dojoDndItemOver,
+.dojoxGridColumnResizing,
+.dojoxGridColumnResizing .dojoDndItemOver,
+.dojoxGridColumnResizing .dojoxGridHeader {
+ cursor: col-resize !important;
+}
+
+.dojoxGridColPlaceBottom {
+ background: transparent url(images/grid_sort_up.gif) no-repeat scroll left top;
+}
+.dojoxGridColPlaceTop {
+ background: transparent url(images/grid_sort_down.gif) no-repeat scroll left top;
+}
+
+.dojoxGridColPlaceTop, .dojoxGridColPlaceBottom {
+ font-size:1px;
+ height:6px;
+ z-index:10000;
+ top:0;
+ overflow:hidden;
+ position:absolute;
+ line-height:1px;
+ width:8px;
+}
+.dojoxGridResizeColLine {
+ width: 1px;
+ background-color: #777;
+ position: absolute;
+}
+
+/* Tree Grid */
+.dojoxGridExpandoCell {
+ vertical-align: middle;
+}
+.dojoxGridSummarySpan {
+ visibility: hidden;
+}
+.dojoxGridSummaryRow .dojoxGridSummarySpan,
+.dojoxGridRowCollapsed .dojoxGridSummarySpan {
+ visibility: visible;
+}
+.dojoxGridNoChildren .dojoxGridExpando {
+ visibility: hidden !important;
+ width: 0px !important;
+} \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/resources/Grid_rtl.css b/js/dojo-1.6/dojox/grid/resources/Grid_rtl.css
new file mode 100644
index 0000000..77d2dd5
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/Grid_rtl.css
@@ -0,0 +1,15 @@
+.dj_ie .dojoxGridRtl .dojoxGridHeader table {
+ float:none;
+}
+
+.dojoxGridRtl .dojoxGridCell {
+ text-align:right;
+}
+
+.dj_ie8 .dojoxGridRtl .dojoxGridCell {
+ border-left: none;
+}
+
+.dojoxGridRtl .dojoxGridArrowButtonNode {
+ float:left;
+} \ No newline at end of file
diff --git a/js/dojo-1.6/dojox/grid/resources/View.html b/js/dojo-1.6/dojox/grid/resources/View.html
new file mode 100644
index 0000000..578b705
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/View.html
@@ -0,0 +1,12 @@
+<div class="dojoxGridView" role="presentation">
+ <div class="dojoxGridHeader" dojoAttachPoint="headerNode" role="presentation">
+ <div dojoAttachPoint="headerNodeContainer" style="width:9000em" role="presentation">
+ <div dojoAttachPoint="headerContentNode" role="row"></div>
+ </div>
+ </div>
+ <input type="checkbox" class="dojoxGridHiddenFocus" dojoAttachPoint="hiddenFocusNode" role="presentation" />
+ <input type="checkbox" class="dojoxGridHiddenFocus" role="presentation" />
+ <div class="dojoxGridScrollbox" dojoAttachPoint="scrollboxNode" role="presentation">
+ <div class="dojoxGridContent" dojoAttachPoint="contentNode" hidefocus="hidefocus" role="presentation"></div>
+ </div>
+</div>
diff --git a/js/dojo-1.6/dojox/grid/resources/_Grid.html b/js/dojo-1.6/dojox/grid/resources/_Grid.html
new file mode 100644
index 0000000..2db90e1
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/_Grid.html
@@ -0,0 +1,6 @@
+<div hidefocus="hidefocus" role="grid" dojoAttachEvent="onmouseout:_mouseOut">
+ <div class="dojoxGridMasterHeader" dojoAttachPoint="viewsHeaderNode" role="presentation"></div>
+ <div class="dojoxGridMasterView" dojoAttachPoint="viewsNode" role="presentation"></div>
+ <div class="dojoxGridMasterMessages" style="display: none;" dojoAttachPoint="messagesNode"></div>
+ <span dojoAttachPoint="lastFocusNode" tabindex="0"></span>
+</div>
diff --git a/js/dojo-1.6/dojox/grid/resources/claroGrid.css b/js/dojo-1.6/dojox/grid/resources/claroGrid.css
new file mode 100644
index 0000000..867a765
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/claroGrid.css
@@ -0,0 +1,283 @@
+/* Claro styles for DataGrid */
+@import url("Grid.css");
+
+.claro .dojoxGrid {
+ margin:0px;
+ padding:0px;
+ border-collapse:collapse;
+ background-color:#fff;
+}
+/* messages */
+.claro .dojoxGridMasterMessages {
+ background-color: #fefefe;
+}
+.claro .dojoxGridLoading,
+.claro .dojoxGridError {
+ background-position:left center;
+ background-repeat: no-repeat;
+ padding-left:25px;
+}
+.claro .dojoxGridLoading {
+ background-image:url("../../../dijit/themes/claro/images/loadingAnimation.gif");
+}
+.claro .dojoxGridError {
+ background-image: url('../../../dijit/icons/images/commonIconsObjActEnabled.png');
+ background-position: -496px;
+ width: 16px;
+ height: 16px;
+}
+
+/* header */
+.claro .dojoxGridHeader {
+ background-color:#FFF;
+}
+.claro .dojoxGridHeader .dojoxGridCell {
+ background:url("images/header.png") #e5edf4 repeat-x top;
+ border-style:solid;
+ border-width:1px;
+ border-color:#BCBCBC #BCBCBC #BCBCBC transparent;
+}
+.dj_ie6 .claro .dojoxGridHeader .dojoxGridCell {
+ border-color:#BCBCBC #BCBCBC #BCBCBC #e5edf4;
+}
+
+/* header sorting arrow */
+.claro .dojoxGridSortNode {
+ background:url("images/header_shadow.png") #e5edf4 repeat-x bottom;
+ text-decoration:none;
+ display:block;
+ padding:4px 6px 5px 6px;
+ border:1px solid #e0eefb;
+}
+.dj_ie6 .claro .dojoxGridSortNode {
+ background-image:none;
+}
+.claro .dojoxGridCellOver .dojoxGridSortNode {
+ background-color:#9dcfff;
+}
+.claro .dojoxGridArrowButtonChar {
+ display:none;
+ float:right;
+}
+.claro .dojoxGridArrowButtonNode {
+ background:transparent url("../../../dijit/themes/claro/images/spriteArrows.png") no-repeat scroll left center;
+ display:block;
+ float:right;
+ height:1em;
+ margin:2px 4px 0 5px;
+ padding-left:0;
+ width:7px;
+}
+.claro .dojoxGridSortUp .dojoxGridArrowButtonNode {
+ background-position:-21px 50%;
+}
+
+/* header rows */
+.dj_ie .claro .dojoxGridHeader .dojoxGridRowTable {
+ border-collapse:separate;
+}
+
+/* Grid view content */
+.claro .dojoxGridScrollbox {
+ background-color: #fefefe;
+}
+
+/* rowbar - row headers */
+.claro .dojoxGridRowbar {
+ background:url("images/header.png") #e5edf4 repeat-x top;
+ border:none;
+ border-right:1px solid #BCBCBC;
+}
+.claro .dojoxGridRowbarTable {
+ background:transparent url("images/header_shadow.png") repeat-x scroll center bottom;
+}
+.dj_ie6 .claro .dojoxGridRowbar,
+.dj_ie6 .claro .dojoxGridRowbarTable {
+ background-image:none;
+}
+.claro .dojoxGridRowbarInner {
+ border:none;
+ border-bottom:1px solid #ccc;
+}
+.claro .dojoxGridRowbarOver .dojoxGridRowbarTable {
+ background-color:#abd5fd;
+}
+.claro .dojoxGridRowBarActive .dojoxGridRowbarTable {
+ background-color:#91c9fe;
+}
+.claro .dojoxGridRowbarSelected {
+ background-color:#abd5fd;
+ border-right:1px solid #ccc;
+}
+
+/* rows */
+.claro .dojoxGridRow {
+ border:none;
+ background-color:#fff;
+}
+.dj_ie .claro .dojoxGridMasterView .dojoxGridRowTable {
+ border-collapse:separate;/*IE, separate is must to show the border of tr and td*/
+}
+.claro .dojoxGridRowTable tr {
+ background:url("images/row_back.png") #fff repeat-x;
+}
+.claro .dojoxGridRowOdd .dojoxGridRowTable tr {
+ background-color:#f7fcff;
+}
+.claro .dojoxGridRowSelected .dojoxGridRowTable tr {
+ background-color:#cee6fa;
+}
+
+/* cells */
+.claro .dojoxGridCell {
+ padding:0px;
+ border:1px solid transparent;
+}
+.dj_ie6 .claro .dojoxGridCell {
+ border-color:#fff
+}
+.dj_ie6 .claro .dojoxGridRowOdd .dojoxGridCell {
+ border-left-color:#f4f9fd;
+ border-right-color:#f4f9fd;
+}
+.dj_ie6 .claro .dojoxGridRowSelected .dojoxGridCell {
+ border-left-color:#d3e9fb;
+ border-right-color:#d3e9fb;
+}
+.claro .dojoxGridRowSelected .dojoxGridCell {
+ border-top:1px solid #BFD6EB;
+ border-bottom:1px solid #BFD6EB;
+}
+.claro .dojoxGridCellFocus {
+ border:1px dashed darkblue !important;
+}
+.claro .dojoxGridCellContent {
+ padding:4px 6px 4px 6px;
+}
+
+/* Single Affordance Hover Effect */
+.claro .dojoxGridRowOver .dojoxGridCell {
+ background:url("images/row_back.png") #ABD6FF repeat-x;
+ border-top:1px solid #769DC0;
+ border-bottom:1px solid #769DC0;
+}
+.dj_ie6 .claro .dojoxGridRowOver .dojoxGridCell,
+.dj_ie7 .claro .dojoxGridRowOver .dojoxGridCell {
+ border-left:1px solid #ABD6FF;
+ border-right:1px solid #ABD6FF;
+}
+.claro .dojoxGridRowActive .dojoxGridCell {
+ background:url("images/td_button_down.png") #7DBEFA repeat-x;
+}
+.dj_ie6 .claro .dojoxGridRowActive .dojoxGridCell,
+.dj_ie7 .claro .dojoxGridRowActive .dojoxGridCell {
+ border-left:1px solid #7DBEFA;
+ border-right:1px solid #7DBEFA;
+}
+
+/* Double Affordance Hover Effect */
+.claro .dojoxGridDoubleAffordance .dojoxGridRowOver .dojoxGridCellOver {
+ border:solid 1px #769dc0;
+ background-color:#93cafe;
+ border-collapse:separate;/*FF*/
+}
+.claro .dojoxGridDoubleAffordance .dojoxGridRowActive .dojoxGridCell{
+ background-image:url("images/row_back.png");
+}
+.claro .dojoxGridDoubleAffordance .dojoxGridRowActive .dojoxGridCellActive {
+ background:url("images/td_button_down.png") #93cafe repeat-x;
+}
+.dj_ie6 .claro .dojoxGridCell {
+ background-image:none !important;
+}
+
+/* editing */
+.claro .dojoxGridRowEditing td {
+ /* background-color: #F4FFF4; */
+ background-color: #cee6fa;
+ /* padding: 0px 3px 0px 3px; */
+}
+.claro .dojoxGridRow-inserting td {
+ background-color: #F4FFF4;
+}
+.claro .dojoxGridRow-inflight td {
+ background-color: #F2F7B7;
+}
+.claro .dojoxGridRow-error td {
+ background-color: #F8B8B6;
+}
+
+/* Drag and Drop */
+.claro .dojoxGrid .dojoDndItemBefore {
+ border-left-color: #3559ac;
+}
+.claro .dojoxGrid .dojoDndItemAfter {
+ border-right-color: #3559ac;
+}
+
+/* Tree Grid */
+.claro .dojoxGridExpando {
+ float: left;
+ height: 18px;
+ width: 18px;
+ text-align: center;
+ margin-top: -3px;
+}
+.dijitRtl .claro .dojoxGridExpando {
+ float: right;
+}
+.claro .dojoxGridExpandoCell {
+ padding-top: 5px;
+ background-position: left top !important;
+}
+.claro .dojoxGridExpandoNode {
+ background-image: url('../../../dijit/themes/claro/images/treeExpandImages.png');
+ width: 16px;
+ height: 16px;
+ background-position: 1px 0px; /* for closed state */
+}
+.dj_ie6 .claro .dojoxGridExpandoNode {
+ background-image: url('../../../dijit/themes/claro/images/treeExpandImages8bit.png');
+}
+.claro .dojoxGridRowOver .dojoxGridExpandoNode {
+ background-position: -17px 0px;
+}
+.claro .dojoxGridExpandoOpened .dojoxGridExpandoNode {
+ background-position: -35px 0px;
+}
+.claro .dojoxGridRowOver .dojoxGridExpandoOpened .dojoxGridExpandoNode {
+ background-position: -53px 0px;
+}
+.claro .dojoxGridExpandoLoading .dojoxGridExpandoNode {
+ background-image: url('../../../dijit/themes/claro/images/loadingAnimation.gif');
+}
+.claro .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpando {
+ visibility: visible !important;
+ width: 18px !important;
+}
+.claro .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode,
+.dj_ie6 .claro .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode {
+ background-image:none;
+}
+.claro .dojoxGridExpandoNodeInner {
+ visibility: hidden;
+}
+.dijit_a11y .dojoxGridExpandoNodeInner {
+ visibility: visible;
+}
+
+.claro .dojoxGridSummaryRow .dojoxGridCell {
+ border:1px solid transparent;
+}
+.dj_ie6 .claro .dojoxGridSummaryRow .dojoxGridCell {
+ border-color:#fff
+}
+.claro tr.dojoxGridSubRowAlt {
+ background-color:#f4f9fd;
+}
+.claro .dojoxGridRowOdd tr.dojoxGridSubRowAlt {
+ background-color:#fff;
+}
+.claro .dojoxGridRow .dojoxGridRowTable tr.dojoxGridRowSelected {
+ background-color:#cee6fa;
+}
diff --git a/js/dojo-1.6/dojox/grid/resources/images/grid_dx_gradient.gif b/js/dojo-1.6/dojox/grid/resources/images/grid_dx_gradient.gif
new file mode 100644
index 0000000..57f67ba
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/images/grid_dx_gradient.gif
Binary files differ
diff --git a/js/dojo-1.6/dojox/grid/resources/images/grid_sort_down.gif b/js/dojo-1.6/dojox/grid/resources/images/grid_sort_down.gif
new file mode 100644
index 0000000..7a73f82
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/images/grid_sort_down.gif
Binary files differ
diff --git a/js/dojo-1.6/dojox/grid/resources/images/grid_sort_up.gif b/js/dojo-1.6/dojox/grid/resources/images/grid_sort_up.gif
new file mode 100644
index 0000000..9452da0
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/images/grid_sort_up.gif
Binary files differ
diff --git a/js/dojo-1.6/dojox/grid/resources/images/header.png b/js/dojo-1.6/dojox/grid/resources/images/header.png
new file mode 100644
index 0000000..aa3e5ba
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/images/header.png
Binary files differ
diff --git a/js/dojo-1.6/dojox/grid/resources/images/header_shadow.png b/js/dojo-1.6/dojox/grid/resources/images/header_shadow.png
new file mode 100644
index 0000000..59b2c83
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/images/header_shadow.png
Binary files differ
diff --git a/js/dojo-1.6/dojox/grid/resources/images/row_back.png b/js/dojo-1.6/dojox/grid/resources/images/row_back.png
new file mode 100644
index 0000000..643db07
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/images/row_back.png
Binary files differ
diff --git a/js/dojo-1.6/dojox/grid/resources/images/tabEnabled_rotated.png b/js/dojo-1.6/dojox/grid/resources/images/tabEnabled_rotated.png
new file mode 100644
index 0000000..e326abd
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/images/tabEnabled_rotated.png
Binary files differ
diff --git a/js/dojo-1.6/dojox/grid/resources/images/tabHover_rotated.png b/js/dojo-1.6/dojox/grid/resources/images/tabHover_rotated.png
new file mode 100644
index 0000000..1a30e10
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/images/tabHover_rotated.png
Binary files differ
diff --git a/js/dojo-1.6/dojox/grid/resources/images/td_button_down.png b/js/dojo-1.6/dojox/grid/resources/images/td_button_down.png
new file mode 100644
index 0000000..ab27e3e
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/images/td_button_down.png
Binary files differ
diff --git a/js/dojo-1.6/dojox/grid/resources/nihiloGrid.css b/js/dojo-1.6/dojox/grid/resources/nihiloGrid.css
new file mode 100644
index 0000000..4fc1bcc
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/nihiloGrid.css
@@ -0,0 +1,237 @@
+@import url("Grid.css");
+
+.nihilo .dojoxGrid {
+ background-color: #e9e9e9;
+ font-size: 0.85em; /* inherit font-family from dojo.css */
+}
+
+/* master messages */
+
+.nihilo .dojoxGridMasterMessages {
+ background-color: #fefefe;
+}
+
+/* header */
+
+.nihilo .dojoxGridHeader {
+ background-color: #e9e9e9;
+}
+
+.nihilo .dojoxGridHeader .dojoxGridCell {
+ border-width: 1px;
+ padding-bottom: 0px;
+ border-color: transparent #ACA899 #919191 transparent;
+ background: url(../../../dijit/themes/nihilo/images/titleBar.png) #e9e9e9 repeat-x top;
+ color: #000 !important;
+}
+
+.nihilo .dojoxGridHeader .dojoxGridCellOver {
+ background: url(../../../dijit/themes/nihilo/images/titleBarActive.png) #e9e9e9 repeat-x top;
+}
+
+.nihilo .dojoxGridHeader .dojoxGridCellFocus {
+ border-color: #ACA899 #919191;
+ border-style: dashed;
+}
+
+.nihilo .dojoxGridArrowButtonChar {
+ float: right;
+ display: none;
+}
+.nihilo .dojoxGridArrowButtonNode {
+ display: block !important;
+ padding-left: 0px;
+ float: right;
+ background:url("../../../dijit/themes/nihilo/images/spriteArrows.png") left center no-repeat;
+ width: 11px;
+ height: 1em;
+ margin-top: 1px;
+}
+.dj_ie6 .nihilo .dojoxGridArrowButtonNode {
+ background-image:url("../../../dijit/themes/nihilo/images/spriteArrows.gif");
+ margin-left: 0px;
+}
+
+.nihilo .dojoxGridSortUp .dojoxGridArrowButtonNode {
+ background-position: -21px;
+}
+.dijit_a11y .nihilo .dojoxGridArrowButtonNode {
+ display: none !important;
+}
+
+/* content */
+
+.nihilo .dojoxGridScrollbox {
+ background-color: #fefefe;
+}
+
+/* rowbar */
+
+.nihilo .dojoxGridRowbar {
+ border: none;
+ background: url(../../../dijit/themes/nihilo/images/titleBar.png) #e9e9e9 repeat-y right;
+ border-right: 1px solid #ccc;
+ padding: 0px;
+}
+
+.nihilo .dojoxGridRowbarInner {
+ border: none;
+ border-bottom: 1px solid #ccc;
+}
+
+.nihilo .dojoxGridRowbarOver {
+ background: url(../../../dijit/themes/nihilo/images/titleBarActive.png) #e9e9e9 repeat-y right;
+}
+
+.nihilo .dojoxGridRowbarSelected {
+ background: url(../../../dijit/themes/nihilo/images/titleBar.png) #D9E8F9 no-repeat center;
+ border-right: 1px solid #ccc;
+}
+
+/* rows */
+
+.nihilo .dojoxGridRow {
+ border: none;
+ background-color: white;
+}
+
+.nihilo .dojoxGridRowOver {
+ border-top-color: #ccc;
+ border-bottom-color: #ccc;
+}
+
+.nihilo .dojoxGridRowOver .dojoxGridCell {
+ background-color: #ffe284;
+}
+
+.nihilo .dojoxGridRowOdd {
+ background-color: #f2f5f9;
+}
+
+.nihilo .dojoxGridRowSelected {
+ background-color: #aec7e3;
+}
+
+.dijit_a11y .nihilo .dojoxGridRowSelected {
+ background-color: #aec7e3;
+ border-style: solid;
+}
+
+/* cells */
+
+.nihilo .dojoxGridCell {
+ border: 1px dotted #D5CDB5;
+ border-left-color: transparent;
+ border-top-color: transparent;
+}
+
+.dj_ff2 .nihilo .dojoxGridCell {
+ border-left-width: 0px;
+ border-top-width: 0px;
+}
+
+.dj_ie6 .nihilo .dojoxGridCell {
+ border: 1px solid white;
+ border-right: 1px solid #D5CDB5;
+}
+
+.nihilo .dojoxGridCellFocus {
+ border: 1px dashed darkblue;
+}
+
+.nihilo .dojoxGridCellOver {
+ border: 1px dotted #a6a6a6;
+}
+
+.nihilo .dojoxGridCellFocus.dojoxGridCellOver {
+ border: 1px dashed darkblue;
+}
+
+/* editing */
+
+/* FIXME: these colors are off! */
+.nihilo .dojoxGridRowEditing td {
+ /* background-color: #F4FFF4; */
+ background-color: #ffe284;
+ /* padding: 0px 3px 0px 3px; */
+}
+
+.nihilo .dojoxGridRow-inserting td {
+ background-color: #F4FFF4;
+}
+.nihilo .dojoxGridRow-inflight td {
+ background-color: #F2F7B7;
+}
+.nihilo .dojoxGridRow-error td {
+ background-color: #F8B8B6;
+}
+
+/* Drag and Drop */
+
+.nihilo .dojoxGrid .dojoDndItemBefore {
+ border-left-color: #ffe284;
+}
+.nihilo .dojoxGrid .dojoDndItemAfter {
+ border-right-color: #ffe284;
+}
+
+
+/* Tree Grid */
+.nihilo .dojoxGridExpando {
+ float: left;
+ height: 18px;
+ width: 18px;
+ text-align: center;
+ margin-top: -3px;
+}
+.dijitRtl .nihilo .dojoxGridExpando {
+ float: right;
+}
+.nihilo .dojoxGridExpandoCell {
+ padding-top: 5px;
+}
+.nihilo .dojoxGridExpandoNode {
+ height: 18px;
+ background-image: url('../../../dijit/themes/nihilo/images/spriteTree.gif');
+}
+.nihilo .dojoxGridExpandoOpened .dojoxGridExpandoNode {
+ background: url('../../../dijit/themes/nihilo/images/spriteTree.gif') no-repeat -18px top;
+}
+.nihilo .dojoxGridExpandoLoading .dojoxGridExpandoNode {
+ background: url('../../../dijit/themes/nihilo/images/treeExpand_loading.gif');
+}
+.nihilo .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpando {
+ visibility: visible !important;
+ width: 18px !important;
+}
+.nihilo .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode {
+ background: url('../../../dijit/themes/nihilo/images/spriteTree.gif') no-repeat -36px top;
+}
+.nihilo .dojoxGridExpandoNodeInner {
+ visibility: hidden;
+}
+.dijit_a11y .dojoxGridExpandoNodeInner {
+ visibility: visible;
+}
+
+.nihilo .dojoxGridSummaryRow .dojoxGridCell {
+ border-top-color: #999;
+ border-top-style: solid;
+}
+.nihilo .dojoxGridSpacerCell,
+.nihilo .dojoxGridExpandoCell,
+.nihilo .dojoxGridSummaryRow .dojoxGridSpacerCell {
+ border-color: transparent;
+ border-right-color: #D5CDB5;
+}
+.nihilo .dojoxGridSummaryRow .dojoxGridTotalCell,
+.nihilo .dojoxGridRowCollapsed .dojoxGridExpandoCell,
+.nihilo .dojoxGridTreeModel .dojoxGridExpandoCell {
+ border-bottom-color: #D5CDB5;
+}
+.nihilo .dojoxGridSubRowAlt {
+ background-color: #F8F8F8;
+}
+.nihilo .dojoxGridRowOdd .dojoxGridSubRowAlt {
+ background-color: #EDEFF3;
+}
diff --git a/js/dojo-1.6/dojox/grid/resources/soriaGrid.css b/js/dojo-1.6/dojox/grid/resources/soriaGrid.css
new file mode 100644
index 0000000..330ddf3
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/soriaGrid.css
@@ -0,0 +1,245 @@
+@import url("Grid.css");
+
+.soria .dojoxGrid {
+ background-color: #e9e9e9;
+ font-size: 0.85em; /* inherit font-family from dojo.css */
+}
+
+/* master messages */
+
+.soria .dojoxGridMasterMessages {
+ background-color: #fefefe;
+}
+
+/* header */
+
+.soria .dojoxGridHeader {
+ background-color: #e9e9e9;
+}
+
+.soria .dojoxGridHeader .dojoxGridCell {
+ border-width: 1px;
+ padding-bottom: 0px;
+ border-color: transparent #ACA899 #919191 transparent;
+ background: url(../../../dijit/themes/soria/images/titleBar.png) #e9e9e9 repeat-x top;
+ color: #000 !important;
+}
+
+.soria .dojoxGridHeader .dojoxGridCellOver {
+ background: url(../../../dijit/themes/soria/images/titleBarActive.png) #e9e9e9 repeat-x top;
+}
+
+.soria .dojoxGridHeader .dojoxGridCellFocus {
+ border-color: #ACA899 #919191;
+ border-style: dashed;
+}
+
+.soria .dojoxGridArrowButtonChar {
+ float: right;
+ display: none;
+}
+.soria .dojoxGridArrowButtonNode {
+ display: block !important;
+ padding-left: 0px;
+ float: right;
+ background:url("../../../dijit/themes/soria/images/spriteArrows.png") no-repeat left center;
+ margin-top: 2px;
+ width: 11px;
+ height: 1em;
+}
+.dj_ie6 .soria .dojoxGridArrowButtonNode {
+ background-image:url("../../../dijit/themes/soria/images/spriteArrows.gif");
+ margin-left: 0px;
+}
+
+.soria .dojoxGridSortUp .dojoxGridArrowButtonNode {
+ background-position: -21px;
+}
+.dijit_a11y .soria .dojoxGridArrowButtonNode {
+ display: none !important;
+}
+
+/* content */
+
+.soria .dojoxGridScrollbox {
+ background-color: #fefefe;
+}
+
+/* rowbar */
+
+.soria .dojoxGridRowbar {
+ border: none;
+ background: url(../../../dijit/themes/soria/images/titleBar.png) #e9e9e9 repeat-y right;
+ border-right: 1px solid #ccc;
+ padding: 0px;
+}
+
+.soria .dojoxGridRowbarInner {
+ border: none;
+ border-bottom: 1px solid #ccc;
+}
+
+.soria .dojoxGridRowbarOver {
+ background: url(../../../dijit/themes/soria/images/titleBarActive.png) #e9e9e9 repeat-y right;
+}
+
+.soria .dojoxGridRowbarSelected {
+ background: url(../../../dijit/themes/soria/images/titleBar.png) #D9E8F9 no-repeat center;
+ border-right: 1px solid #ccc;
+}
+
+/* rows */
+
+.soria .dojoxGridRow {
+ border: none;
+ background-color: white;
+}
+
+.soria .dojoxGridRowOver {
+ border-top-color: #ccc;
+ border-bottom-color: #ccc;
+}
+
+.soria .dojoxGridRowOver .dojoxGridCell {
+ background-color: #60a1ea;
+ color:#fff;
+}
+
+.soria .dojoxGridRowOver .dojoxGridCell .dijit {
+ color: #000;
+}
+
+.soria .dojoxGridRowOver .dojoxGridCell .dijitDisabled {
+ color: gray;
+}
+
+.soria .dojoxGridRowOdd {
+ background-color: #f2f5f9;
+}
+
+.soria .dojoxGridRowSelected {
+ background-color: #aec7e3;
+}
+
+.dijit_a11y .soria .dojoxGridRowSelected {
+ background-color: #aec7e3;
+ border-style: solid;
+}
+
+/* cells */
+
+.soria .dojoxGridCell {
+ border: 1px dotted #D5CDB5;
+ border-left-color: transparent;
+ border-top-color: transparent;
+}
+
+.dj_ff2 .soria .dojoxGridCell {
+ border-left-width: 0px;
+ border-top-width: 0px;
+}
+
+.dj_ie6 .soria .dojoxGridCell {
+ border: 1px solid white;
+ border-right: 1px solid #D5CDB5;
+}
+
+.soria .dojoxGridCellFocus {
+ border: 1px dashed darkblue;
+}
+
+.soria .dojoxGridCellOver {
+ border: 1px dotted #a6a6a6;
+}
+
+.soria .dojoxGridCellFocus.dojoxGridCellOver {
+ border: 1px dashed darkblue;
+}
+
+/* editing */
+
+/* FIXME: these colors are off! */
+.soria .dojoxGridRowEditing td {
+ /* background-color: #F4FFF4; */
+ background-color: #60a1ea;
+ /* padding: 0px 3px 0px 3px; */
+}
+
+.soria .dojoxGridRow-inserting td {
+ background-color: #F4FFF4;
+}
+.soria .dojoxGridRow-inflight td {
+ background-color: #F2F7B7;
+}
+.soria .dojoxGridRow-error td {
+ background-color: #F8B8B6;
+}
+
+/* Drag and Drop */
+
+.soria .dojoxGrid .dojoDndItemBefore {
+ border-left-color: #4B5AAA;
+}
+.soria .dojoxGrid .dojoDndItemAfter {
+ border-right-color: #4B5AAA;
+}
+
+/* Tree Grid */
+.soria .dojoxGridExpando {
+ float: left;
+ height: 18px;
+ width: 18px;
+ text-align: center;
+ margin-top: -3px;
+}
+.dijitRtl .soria .dojoxGridExpando {
+ float: right;
+}
+.soria .dojoxGridExpandoCell {
+ padding-top: 5px;
+}
+.soria .dojoxGridExpandoNode {
+ height: 18px;
+ background-image: url('../../../dijit/themes/soria/images/spriteTree.gif');
+}
+.soria .dojoxGridExpandoOpened .dojoxGridExpandoNode {
+ background: url('../../../dijit/themes/soria/images/spriteTree.gif') no-repeat -18px top;
+}
+.soria .dojoxGridExpandoLoading .dojoxGridExpandoNode {
+ background: url('../../../dijit/themes/soria/images/treeExpand_loading.gif');
+}
+.soria .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpando {
+ visibility: visible !important;
+ width: 18px !important;
+}
+.soria .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode {
+ background: url('../../../dijit/themes/soria/images/spriteTree.gif') no-repeat -36px top;
+}
+.soria .dojoxGridExpandoNodeInner {
+ visibility: hidden;
+}
+.dijit_a11y .dojoxGridExpandoNodeInner {
+ visibility: visible;
+}
+
+.soria .dojoxGridSummaryRow .dojoxGridCell {
+ border-top-color: #999;
+ border-top-style: solid;
+}
+.soria .dojoxGridSpacerCell,
+.soria .dojoxGridExpandoCell,
+.soria .dojoxGridSummaryRow .dojoxGridSpacerCell {
+ border-color: transparent;
+ border-right-color: #D5CDB5;
+}
+.soria .dojoxGridSummaryRow .dojoxGridTotalCell,
+.soria .dojoxGridRowCollapsed .dojoxGridExpandoCell,
+.soria .dojoxGridTreeModel .dojoxGridExpandoCell {
+ border-bottom-color: #D5CDB5;
+}
+.soria .dojoxGridSubRowAlt {
+ background-color: #F8F8F8;
+}
+.soria .dojoxGridRowOdd .dojoxGridSubRowAlt {
+ background-color: #EDEFF3;
+}
diff --git a/js/dojo-1.6/dojox/grid/resources/tundraGrid.css b/js/dojo-1.6/dojox/grid/resources/tundraGrid.css
new file mode 100644
index 0000000..18ba271
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/resources/tundraGrid.css
@@ -0,0 +1,268 @@
+@import url("Grid.css");
+
+.tundra .dojoxGrid {
+ background-color: #e9e9e9;
+ font-size: 0.85em; /* inherit font-family from dojo.css */
+}
+
+/* master messages */
+
+.tundra .dojoxGridMasterMessages {
+ background-color: #fefefe;
+}
+
+.tundra .dojoxGridLoading,
+.tundra .dojoxGridError {
+ background-position:left center;
+ background-repeat: no-repeat;
+ padding-left:25px;
+}
+
+.dijitRtl .tundra .dojoxGridLoading,
+.dijitRtl .tundra .dojoxGridError,
+.dijitRtl .tundra .dojoxGridNoData {
+ background-position:right;
+ padding-right:25px;
+ padding-left:0px;
+}
+
+.tundra .dojoxGridLoading {
+ background-image: url('../../../dijit/themes/tundra/images/loading.gif');
+}
+
+.tundra .dojoxGridError {
+ background-image: url('../../../dijit/themes/tundra/images/warning.png');
+}
+
+/* header */
+
+.tundra .dojoxGridHeader {
+ background-color: #e9e9e9;
+}
+
+.tundra .dojoxGridHeader .dojoxGridCell {
+ border-width: 1px;
+ padding-bottom: 0px;
+ border-color: transparent #ACA899 #919191 transparent;
+ background: url(../../../dijit/themes/tundra/images/tabEnabled.png) #e9e9e9 repeat-x top;
+ color: #000 !important;
+}
+
+.tundra .dojoxGridHeader .dojoxGridCellOver {
+ background: url(../../../dijit/themes/tundra/images/tabHover.png) #e9e9e9 repeat-x top;
+ color: #000 !important;
+}
+.tundra .dojoxGridHeader .dojoxGridCellFocus {
+ border-color: #ACA899 #919191;
+ border-style: dashed;
+}
+.tundra .dojoxGridArrowButtonChar {
+ float: right;
+ display: none;
+}
+.tundra .dojoxGridArrowButtonNode {
+ display: block !important;
+ padding-left: 0px;
+ float: right;
+ background:url("../../../dijit/themes/tundra/images/spriteArrows.png") no-repeat left center;
+ width: 7px;
+ height: 1em;
+ margin: 2px 4px 0px 5px;
+}
+.dj_ie6 .tundra .dojoxGridArrowButtonNode {
+ background-image:url("../../../dijit/themes/tundra/images/spriteArrows.gif");
+ margin-left: 0px;
+}
+
+.tundra .dojoxGridSortUp .dojoxGridArrowButtonNode {
+ background-position: -21px;
+}
+.dijit_a11y .tundra .dojoxGridArrowButtonNode {
+ display: none !important;
+}
+
+/* content */
+
+.tundra .dojoxGridScrollbox {
+ background-color: #fefefe;
+}
+
+/* rowbar */
+
+.tundra .dojoxGridRowbar {
+ border: none;
+ background: url(images/tabEnabled_rotated.png) #e9e9e9 repeat-y right;
+ border-right: 1px solid #ccc;
+ padding: 0px;
+}
+
+.tundra .dojoxGridRowbarInner {
+ border: none;
+ border-bottom: 1px solid #ccc;
+}
+
+.tundra .dojoxGridRowbarOver {
+ background: url(images/tabHover_rotated.png) #e9e9e9 repeat-y right;
+}
+
+.tundra .dojoxGridRowbarSelected {
+ background: url(../../../dijit/themes/tundra/images/tabDisabled.png) #D8E8F9 no-repeat center;
+ border-right: 1px solid #ccc;
+}
+
+/* rows */
+
+.tundra .dojoxGridRow {
+ border: none;
+ background-color: white;
+}
+
+.tundra .dojoxGridRowOver {
+ border-top-color: #ccc;
+ border-bottom-color: #ccc;
+}
+
+.tundra .dojoxGridRowOver .dojoxGridCell {
+ background-color: #60a1ea;
+ color:#fff;
+}
+
+.tundra .dojoxGridRowOver .dojoxGridCell .dijit {
+ color: #000;
+}
+
+.tundra .dojoxGridRowOver .dojoxGridCell .dijitDisabled {
+ color: gray;
+}
+
+.tundra .dojoxGridRowOdd {
+ background-color: #f2f5f9;
+}
+
+.tundra .dojoxGridRowSelected {
+ background-color: #aec7e3 !important;
+}
+
+.dijit_a11y .tundra .dojoxGridRowSelected {
+ background-color: #aec7e3;
+ border-style: solid;
+}
+
+/* cells */
+
+.tundra .dojoxGridCell {
+ border: 1px dotted #D5CDB5;
+ border-left-color: transparent;
+ border-top-color: transparent;
+}
+
+.dj_ff2 .tundra .dojoxGridCell {
+ border-left-width: 0px;
+ border-top-width: 0px;
+}
+
+.dj_ie6 .tundra .dojoxGridCell {
+ border: 1px solid white;
+ border-right: 1px solid #D5CDB5;
+}
+
+.tundra .dojoxGridCellFocus {
+ border: 1px dashed darkblue !important;
+}
+
+.tundra .dojoxGridCellOver {
+ border: 1px dotted #a6a6a6;
+}
+
+.tundra .dojoxGridCellFocus .dojoxGridCellOver {
+ border: 1px dashed darkblue !important;
+}
+
+/* editing */
+
+/* FIXME: these colors are off! */
+.tundra .dojoxGridRowEditing td {
+ /* background-color: #F4FFF4; */
+ background-color: #60a1ea;
+ /* padding: 0px 3px 0px 3px; */
+}
+
+.tundra .dojoxGridRow-inserting td {
+ background-color: #F4FFF4;
+}
+.tundra .dojoxGridRow-inflight td {
+ background-color: #F2F7B7;
+}
+.tundra .dojoxGridRow-error td {
+ background-color: #F8B8B6;
+}
+
+/* Drag and Drop */
+
+.tundra .dojoxGrid .dojoDndItemBefore {
+ border-left-color: #3559ac;
+}
+.tundra .dojoxGrid .dojoDndItemAfter {
+ border-right-color: #3559ac;
+}
+
+/* Tree Grid */
+.tundra .dojoxGridExpando {
+ float: left;
+ height: 18px;
+ width: 18px;
+ text-align: center;
+ margin-top: -3px;
+}
+.dijitRtl .tundra .dojoxGridExpando {
+ float: right;
+}
+.tundra .dojoxGridExpandoCell {
+ padding-top: 5px;
+}
+.tundra .dojoxGridExpandoNode {
+ height: 18px;
+ background-image: url('../../../dijit/themes/tundra/images/treeExpand_plus.gif');
+}
+.tundra .dojoxGridExpandoOpened .dojoxGridExpandoNode {
+ background-image: url('../../../dijit/themes/tundra/images/treeExpand_minus.gif');
+}
+.tundra .dojoxGridExpandoLoading .dojoxGridExpandoNode {
+ background-image: url('../../../dijit/themes/tundra/images/treeExpand_loading.gif');
+}
+.tundra .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpando {
+ visibility: visible !important;
+ width: 18px !important;
+}
+.tundra .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode {
+ background-image: url('../../../dijit/themes/tundra/images/treeExpand_leaf.gif');
+ background-position: -3px;
+}
+.tundra .dojoxGridExpandoNodeInner {
+ visibility: hidden;
+}
+.dijit_a11y .dojoxGridExpandoNodeInner {
+ visibility: visible;
+}
+
+.tundra .dojoxGridSummaryRow .dojoxGridCell {
+ border-top-color: #999;
+ border-top-style: solid;
+}
+.tundra .dojoxGridSpacerCell,
+.tundra .dojoxGridExpandoCell,
+.tundra .dojoxGridSummaryRow .dojoxGridSpacerCell {
+ border-color: transparent;
+ border-right-color: #D5CDB5;
+}
+.tundra .dojoxGridSummaryRow .dojoxGridTotalCell,
+.tundra .dojoxGridRowCollapsed .dojoxGridExpandoCell,
+.tundra .dojoxGridTreeModel .dojoxGridExpandoCell {
+ border-bottom-color: #D5CDB5;
+}
+.tundra .dojoxGridSubRowAlt {
+ background-color: #F8F8F8;
+}
+.tundra .dojoxGridRowOdd .dojoxGridSubRowAlt {
+ background-color: #EDEFF3;
+}
diff --git a/js/dojo-1.6/dojox/grid/util.js b/js/dojo-1.6/dojox/grid/util.js
new file mode 100644
index 0000000..f2cce77
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/util.js
@@ -0,0 +1,79 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.util"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.util"] = true;
+dojo.provide("dojox.grid.util");
+
+// summary: grid utility library
+(function(){
+ var dgu = dojox.grid.util;
+
+ dgu.na = '...';
+ dgu.rowIndexTag = "gridRowIndex";
+ dgu.gridViewTag = "gridView";
+
+
+ dgu.fire = function(ob, ev, args){
+ var fn = ob && ev && ob[ev];
+ return fn && (args ? fn.apply(ob, args) : ob[ev]());
+ };
+
+ dgu.setStyleHeightPx = function(inElement, inHeight){
+ if(inHeight >= 0){
+ var s = inElement.style;
+ var v = inHeight + 'px';
+ if(inElement && s['height'] != v){
+ s['height'] = v;
+ }
+ }
+ };
+
+ dgu.mouseEvents = [ 'mouseover', 'mouseout', /*'mousemove',*/ 'mousedown', 'mouseup', 'click', 'dblclick', 'contextmenu' ];
+
+ dgu.keyEvents = [ 'keyup', 'keydown', 'keypress' ];
+
+ dgu.funnelEvents = function(inNode, inObject, inMethod, inEvents){
+ var evts = (inEvents ? inEvents : dgu.mouseEvents.concat(dgu.keyEvents));
+ for (var i=0, l=evts.length; i<l; i++){
+ inObject.connect(inNode, 'on' + evts[i], inMethod);
+ }
+ };
+
+ dgu.removeNode = function(inNode){
+ inNode = dojo.byId(inNode);
+ inNode && inNode.parentNode && inNode.parentNode.removeChild(inNode);
+ return inNode;
+ };
+
+ dgu.arrayCompare = function(inA, inB){
+ for(var i=0,l=inA.length; i<l; i++){
+ if(inA[i] != inB[i]){return false;}
+ }
+ return (inA.length == inB.length);
+ };
+
+ dgu.arrayInsert = function(inArray, inIndex, inValue){
+ if(inArray.length <= inIndex){
+ inArray[inIndex] = inValue;
+ }else{
+ inArray.splice(inIndex, 0, inValue);
+ }
+ };
+
+ dgu.arrayRemove = function(inArray, inIndex){
+ inArray.splice(inIndex, 1);
+ };
+
+ dgu.arraySwap = function(inArray, inI, inJ){
+ var cache = inArray[inI];
+ inArray[inI] = inArray[inJ];
+ inArray[inJ] = cache;
+ };
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/grid/util.xd.js b/js/dojo-1.6/dojox/grid/util.xd.js
new file mode 100644
index 0000000..242814c
--- /dev/null
+++ b/js/dojo-1.6/dojox/grid/util.xd.js
@@ -0,0 +1,83 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.grid.util"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.grid.util"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.util"] = true;
+dojo.provide("dojox.grid.util");
+
+// summary: grid utility library
+(function(){
+ var dgu = dojox.grid.util;
+
+ dgu.na = '...';
+ dgu.rowIndexTag = "gridRowIndex";
+ dgu.gridViewTag = "gridView";
+
+
+ dgu.fire = function(ob, ev, args){
+ var fn = ob && ev && ob[ev];
+ return fn && (args ? fn.apply(ob, args) : ob[ev]());
+ };
+
+ dgu.setStyleHeightPx = function(inElement, inHeight){
+ if(inHeight >= 0){
+ var s = inElement.style;
+ var v = inHeight + 'px';
+ if(inElement && s['height'] != v){
+ s['height'] = v;
+ }
+ }
+ };
+
+ dgu.mouseEvents = [ 'mouseover', 'mouseout', /*'mousemove',*/ 'mousedown', 'mouseup', 'click', 'dblclick', 'contextmenu' ];
+
+ dgu.keyEvents = [ 'keyup', 'keydown', 'keypress' ];
+
+ dgu.funnelEvents = function(inNode, inObject, inMethod, inEvents){
+ var evts = (inEvents ? inEvents : dgu.mouseEvents.concat(dgu.keyEvents));
+ for (var i=0, l=evts.length; i<l; i++){
+ inObject.connect(inNode, 'on' + evts[i], inMethod);
+ }
+ };
+
+ dgu.removeNode = function(inNode){
+ inNode = dojo.byId(inNode);
+ inNode && inNode.parentNode && inNode.parentNode.removeChild(inNode);
+ return inNode;
+ };
+
+ dgu.arrayCompare = function(inA, inB){
+ for(var i=0,l=inA.length; i<l; i++){
+ if(inA[i] != inB[i]){return false;}
+ }
+ return (inA.length == inB.length);
+ };
+
+ dgu.arrayInsert = function(inArray, inIndex, inValue){
+ if(inArray.length <= inIndex){
+ inArray[inIndex] = inValue;
+ }else{
+ inArray.splice(inIndex, 0, inValue);
+ }
+ };
+
+ dgu.arrayRemove = function(inArray, inIndex){
+ inArray.splice(inIndex, 1);
+ };
+
+ dgu.arraySwap = function(inArray, inI, inJ){
+ var cache = inArray[inI];
+ inArray[inI] = inArray[inJ];
+ inArray[inJ] = cache;
+ };
+})();
+
+}
+
+}};});