You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by js...@apache.org on 2009/03/19 11:37:20 UTC
svn commit: r755904 [27/40] - in
/camel/trunk/components/camel-web/src/main/webapp/js/dojox: ./ analytics/
analytics/logger/ analytics/plugins/ analytics/profiles/ atom/ atom/io/
atom/widget/ atom/widget/nls/ atom/widget/nls/cs/ atom/widget/nls/de/ ato...
Added: camel/trunk/components/camel-web/src/main/webapp/js/dojox/grid/DataGrid.js.uncompressed.js
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/js/dojox/grid/DataGrid.js.uncompressed.js?rev=755904&view=auto
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/js/dojox/grid/DataGrid.js.uncompressed.js (added)
+++ camel/trunk/components/camel-web/src/main/webapp/js/dojox/grid/DataGrid.js.uncompressed.js Thu Mar 19 10:37:00 2009
@@ -0,0 +1,9545 @@
+/*
+ Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+ development. To get an editable version, please visit:
+
+ http://dojotoolkit.org
+
+ for documentation and information on getting the source.
+*/
+
+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; });
+ 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(/*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
+ this.focusChild(this._getFirstFocusableChild());
+ },
+
+ focusNext: function(){
+ // summary:
+ // Focus the next widget or focal node (for widgets
+ // with multiple focal nodes) within this container.
+ // tags:
+ // protected
+ if(this.focusedChild && this.focusedChild.hasNextFocalNode
+ && this.focusedChild.hasNextFocalNode()){
+ this.focusedChild.focusNext();
+ return;
+ }
+ var child = this._getNextFocusableChild(this.focusedChild, 1);
+ if(child.getFocalNodes){
+ this.focusChild(child, child.getFocalNodes()[0]);
+ }else{
+ this.focusChild(child);
+ }
+ },
+
+ focusPrev: function(){
+ // summary:
+ // Focus the previous widget or focal node (for widgets
+ // with multiple focal nodes) within this container.
+ // tags:
+ // protected
+ if(this.focusedChild && this.focusedChild.hasPrevFocalNode
+ && this.focusedChild.hasPrevFocalNode()){
+ this.focusedChild.focusPrev();
+ return;
+ }
+ var child = this._getNextFocusableChild(this.focusedChild, -1);
+ if(child.getFocalNodes){
+ var nodes = child.getFocalNodes();
+ this.focusChild(child, nodes[nodes.length-1]);
+ }else{
+ this.focusChild(child);
+ }
+ },
+
+ focusChild: function(/*Widget*/ widget, /*Node?*/ node){
+ // summary:
+ // Focus widget. Optionally focus 'node' within widget.
+ // tags:
+ // protected
+ if(widget){
+ if(this.focusedChild && widget !== this.focusedChild){
+ this._onChildBlur(this.focusedChild);
+ }
+ this.focusedChild = widget;
+ if(node && widget.focusFocalNode){
+ widget.focusFocalNode(node);
+ }else{
+ widget.focus();
+ }
+ }
+ },
+
+ _startupChild: function(/*Widget*/ widget){
+ // summary:
+ // Set tabindex="-1" on focusable widgets so that we
+ // can focus them programmatically and by clicking.
+ // Connect focus and blur handlers.
+ // tags:
+ // private
+ if(widget.getFocalNodes){
+ dojo.forEach(widget.getFocalNodes(), function(node){
+ dojo.attr(node, "tabindex", -1);
+ this._connectNode(node);
+ }, this);
+ }else{
+ var node = widget.focusNode || widget.domNode;
+ if(widget.isFocusable()){
+ dojo.attr(node, "tabindex", -1);
+ }
+ this._connectNode(node);
+ }
+ },
+
+ _connectNode: function(/*Element*/ node){
+ // summary:
+ // Monitor focus and blur events on the node
+ // tags:
+ // private
+ this.connect(node, "onfocus", "_onNodeFocus");
+ this.connect(node, "onblur", "_onNodeBlur");
+ },
+
+ _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 remove the container's tabIndex,
+ // so that tab or shift-tab will go to the fields after/before
+ // the container, rather than the container itself
+ dojo.removeAttr(this.domNode, "tabIndex");
+ },
+
+ _onBlur: function(evt){
+ // When focus is moved away the container, and it's 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);
+ }
+ // TODO: 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);
+ }
+ },
+
+ _onNodeFocus: function(evt){
+ // summary:
+ // Handler for onfocus event on a child node
+ // tags:
+ // private
+
+ // record the child that has been focused
+ var widget = dijit.getEnclosingWidget(evt.target);
+ if(widget && widget.isFocusable()){
+ this.focusedChild = widget;
+ }
+ dojo.stopEvent(evt);
+ },
+
+ _onNodeBlur: function(evt){
+ // summary:
+ // Handler for onblur event on a child node
+ // tags:
+ // private
+ dojo.stopEvent(evt);
+ },
+
+ _onChildBlur: function(/*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);
+ },
+
+ _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;
+ }
+ child = this._getSiblingOfChild(child, dir);
+ }
+ // no focusable child found
+ return null;
+ }
+ }
+);
+
+}
+
+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],
+ {
+ // summary:
+ // A line item in a Menu Widget
+
+ // Make 3 columns
+ // icon, label, and expand arrow (BiDi-dependent) indicating sub-menu
+ templateString:"<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" waiRole=\"menuitem\" tabIndex=\"-1\"\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset\" waiRole=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon\" dojoAttachPoint=\"iconNode\">\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" dojoAttachPoint=\"containerNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" dojoAttachPoint=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" waiRole=\"presentation\">\n\t\t<div dojoAttachPoint=\"arrowWrapper\" style=\"visibility: hidden\">\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuExpand\">\n\t\t\t<span class=\"dijitMenuExpandA11y\">+</span>\n\t\t</div>\n\t</td>\n</tr>\n",
+
+ attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
+ label: { node: "containerNode", type: "innerHTML" },
+ iconClass: { node: "iconNode", type: "class" }
+ }),
+
+ // 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.attr('label', source.innerHTML);
+ }
+ },
+
+ postCreate: function(){
+ dojo.setSelectable(this.domNode, false);
+ dojo.attr(this.containerNode, "id", this.id+"_text");
+ dijit.setWaiState(this.domNode, "labelledby", this.id+"_text");
+ },
+
+ _onHover: function(){
+ // summary:
+ // Handler when mouse is moved onto menu item
+ // tags:
+ // protected
+ dojo.addClass(this.domNode, 'dijitMenuItemHover');
+ 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
+ dojo.removeClass(this.domNode, 'dijitMenuItemHover');
+ this.getParent().onItemUnhover(this);
+ },
+
+ _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{
+ 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);
+
+ // TODO: 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() 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 attr('label', ...) instead.
+ // tags:
+ // deprecated
+ dojo.deprecated("dijit.MenuItem.setLabel() is deprecated. Use attr('label', ...) instead.", "", "2.0");
+ this.attr("label", content);
+ },
+
+ setDisabled: function(/*Boolean*/ disabled){
+ // summary:
+ // Deprecated. Use attr('disabled', bool) instead.
+ // tags:
+ // deprecated
+ dojo.deprecated("dijit.Menu.setDisabled() is deprecated. Use attr('disabled', bool) instead.", "", "2.0");
+ this.attr('disabled', disabled);
+ },
+ _setDisabledAttr: function(/*Boolean*/ value){
+ // summary:
+ // Hook for attr('disabled', ...) to work.
+ // Enable or disable this menu item.
+ this.disabled = value;
+ dojo[value ? "addClass" : "removeClass"](this.domNode, 'dijitMenuItemDisabled');
+ dijit.setWaiState(this.focusNode, 'disabled', value ? 'true' : 'false');
+ },
+ _setAccelKeyAttr: function(/*String*/ value){
+ // summary:
+ // Hook for attr('accelKey', ...) to work.
+ // Set accelKey on this menu item.
+ this.accelKey=value;
+
+ 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");
+ }
+ });
+
+}
+
+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.domNode.style.display="none";
+ if(this.arrowWrapper){
+ dojo.style(this.arrowWrapper, "visibility", "");
+ }
+ dijit.setWaiState(this.focusNode, "haspopup", "true");
+ },
+
+ destroyDescendants: function(){
+ if(this.popup){
+ 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:"<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" waiRole=\"menuitemcheckbox\" tabIndex=\"-1\"\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset\" waiRole=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" dojoAttachPoint=\"iconNode\">\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">✓</span>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" dojoAttachPoint=\"containerNode,labelNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" dojoAttachPoint=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" waiRole=\"presentation\">\n\t</td>\n</tr>\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.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.attr("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:"<tr class=\"dijitMenuSeparator\">\n\t<td colspan=\"4\">\n\t\t<div class=\"dijitMenuSeparatorTop\"></div>\n\t\t<div class=\"dijitMenuSeparatorBottom\"></div>\n\t</td>\n</tr>\n",
+
+ postCreate: function(){
+ 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");
+
+
+
+
+
+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();
+ }
+ }
+ },
+
+ 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) tabbing into it
+ // 3) 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);
+ }
+ }
+ },
+
+ _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
+
+ item._setSelected(false);
+
+ // Close all popups that are open and descendants of this menu
+ dijit.popup.close(item.popup);
+ this._stopPopupTimer();
+ },
+
+ onItemUnhover: function(/*MenuItem*/ item){
+ // summary:
+ // Callback fires when mouse exits a MenuItem
+ // tags:
+ // protected
+ if(this.isActive){
+ this._stopPopupTimer();
+ }
+ },
+
+ _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;
+ }
+ },
+
+ _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(/*Widget*/ item, /*Event*/ evt){
+ // summary:
+ // Handle clicks on an item.
+ // tags:
+ // private
+ if(item.disabled){ return false; }
+
+ this.focusChild(item);
+
+ if(item.popup){
+ if(!this.is_open){
+ 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;
+ var popup = from_item.popup;
+
+ if(popup.isShowingNow){ return; }
+ popup.parentMenu = this;
+ var self = this;
+ dijit.popup.open({
+ parent: this,
+ popup: popup,
+ around: from_item.domNode,
+ orient: this._orient || (this.isLeftToRight() ? {'TR': 'TL', 'TL': 'TR'} : {'TL': 'TR', 'TR': 'TL'}),
+ onCancel: function(){
+ // called when the child menu is canceled
+ dijit.popup.close(popup);
+ from_item.focus(); // put focus back on my node
+ self.currentPopup = null;
+ },
+ onExecute: dojo.hitch(this, "_onDescendantExecute")
+ });
+
+ this.currentPopup = popup;
+
+ 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)
+ setTimeout(dojo.hitch(popup, "focus"), 0);
+ }
+ },
+
+ 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;
+ },
+
+ 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._stopPopupTimer();
+ this.parentMenu = null;
+ this.isShowingNow = false;
+ this.currentPopup = null;
+ if(this.focusedChild){
+ this._onChildBlur(this.focusedChild);
+ this.focusedChild = null;
+ }
+ },
+
+ _onFocus: function(){
+ // summary:
+ // Called when 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.
+ // tags:
+ // protected
+ this.isActive = true;
+ dojo.addClass(this.domNode, "dijitMenuActive");
+ dojo.removeClass(this.domNode, "dijitMenuPassive");
+ this.inherited(arguments);
+ },
+
+ _onBlur: function(){
+ // summary:
+ // Called when focus is moved away from this Menu and it's submenus.
+ // tags:
+ // protected
+ this.isActive = false;
+ dojo.removeClass(this.domNode, "dijitMenuActive");
+ dojo.addClass(this.domNode, "dijitMenuPassive");
+
+ // If user blurs/clicks away from a MenuBar (or always visible Menu), then close all popped up submenus etc.
+ this.onClose();
+
+ this.inherited(arguments);
+ },
+
+ _onDescendantExecute: function(){
+ // summary:
+ // Called when submenu is clicked. Close hierarchy of menus.
+ // tags:
+ // private
+ this.onClose();
+ }
+});
+
+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:"<table class=\"dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable\" waiRole=\"menu\" tabIndex=\"${tabIndex}\" dojoAttachEvent=\"onkeypress:_onKeyPress\">\n\t<tbody class=\"dijitReset\" dojoAttachPoint=\"containerNode\"></tbody>\n</table>\n",
+
+ // 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,
+
+ // _contextMenuWithMouse: [private] Boolean
+ // Used to record mouse and keyboard events to determine if a context
+ // menu is being opened with the keyboard or the mouse.
+ _contextMenuWithMouse: false,
+
+ 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(/*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 = dijit.getDocumentWindow(dijit.Menu._iframeContentDocument(iframe_el)) ||
+ // Moz. TODO: is this available when defaultView isn't?
+ dijit.Menu._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);
+
+ //TODO: this is to support context popups in Editor. Maybe this shouldn't be in dijit.Menu
+ var win = dijit.getDocumentWindow(node.ownerDocument);
+ if(node.tagName.toLowerCase()=="iframe"){
+ win = this._iframeContentWindow(node);
+ node = dojo.withGlobal(win, dojo.body);
+ }
+
+ // to capture these events at the top level,
+ // attach to document, not body
+ var cn = (node == dojo.body() ? dojo.doc : node);
+
+ node[this.id] = this._bindings.push([
+ dojo.connect(cn, (this.leftClickToOpen)?"onclick":"oncontextmenu", this, "_openMyself"),
+ dojo.connect(cn, "onkeydown", this, "_contextKey"),
+ dojo.connect(cn, "onmousedown", this, "_contextMouse")
+ ]);
+ },
+
+ unBindDomNode: function(/*String|DomNode*/ nodeName){
+ // summary:
+ // Detach menu from given node
+ var node = dojo.byId(nodeName);
+ if(node){
+ var bid = node[this.id]-1, b = this._bindings[bid];
+ dojo.forEach(b, dojo.disconnect);
+ delete this._bindings[bid];
+ }
+ },
+
+ _contextKey: function(e){
+ // summary:
+ // Code to handle popping up editor using F10 key rather than mouse
+ // tags:
+ // private
+ this._contextMenuWithMouse = false;
+ if(e.keyCode == dojo.keys.F10){
+ dojo.stopEvent(e);
+ if(e.shiftKey && e.type=="keydown"){
+ // FF: copying the wrong property from e will cause the system
+ // context menu to appear in spite of stopEvent. Don't know
+ // exactly which properties cause this effect.
+ var _e = { target: e.target, pageX: e.pageX, pageY: e.pageY };
+ _e.preventDefault = _e.stopPropagation = function(){};
+ // IE: without the delay, focus work in "open" causes the system
+ // context menu to appear in spite of stopEvent.
+ window.setTimeout(dojo.hitch(this, function(){ this._openMyself(_e); }), 1);
+ }
+ }
+ },
+
+ _contextMouse: function(e){
+ // summary:
+ // Helper to remember when we opened the context menu with the mouse instead
+ // of with the keyboard
+ // tags:
+ // private
+ this._contextMenuWithMouse = true;
+ },
+
+ _openMyself: function(/*Event*/ e){
+ // summary:
+ // Internal function for opening myself when the user
+ // does a right-click or something similar
+ // tags:
+ // private
+
+ if(this.leftClickToOpen&&e.button>0){
+ return;
+ }
+ dojo.stopEvent(e);
+
+ // Get coordinates.
+ // if we are opening the menu with the mouse or on safari open
+ // the menu at the mouse cursor
+ // (Safari does not have a keyboard command to open the context menu
+ // and we don't currently have a reliable way to determine
+ // _contextMenuWithMouse on Safari)
+ var x,y;
+ if(dojo.isSafari || this._contextMenuWithMouse){
+ x=e.pageX;
+ y=e.pageY;
+ }else{
+ // otherwise open near e.target
+ var coords = dojo.coords(e.target, true);
+ x = coords.x + 10;
+ y = coords.y + 10;
+ }
+
+ var self=this;
+ var savedFocus = dijit.getFocus(this);
+ function closeAndRestoreFocus(){
+ // user has clicked on a menu or popup
+ dijit.focus(savedFocus);
+ dijit.popup.close(self);
+ }
+ dijit.popup.open({
+ popup: this,
+ x: x,
+ y: 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.targetNodeIds, this.unBindDomNode, this);
+ this.inherited(arguments);
+ }
+}
+);
+
+// Back-compat (TODO: remove in 2.0)
+
+
+
+
+
+
+}
+
+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.border="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;
+ if(!measuringNode){
+ m = measuringNode = dojo.doc.createElement("div");
+ m.style.position = "absolute";
+ m.style.left = "-10000px";
+ m.style.top = "0";
+ dojo.body().appendChild(m);
+ }else{
+ m = measuringNode;
+ }
+ // reset styles
+ m.className = "";
+ m.style.border = "0";
+ m.style.margin = "0";
+ m.style.padding = "0";
+ m.style.outline = "0";
+ // set new style
+ if(arguments.length > 1 && style){
+ for(var i in style){
+ if(i in empty){ continue; }
+ m.style[i] = style[i];
+ }
+ }
+ // set classes
+ if(arguments.length > 2 && className){
+ m.className = className;
+ }
+ // take a measure
+ m.innerHTML = text;
+ return dojo.marginBox(m);
+ };
+
+ // 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";
+ f.src = dojo.config["dojoBlankHtmlUrl"] || dojo.moduleUrl("dojo", "resources/blank.html");
+ dojo.body().appendChild(f);
+
+ if(dojo.isIE){
+ f.onreadystatechange = function(){
+ if(f.contentWindow.document.readyState == "complete"){
+ f.onresize = Function('window.parent.'+dojox._scopeName+'.html.metrics._fontresize()');
+ }
+ };
+ }else{
+ f.onload = function(){
+ f.contentWindow.onresize = Function('window.parent.'+dojox._scopeName+'.html.metrics._fontresize()');
+ };
+ }
+ 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);
+ //
+ 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++])){
+ 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;
+ }
+ 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.keepRows : 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.invalidateNodes();
+ this.pageHeights = [];
+ this.height = (this.pageCount ? (this.pageCount - 1)* this.defaultPageHeight + this.calcLastPageHeight() : 0);
+ this.resize();
+ },
+ updateRowCount: function(inRowCount){
+ this.invalidateNodes();
+ this.rowCount = inRowCount;
+ // update page count, adjust document height
+ var oldPageCount = this.pageCount;
+ 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){
+ var n = this.getDefaultPageNode(inPageIndex);
+ return (n&&n.innerHTML) ? n.offsetHeight : 0;
+ },
+ 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;
+ new_p.id = (this._pageIdPrefix || "") + 'page-' + inPageIndex;
+ nodes[inPageIndex] = new_p;
+ }
+ },
+ // rendering implementation
+ renderPage: function(inPageIndex){
+ var nodes = [];
+ for(var i=0; i<this.colCount; i++){
+ nodes[i] = this.pageNodes[i][inPageIndex];
+ }
+ for(var 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++){
+ dojox.grid.util.setStyleHeightPx(this.contentNodes[i], this.height);
+ }
+
+ // Calculate the average row height and update the defaults (row and page).
+ 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){
+ if(this.pageExists(inPageIndex)){
+ var oh = this.getPageHeight(inPageIndex);
+ var h = (this.measurePage(inPageIndex))||(oh);
+ this.pageHeights[inPageIndex] = h;
+ if((h)&&(oh != h)){
+ this.updateContentHeight(h - oh)
+ this.repositionPages(inPageIndex);
+ }
+ }
+ },
+ rowHeightChanged: function(inRowIndex){
+ this.updatePageHeight(Math.floor(inRowIndex / this.rowsPerPage));
+ },
+ // scroller core
+ invalidateNodes: function(){
+ while(this.stack.length){
+ this.destroyPage(this.popPage());
+ }
+ },
+ createPageNode: function(){
+ var p = document.createElement('div');
+ 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.keepPages&&(this.stack.length >= this.keepPages), inPos);
+ h = this.measurePage(inPageIndex) || h;
+ this.pageHeights[inPageIndex] = h;
+ if(h && (oh != h)){
+ this.updateContentHeight(h - oh)
+ }
+ }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;
+ for(var i=0; i<rowPage; i++){
+ t += this.getPageHeight(i);
+ }
+ this.pageTop = t;
+ this.needPage(rowPage, this.pageTop);
+
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[rowPage]);
+ var r = inRow - this.rowsPerPage * rowPage;
+ for(var 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");
+
+
+
+(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,
+ //private
+ _valueProp: "value",
+ _formatPending: false,
+
+ constructor: function(inProps){
+ this._props = inProps || {};
+ dojo.mixin(this, inProps);
+ },
+
+ // 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);
+ if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndex && i.cell==this))){
+ return this.formatEditing(d, inRowIndex);
+ }else{
+ var v = (d != this.defaultValue && (f = this.formatter)) ? f.call(this, d, inRowIndex) : d;
+ return (typeof v == "undefined" ? this.defaultValue : v);
+ }
+ },
+ 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)){
+ //
+ 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);
+ //
+ },
+ restore: function(inRowIndex){
+ // summary:
+ // restore editor state
+ // inRowIndex: int
+ // grid row index
+ this.setValue(inRowIndex, this.value);
+ //
+ },
+ //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);
+ }
+ var get = d.trim(d.attr(node, "get")||"");
+ if(get){
+ cellDef.get = dojo.getObject(get);
+ }
+ var getBoolAttr = function(attr){
+ var value = d.trim(d.attr(node, attr)||"");
+ return value ? !(value.toLowerCase()=="false") : undefined;
+ }
+ cellDef.sortDesc = getBoolAttr("sortDesc");
+ cellDef.editable = getBoolAttr("editable");
+ cellDef.alwaysEditing = getBoolAttr("alwaysEditing");
+ cellDef.noresize = getBoolAttr("noresize");
+
+ var value = d.trim(d.attr(node, "loadingText")||d.attr(node, "defaultValue")||"");
+ if(value){
+ cellDef.defaultValue = value;
+ }
+
+ var getStrAttr = function(attr){
+ return d.trim(d.attr(node, attr)||"")||undefined;
+ };
+ cellDef.styles = getStrAttr("styles");
+ cellDef.headerStyles = getStrAttr("headerStyles");
+ cellDef.cellStyles = getStrAttr("cellStyles");
+ cellDef.classes = getStrAttr("classes");
+ cellDef.headerClasses = getStrAttr("headerClasses");
+ cellDef.cellClasses = getStrAttr("cellClasses");
+ }
+
+ 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.dnd._isMac = navigator.appVersion.indexOf("Macintosh") >= 0;
+dojo.dnd._copyKey = dojo.dnd._isMac ? "metaKey" : "ctrlKey";
+
+dojo.dnd.getCopyKeyState = function(e) {
+ // summary: abstracts away the difference between selection on Mac and PC,
+ // and returns the state of the "copy" key to be pressed.
+ // e: Event: mouse event
+ return e[dojo.dnd._copyKey]; // Boolean
+};
+
+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
+};
+
+// doesn't take into account when multiple buttons are pressed
+dojo.dnd._lmb = dojo.isIE ? 1 : 0; // left mouse button
+
+dojo.dnd._isLmbPressed = dojo.isIE ?
+ function(e){ return e.button & 1; } : // intentional bit-and
+ function(e){ return e.button === 0; };
+
+}
+
+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.dnd.getViewport = function(){
+ // summary: returns a viewport size (visible part of the window)
+
+ // FIXME: need more docs!!
+ var d = dojo.doc, dd = d.documentElement, w = window, b = dojo.body();
+ if(dojo.isMozilla){
+ return {w: dd.clientWidth, h: w.innerHeight}; // Object
+ }else if(!dojo.isOpera && w.innerWidth){
+ return {w: w.innerWidth, h: w.innerHeight}; // Object
+ }else if (!dojo.isOpera && dd && dd.clientWidth){
+ return {w: dd.clientWidth, h: dd.clientHeight}; // Object
+ }else if (b.clientWidth){
+ return {w: b.clientWidth, h: b.clientHeight}; // Object
+ }
+ return null; // Object
+};
+
+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.dnd.getViewport(), 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._abs(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){
+ // FIXME: this code should not be here, it should be taken into account
+ // either by the event fixing code, or the dojo._abs()
+ // 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;
+ }
+ }
+ //
+ 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,
+ // 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);
+ this.marginBox = {l: e.pageX, t: e.pageY};
+ this.mouseButton = e.button;
+ var h = this.host = host, d = node.ownerDocument,
+ firstEvent = dojo.connect(d, "onmousemove", this, "onFirstMove");
+ this.events = [
+ dojo.connect(d, "onmousemove", this, "onMouseMove"),
+ dojo.connect(d, "onmouseup", this, "onMouseUp"),
+ // cancel text selection and text dragging
+ dojo.connect(d, "ondragstart", dojo.stopEvent),
+ dojo.connect(d.body, "onselectstart", dojo.stopEvent),
+ firstEvent
+ ];
+ // notify that the move has started
+ if(h && h.onMoveStart){
+ h.onMoveStart(this);
+ }
+ },
+ // mouse event processors
+ onMouseMove: function(e){
+ // summary: event processor for onmousemove
+ // e: Event: mouse event
+ dojo.dnd.autoScroll(e);
+ var m = this.marginBox;
+ this.host.onMove(this, {l: m.l + e.pageX, t: m.t + e.pageY});
+ dojo.stopEvent(e);
+ },
+ onMouseUp: function(e){
+ if(dojo.isWebKit && dojo.dnd._isMac && this.mouseButton == 2 ?
+ e.button == 0 : this.mouseButton == e.button){
+ this.destroy();
+ }
+ dojo.stopEvent(e);
+ },
+ // utilities
+ onFirstMove: function(){
+ // summary: makes the node absolute; it is meant to be called only once
+ 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));
+ t = Math.round(parseFloat(s.top));
+ 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);
+ }
+ dojo.disconnect(this.events.pop());
+ },
+ 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.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: Object: an optional object with additional parameters;
+ // following parameters are recognized:
+ // handle: Node: a node (or node's id), which is used as a mouse handle
+ // if omitted, the node itself is used as a handle
+ // delay: Number: delay move by this number of pixels
+ // skip: Boolean: skip move of form elements
+ // mover: Object: a constructor of custom Mover
+ 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"),
+ // 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, creates a Mover for the node
+ // e: Event: mouse 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, "onmouseup", this, "onMouseUp")
+ );
+ this._lastX = e.pageX;
+ this._lastY = e.pageY;
+ }else{
+ this.onDragDetected(e);
+ }
+ dojo.stopEvent(e);
+ },
+ onMouseMove: function(e){
+ // summary: event processor for onmousemove, used only for delayed drags
+ // e: Event: mouse event
+ if(Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.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){
+ // 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){
+ // 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="wairole: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;
+ var waiPrefix = dojo.isFF<3 ? "wairole:" : "";
+ if(isHeader){
+ html = ['<th tabIndex="-1" role="', waiPrefix, 'columnheader"'];
+ }else{
+ html = ['<td tabIndex="-1" role="', waiPrefix, 'gridcell"'];
+ }
+ inCell.colSpan && html.push(' colspan="', inCell.colSpan, '"');
+ inCell.rowSpan && html.push(' rowspan="', inCell.rowSpan, '"');
+ html.push(' class="dojoxGridCell ');
+ inCell.classes && html.push(inCell.classes, ' ');
+ 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;':'');
+ inCell.unitWidth && html.push('width:', inCell.unitWidth, ';');
+ // result[2] => markup
+ result.push(html.join(''));
+ // SLOT: result[3] => td style
+ result.push('');
+ html = [ '"' ];
+ 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('</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;
+ }
+ }
+ }
+ },
+
+ 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);
+ }
+ },
+
+ // 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);
+ }
+ }
+ },
+
+ // 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.headerClasses){
+ if(cell.headerClasses.indexOf('dojoDndItem') == -1){
[... 6619 lines stripped ...]