You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cacert-testmgr/external/ZendFramework-1.9.5/externals/dojo/dijit/layout/AccordionContainer.js

312 lines
9.4 KiB
JavaScript

dojo.provide("dijit.layout.AccordionContainer");
dojo.require("dojo.fx");
dojo.require("dijit._Container");
dojo.require("dijit._Templated");
dojo.require("dijit.layout.StackContainer");
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.layout.AccordionPane"); // for back compat
dojo.declare(
"dijit.layout.AccordionContainer",
dijit.layout.StackContainer,
{
// summary:
// Holds a set of panes where every pane's title is visible, but only one pane's content is visible at a time,
// and switching between panes is visualized by sliding the other panes up/down.
// example:
// | <div dojoType="dijit.layout.AccordionContainer">
// | <div dojoType="dijit.layout.AccordionPane" title="pane 1">
// | <div dojoType="dijit.layout.ContentPane">...</div>
// | </div>
// | <div dojoType="dijit.layout.AccordionPane" title="pane 2">
// | <p>This is some text</p>
// || ...
// | </div>
// duration: Integer
// Amount of time (in ms) it takes to slide panes
duration: dijit.defaultDuration,
// _verticalSpace: Number
// Pixels of space available for the open pane
// (my content box size minus the cumulative size of all the title bars)
_verticalSpace: 0,
baseClass: "dijitAccordionContainer",
postCreate: function(){
this.domNode.style.overflow = "hidden";
this.inherited(arguments);
dijit.setWaiRole(this.domNode, "tablist");
},
startup: function(){
if(this._started){ return; }
this.inherited(arguments);
if(this.selectedChildWidget){
var style = this.selectedChildWidget.containerNode.style;
style.display = "";
style.overflow = "auto";
this.selectedChildWidget._buttonWidget._setSelectedState(true);
}
},
_getTargetHeight: function(/* Node */ node){
// summary:
// For the given node, returns the height that should be
// set to achieve our vertical space (subtract any padding
// we may have).
//
// This is used by the animations.
//
// TODO: I don't think this works correctly in IE quirks when an elements
// style.height including padding and borders
var cs = dojo.getComputedStyle(node);
return Math.max(this._verticalSpace - dojo._getPadBorderExtents(node, cs).h, 0);
},
layout: function(){
// Implement _LayoutWidget.layout() virtual method.
// Set the height of the open pane based on what room remains.
var openPane = this.selectedChildWidget;
// get cumulative height of all the title bars
var totalCollapsedHeight = 0;
dojo.forEach(this.getChildren(), function(child){
totalCollapsedHeight += child._buttonWidget.getTitleHeight();
});
var mySize = this._contentBox;
this._verticalSpace = mySize.h - totalCollapsedHeight;
// Memo size to make displayed child
this._containerContentBox = {
h: this._verticalSpace,
w: mySize.w
};
if(openPane){
openPane.resize(this._containerContentBox);
}
},
_setupChild: function(child){
// Overrides _LayoutWidget._setupChild().
// Setup clickable title to sit above the child widget,
// and stash pointer to it inside the widget itself.
child._buttonWidget = new dijit.layout._AccordionButton({
contentWidget: child,
title: child.title,
id: child.id + "_button",
parent: this
});
dojo.place(child._buttonWidget.domNode, child.domNode, "before");
this.inherited(arguments);
},
removeChild: function(child){
// Overrides _LayoutWidget.removeChild().
child._buttonWidget.destroy();
this.inherited(arguments);
},
getChildren: function(){
// Overrides _Container.getChildren() to ignore titles and only look at panes.
return dojo.filter(this.inherited(arguments), function(child){
return child.declaredClass != "dijit.layout._AccordionButton";
});
},
destroy: function(){
dojo.forEach(this.getChildren(), function(child){
child._buttonWidget.destroy();
});
this.inherited(arguments);
},
_transition: function(/*Widget?*/newWidget, /*Widget?*/oldWidget){
// Overrides StackContainer._transition() to provide sliding of title bars etc.
//TODO: should be able to replace this with calls to slideIn/slideOut
if(this._inTransition){ return; }
this._inTransition = true;
var animations = [];
var paneHeight = this._verticalSpace;
if(newWidget){
newWidget._buttonWidget.setSelected(true);
this._showChild(newWidget); // prepare widget to be slid in
// Size the new widget, in case this is the first time it's being shown,
// or I have been resized since the last time it was shown.
// Note that page must be visible for resizing to work.
if(this.doLayout && newWidget.resize){
newWidget.resize(this._containerContentBox);
}
var newContents = newWidget.domNode;
dojo.addClass(newContents, "dijitVisible");
dojo.removeClass(newContents, "dijitHidden");
var newContentsOverflow = newContents.style.overflow;
newContents.style.overflow = "hidden";
animations.push(dojo.animateProperty({
node: newContents,
duration: this.duration,
properties: {
height: { start: 1, end: this._getTargetHeight(newContents) }
},
onEnd: dojo.hitch(this, function(){
newContents.style.overflow = newContentsOverflow;
delete this._inTransition;
})
}));
}
if(oldWidget){
oldWidget._buttonWidget.setSelected(false);
var oldContents = oldWidget.domNode,
oldContentsOverflow = oldContents.style.overflow;
oldContents.style.overflow = "hidden";
animations.push(dojo.animateProperty({
node: oldContents,
duration: this.duration,
properties: {
height: { start: this._getTargetHeight(oldContents), end: 1 }
},
onEnd: function(){
dojo.addClass(oldContents, "dijitHidden");
dojo.removeClass(oldContents, "dijitVisible");
oldContents.style.overflow = oldContentsOverflow;
if(oldWidget.onHide){
oldWidget.onHide();
}
}
}));
}
dojo.fx.combine(animations).play();
},
// note: we are treating the container as controller here
_onKeyPress: function(/*Event*/ e, /*Widget*/ fromTitle){
// summary:
// Handle keypress events
// description:
// This is called from a handler on AccordionContainer.domNode
// (setup in StackContainer), and is also called directly from
// the click handler for accordion labels
if(this._inTransition || this.disabled || e.altKey || !(fromTitle || e.ctrlKey)){
if(this._inTransition){
dojo.stopEvent(e);
}
return;
}
var k = dojo.keys,
c = e.charOrCode;
if((fromTitle && (c == k.LEFT_ARROW || c == k.UP_ARROW)) ||
(e.ctrlKey && c == k.PAGE_UP)){
this._adjacent(false)._buttonWidget._onTitleClick();
dojo.stopEvent(e);
}else if((fromTitle && (c == k.RIGHT_ARROW || c == k.DOWN_ARROW)) ||
(e.ctrlKey && (c == k.PAGE_DOWN || c == k.TAB))){
this._adjacent(true)._buttonWidget._onTitleClick();
dojo.stopEvent(e);
}
}
}
);
dojo.declare("dijit.layout._AccordionButton",
[dijit._Widget, dijit._Templated],
{
// summary:
// The title bar to click to open up an accordion pane.
// Internal widget used by AccordionContainer.
// tags:
// private
templatePath: dojo.moduleUrl("dijit.layout", "templates/AccordionButton.html"),
attributeMap: dojo.mixin(dojo.clone(dijit.layout.ContentPane.prototype.attributeMap), {
title: {node: "titleTextNode", type: "innerHTML" }
}),
baseClass: "dijitAccordionTitle",
getParent: function(){
// summary:
// Returns the parent.
// tags:
// private
return this.parent;
},
postCreate: function(){
this.inherited(arguments);
dojo.setSelectable(this.domNode, false);
this.setSelected(this.selected);
var titleTextNodeId = dojo.attr(this.domNode,'id').replace(' ','_');
dojo.attr(this.titleTextNode, "id", titleTextNodeId+"_title");
dijit.setWaiState(this.focusNode, "labelledby", dojo.attr(this.titleTextNode, "id"));
},
getTitleHeight: function(){
// summary:
// Returns the height of the title dom node.
return dojo.marginBox(this.titleNode).h; // Integer
},
_onTitleClick: function(){
// summary:
// Callback when someone clicks my title.
var parent = this.getParent();
if(!parent._inTransition){
parent.selectChild(this.contentWidget);
dijit.focus(this.focusNode);
}
},
_onTitleEnter: function(){
// summary:
// Callback when someone hovers over my title.
dojo.addClass(this.focusNode, "dijitAccordionTitle-hover");
},
_onTitleLeave: function(){
// summary:
// Callback when someone stops hovering over my title.
dojo.removeClass(this.focusNode, "dijitAccordionTitle-hover");
},
_onTitleKeyPress: function(/*Event*/ evt){
return this.getParent()._onKeyPress(evt, this.contentWidget);
},
_setSelectedState: function(/*Boolean*/ isSelected){
this.selected = isSelected;
dojo[(isSelected ? "addClass" : "removeClass")](this.titleNode,"dijitAccordionTitle-selected");
dijit.setWaiState(this.focusNode, "expanded", isSelected);
dijit.setWaiState(this.focusNode, "selected", isSelected);
this.focusNode.setAttribute("tabIndex", isSelected ? "0" : "-1");
},
_handleFocus: function(/*Event*/e){
// summary:
// Handle the blur and focus state of this widget.
dojo[(e.type=="focus" ? "addClass" : "removeClass")](this.focusNode,"dijitAccordionFocused");
},
setSelected: function(/*Boolean*/ isSelected){
// summary:
// Change the selected state on this pane.
this._setSelectedState(isSelected);
if(isSelected){
var cw = this.contentWidget;
if(cw.onSelected){ cw.onSelected(); }
}
}
});