Improve output: distinguish between failed assertions (failures) and unexpected exceptions (errors), and print a filtered stack trace for any exception.
This commit is contained in:
commit
4f2e303079
1839 changed files with 235630 additions and 0 deletions
71
webapp/web/src/widget/AccordionContainer.js
Normal file
71
webapp/web/src/widget/AccordionContainer.js
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.AccordionContainer");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.AccordionPane");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.AccordionContainer",
|
||||
dojo.widget.HtmlWidget,
|
||||
{
|
||||
widgetType: "AccordionContainer",
|
||||
isContainer: true,
|
||||
labelNodeClass: "",
|
||||
containerNodeClass: "",
|
||||
allowCollapse: false,
|
||||
|
||||
addChild: function(widget, overrideContainerNode, pos, ref, insertIndex){
|
||||
if (widget.widgetType != "AccordionPane") {
|
||||
var wrapper=dojo.widget.createWidget("AccordionPane",{label: widget.label, open: widget.open, labelNodeClass: this.labelNodeClass, containerNodeClass: this.containerNodeClass, allowCollapse: this.allowCollapse });
|
||||
wrapper.addChild(widget);
|
||||
this.addWidgetAsDirectChild(wrapper);
|
||||
this.registerChild(wrapper);
|
||||
wrapper.setSizes();
|
||||
return wrapper;
|
||||
} else {
|
||||
dojo.html.addClass(widget.containerNode, this.containerNodeClass);
|
||||
dojo.html.addClass(widget.labelNode, this.labelNodeClass);
|
||||
this.addWidgetAsDirectChild(widget);
|
||||
this.registerChild(widget);
|
||||
widget.setSizes();
|
||||
return widget;
|
||||
}
|
||||
},
|
||||
|
||||
postCreate: function() {
|
||||
var tmpChildren = this.children;
|
||||
this.children=[];
|
||||
dojo.html.removeChildren(this.domNode);
|
||||
dojo.lang.forEach(tmpChildren, dojo.lang.hitch(this,"addChild"));
|
||||
},
|
||||
|
||||
removeChild: function(widget) {
|
||||
dojo.widget.AccordionContainer.superclass.removeChild.call(this, widget);
|
||||
if(this.children[0]){
|
||||
this.children[0].setSizes();
|
||||
}
|
||||
},
|
||||
|
||||
onResized: function(){
|
||||
this.children[0].setSizes();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// These arguments can be specified for the children of a Accordion
|
||||
// Since any widget can be specified as a child, mix them
|
||||
// into the base widget class. (This is a hack, but it's effective.)
|
||||
dojo.lang.extend(dojo.widget.Widget, {
|
||||
label: "",
|
||||
open: false
|
||||
});
|
||||
|
12
webapp/web/src/widget/AccordionPane.js
Normal file
12
webapp/web/src/widget/AccordionPane.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.AccordionPane");
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.AccordionPane");
|
83
webapp/web/src/widget/AnimatedPng.js
Normal file
83
webapp/web/src/widget/AnimatedPng.js
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.AnimatedPng");
|
||||
dojo.provide("dojo.widget.html.AnimatedPng");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.AnimatedPng",
|
||||
dojo.widget.HtmlWidget,
|
||||
{
|
||||
|
||||
widgetType: "AnimatedPng",
|
||||
isContainer: false,
|
||||
|
||||
domNode: null,
|
||||
width: 0,
|
||||
height: 0,
|
||||
aniSrc: '',
|
||||
interval: 100,
|
||||
|
||||
cellWidth: 0,
|
||||
cellHeight: 0,
|
||||
aniCols: 1,
|
||||
aniRows: 1,
|
||||
aniCells: 1,
|
||||
|
||||
blankSrc: dojo.uri.dojoUri("src/widget/templates/images/blank.gif"),
|
||||
|
||||
templateString: '<img class="dojoAnimatedPng" />',
|
||||
|
||||
postCreate: function(){
|
||||
this.cellWidth = this.width;
|
||||
this.cellHeight = this.height;
|
||||
|
||||
var img = new Image();
|
||||
var self = this;
|
||||
|
||||
img.onload = function(){ self.initAni(img.width, img.height); };
|
||||
img.src = this.aniSrc;
|
||||
},
|
||||
|
||||
initAni: function(w, h){
|
||||
|
||||
this.domNode.src = this.blankSrc;
|
||||
this.domNode.width = this.cellWidth;
|
||||
this.domNode.height = this.cellHeight;
|
||||
this.domNode.style.backgroundImage = 'url('+this.aniSrc+')';
|
||||
this.domNode.style.backgroundRepeat = 'no-repeat';
|
||||
|
||||
this.aniCols = Math.floor(w/this.cellWidth);
|
||||
this.aniRows = Math.floor(h/this.cellHeight);
|
||||
this.aniCells = this.aniCols * this.aniRows;
|
||||
this.aniFrame = 0;
|
||||
|
||||
window.setInterval(dojo.lang.hitch(this, 'tick'), this.interval);
|
||||
},
|
||||
|
||||
tick: function(){
|
||||
|
||||
this.aniFrame++;
|
||||
if (this.aniFrame == this.aniCells) this.aniFrame = 0;
|
||||
|
||||
var col = this.aniFrame % this.aniCols;
|
||||
var row = Math.floor(this.aniFrame / this.aniCols);
|
||||
|
||||
var bx = -1 * col * this.cellWidth;
|
||||
var by = -1 * row * this.cellHeight;
|
||||
|
||||
this.domNode.style.backgroundPosition = bx+'px '+by+'px';
|
||||
}
|
||||
}
|
||||
);
|
315
webapp/web/src/widget/Button.js
Normal file
315
webapp/web/src/widget/Button.js
Normal file
|
@ -0,0 +1,315 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Button");
|
||||
dojo.provide("dojo.widget.html.Button");
|
||||
|
||||
dojo.require("dojo.lang.extras");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.style");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.Button",
|
||||
dojo.widget.HtmlWidget,
|
||||
{
|
||||
widgetType: "Button",
|
||||
isContainer: true,
|
||||
|
||||
// Constructor arguments
|
||||
caption: "",
|
||||
disabled: false,
|
||||
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlButtonTemplate.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlButtonTemplate.css"),
|
||||
|
||||
// button images
|
||||
inactiveImg: "src/widget/templates/images/soriaButton-",
|
||||
activeImg: "src/widget/templates/images/soriaActive-",
|
||||
pressedImg: "src/widget/templates/images/soriaPressed-",
|
||||
disabledImg: "src/widget/templates/images/soriaDisabled-",
|
||||
width2height: 1.0/3.0,
|
||||
|
||||
// attach points
|
||||
containerNode: null,
|
||||
leftImage: null,
|
||||
centerImage: null,
|
||||
rightImage: null,
|
||||
|
||||
fillInTemplate: function(args, frag){
|
||||
if(this.caption != ""){
|
||||
this.containerNode.appendChild(document.createTextNode(this.caption));
|
||||
}
|
||||
dojo.html.disableSelection(this.containerNode);
|
||||
},
|
||||
|
||||
postCreate: function(args, frag){
|
||||
this.sizeMyself();
|
||||
},
|
||||
|
||||
sizeMyself: function(){
|
||||
// we cannot size correctly if any of our ancestors are hidden (display:none),
|
||||
// so temporarily attach to document.body
|
||||
if(this.domNode.parentNode){
|
||||
var placeHolder = document.createElement("span");
|
||||
dojo.dom.insertBefore(placeHolder, this.domNode);
|
||||
}
|
||||
dojo.html.body().appendChild(this.domNode);
|
||||
|
||||
this.sizeMyselfHelper();
|
||||
|
||||
// Put this.domNode back where it was originally
|
||||
if(placeHolder){
|
||||
dojo.dom.insertBefore(this.domNode, placeHolder);
|
||||
dojo.dom.removeNode(placeHolder);
|
||||
}
|
||||
},
|
||||
|
||||
sizeMyselfHelper: function(){
|
||||
this.height = dojo.style.getOuterHeight(this.containerNode);
|
||||
this.containerWidth = dojo.style.getOuterWidth(this.containerNode);
|
||||
var endWidth= this.height * this.width2height;
|
||||
|
||||
this.containerNode.style.left=endWidth+"px";
|
||||
|
||||
this.leftImage.height = this.rightImage.height = this.centerImage.height = this.height;
|
||||
this.leftImage.width = this.rightImage.width = endWidth+1;
|
||||
this.centerImage.width = this.containerWidth;
|
||||
this.centerImage.style.left=endWidth+"px";
|
||||
this._setImage(this.disabled ? this.disabledImg : this.inactiveImg);
|
||||
|
||||
if ( this.disabled ) {
|
||||
dojo.html.prependClass(this.domNode, "dojoButtonDisabled");
|
||||
} else {
|
||||
dojo.html.removeClass(this.domNode, "dojoButtonDisabled");
|
||||
}
|
||||
|
||||
this.domNode.style.height=this.height + "px";
|
||||
this.domNode.style.width= (this.containerWidth+2*endWidth) + "px";
|
||||
},
|
||||
|
||||
onMouseOver: function(e){
|
||||
if( this.disabled ){ return; }
|
||||
dojo.html.prependClass(this.domNode, "dojoButtonHover");
|
||||
this._setImage(this.activeImg);
|
||||
},
|
||||
|
||||
onMouseDown: function(e){
|
||||
if( this.disabled ){ return; }
|
||||
dojo.html.prependClass(this.domNode, "dojoButtonDepressed");
|
||||
dojo.html.removeClass(this.domNode, "dojoButtonHover");
|
||||
this._setImage(this.pressedImg);
|
||||
},
|
||||
onMouseUp: function(e){
|
||||
if( this.disabled ){ return; }
|
||||
dojo.html.prependClass(this.domNode, "dojoButtonHover");
|
||||
dojo.html.removeClass(this.domNode, "dojoButtonDepressed");
|
||||
this._setImage(this.activeImg);
|
||||
},
|
||||
|
||||
onMouseOut: function(e){
|
||||
if( this.disabled ){ return; }
|
||||
dojo.html.removeClass(this.domNode, "dojoButtonHover");
|
||||
this._setImage(this.inactiveImg);
|
||||
},
|
||||
|
||||
buttonClick: function(e){
|
||||
if( !this.disabled ) { this.onClick(e); }
|
||||
},
|
||||
|
||||
onClick: function(e) { },
|
||||
|
||||
_setImage: function(prefix){
|
||||
this.leftImage.src=dojo.uri.dojoUri(prefix + "l.gif");
|
||||
this.centerImage.src=dojo.uri.dojoUri(prefix + "c.gif");
|
||||
this.rightImage.src=dojo.uri.dojoUri(prefix + "r.gif");
|
||||
},
|
||||
|
||||
_toggleMenu: function(menuId){
|
||||
var menu = dojo.widget.getWidgetById(menuId);
|
||||
if ( !menu ) { return; }
|
||||
|
||||
if ( menu.open && !menu.isShowingNow) {
|
||||
var pos = dojo.style.getAbsolutePosition(this.domNode, false);
|
||||
menu.open(pos.x, pos.y+this.height, this);
|
||||
} else if ( menu.close && menu.isShowingNow ){
|
||||
menu.close();
|
||||
} else {
|
||||
menu.toggle();
|
||||
}
|
||||
},
|
||||
|
||||
setCaption: function(content){
|
||||
this.caption=content;
|
||||
this.containerNode.innerHTML=content;
|
||||
this.sizeMyself();
|
||||
},
|
||||
|
||||
setDisabled: function(disabled){
|
||||
this.disabled=disabled;
|
||||
this.sizeMyself();
|
||||
}
|
||||
});
|
||||
|
||||
/**** DropDownButton - push the button and a menu shows up *****/
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.DropDownButton",
|
||||
dojo.widget.html.Button,
|
||||
{
|
||||
widgetType: "DropDownButton",
|
||||
|
||||
menuId: "",
|
||||
|
||||
arrow: null,
|
||||
|
||||
downArrow: "src/widget/templates/images/whiteDownArrow.gif",
|
||||
disabledDownArrow: "src/widget/templates/images/whiteDownArrow.gif",
|
||||
|
||||
fillInTemplate: function(args, frag){
|
||||
dojo.widget.html.DropDownButton.superclass.fillInTemplate.call(this, args, frag);
|
||||
|
||||
this.arrow = document.createElement("img");
|
||||
dojo.html.setClass(this.arrow, "downArrow");
|
||||
},
|
||||
|
||||
sizeMyselfHelper: function(){
|
||||
// draw the arrow (todo: why is the arror in containerNode rather than outside it?)
|
||||
this.arrow.src = dojo.uri.dojoUri(this.disabled ? this.disabledDownArrow : this.downArrow);
|
||||
this.containerNode.appendChild(this.arrow);
|
||||
|
||||
dojo.widget.html.DropDownButton.superclass.sizeMyselfHelper.call(this);
|
||||
},
|
||||
|
||||
onClick: function (e){
|
||||
this._toggleMenu(this.menuId);
|
||||
}
|
||||
});
|
||||
|
||||
/**** ComboButton - left side is normal button, right side shows menu *****/
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.ComboButton",
|
||||
dojo.widget.html.Button,
|
||||
{
|
||||
widgetType: "ComboButton",
|
||||
|
||||
menuId: "",
|
||||
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlComboButtonTemplate.html"),
|
||||
|
||||
// attach points
|
||||
leftPart: null,
|
||||
rightPart: null,
|
||||
arrowBackgroundImage: null,
|
||||
|
||||
// constants
|
||||
splitWidth: 2, // pixels between left&right part of button
|
||||
arrowWidth: 5, // width of segment holding down arrow
|
||||
|
||||
sizeMyselfHelper: function(e){
|
||||
this.height = dojo.style.getOuterHeight(this.containerNode);
|
||||
this.containerWidth = dojo.style.getOuterWidth(this.containerNode);
|
||||
var endWidth= this.height/3;
|
||||
|
||||
// left part
|
||||
this.leftImage.height = this.rightImage.height = this.centerImage.height =
|
||||
this.arrowBackgroundImage.height = this.height;
|
||||
this.leftImage.width = endWidth+1;
|
||||
this.centerImage.width = this.containerWidth;
|
||||
this.leftPart.style.height = this.height + "px";
|
||||
this.leftPart.style.width = endWidth + this.containerWidth + "px";
|
||||
this._setImageL(this.disabled ? this.disabledImg : this.inactiveImg);
|
||||
|
||||
// right part
|
||||
this.arrowBackgroundImage.width=this.arrowWidth;
|
||||
this.rightImage.width = endWidth+1;
|
||||
this.rightPart.style.height = this.height + "px";
|
||||
this.rightPart.style.width = this.arrowWidth + endWidth + "px";
|
||||
this._setImageR(this.disabled ? this.disabledImg : this.inactiveImg);
|
||||
|
||||
// outer container
|
||||
this.domNode.style.height=this.height + "px";
|
||||
var totalWidth = this.containerWidth+this.splitWidth+this.arrowWidth+2*endWidth;
|
||||
this.domNode.style.width= totalWidth + "px";
|
||||
},
|
||||
|
||||
/** functions on left part of button**/
|
||||
leftOver: function(e){
|
||||
if( this.disabled ){ return; }
|
||||
dojo.html.prependClass(this.leftPart, "dojoButtonHover");
|
||||
this._setImageL(this.activeImg);
|
||||
},
|
||||
|
||||
leftDown: function(e){
|
||||
if( this.disabled ){ return; }
|
||||
dojo.html.prependClass(this.leftPart, "dojoButtonDepressed");
|
||||
dojo.html.removeClass(this.leftPart, "dojoButtonHover");
|
||||
this._setImageL(this.pressedImg);
|
||||
},
|
||||
leftUp: function(e){
|
||||
if( this.disabled ){ return; }
|
||||
dojo.html.prependClass(this.leftPart, "dojoButtonHover");
|
||||
dojo.html.removeClass(this.leftPart, "dojoButtonDepressed");
|
||||
this._setImageL(this.activeImg);
|
||||
},
|
||||
|
||||
leftOut: function(e){
|
||||
if( this.disabled ){ return; }
|
||||
dojo.html.removeClass(this.leftPart, "dojoButtonHover");
|
||||
this._setImageL(this.inactiveImg);
|
||||
},
|
||||
|
||||
leftClick: function(e){
|
||||
if ( !this.disabled ) {
|
||||
this.onClick(e);
|
||||
}
|
||||
},
|
||||
|
||||
_setImageL: function(prefix){
|
||||
this.leftImage.src=dojo.uri.dojoUri(prefix + "l.gif");
|
||||
this.centerImage.src=dojo.uri.dojoUri(prefix + "c.gif");
|
||||
},
|
||||
|
||||
/*** functions on right part of button ***/
|
||||
rightOver: function(e){
|
||||
if( this.disabled ){ return; }
|
||||
dojo.html.prependClass(this.rightPart, "dojoButtonHover");
|
||||
this._setImageR(this.activeImg);
|
||||
},
|
||||
|
||||
rightDown: function(e){
|
||||
if( this.disabled ){ return; }
|
||||
dojo.html.prependClass(this.rightPart, "dojoButtonDepressed");
|
||||
dojo.html.removeClass(this.rightPart, "dojoButtonHover");
|
||||
this._setImageR(this.pressedImg);
|
||||
},
|
||||
rightUp: function(e){
|
||||
if( this.disabled ){ return; }
|
||||
dojo.html.prependClass(this.rightPart, "dojoButtonHover");
|
||||
dojo.html.removeClass(this.rightPart, "dojoButtonDepressed");
|
||||
this._setImageR(this.activeImg);
|
||||
},
|
||||
|
||||
rightOut: function(e){
|
||||
if( this.disabled ){ return; }
|
||||
dojo.html.removeClass(this.rightPart, "dojoButtonHover");
|
||||
this._setImageR(this.inactiveImg);
|
||||
},
|
||||
|
||||
rightClick: function(e){
|
||||
if( this.disabled ){ return; }
|
||||
this._toggleMenu(this.menuId);
|
||||
},
|
||||
|
||||
_setImageR: function(prefix){
|
||||
this.arrowBackgroundImage.src=dojo.uri.dojoUri(prefix + "c.gif");
|
||||
this.rightImage.src=dojo.uri.dojoUri(prefix + "r.gif");
|
||||
}
|
||||
});
|
33
webapp/web/src/widget/Button2.js
Normal file
33
webapp/web/src/widget/Button2.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Button2");
|
||||
dojo.require("dojo.widget.Button");
|
||||
dojo.require("dojo.widget.*");
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:button2");
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:dropdownbutton2");
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:combobutton2");
|
||||
|
||||
dojo.deprecated("dojo.widget.Button2", "Use dojo.widget.Button instead", "0.4");
|
||||
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.Button2");
|
||||
|
||||
dojo.widget.Button2 = function(){}
|
||||
dojo.inherits(dojo.widget.Button2, dojo.widget.Button);
|
||||
dojo.lang.extend(dojo.widget.Button2, { widgetType: "Button2" });
|
||||
|
||||
dojo.widget.DropDownButton2 = function(){}
|
||||
dojo.inherits(dojo.widget.DropDownButton2, dojo.widget.DropDownButton);
|
||||
dojo.lang.extend(dojo.widget.DropDownButton2, { widgetType: "DropDownButton2" });
|
||||
|
||||
dojo.widget.ComboButton2 = function(){}
|
||||
dojo.inherits(dojo.widget.ComboButton2, dojo.widget.ComboButton);
|
||||
dojo.lang.extend(dojo.widget.ComboButton2, { widgetType: "ComboButton2" });
|
199
webapp/web/src/widget/Chart.js
vendored
Normal file
199
webapp/web/src/widget/Chart.js
vendored
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Chart");
|
||||
dojo.provide("dojo.widget.Chart.PlotTypes");
|
||||
dojo.provide("dojo.widget.Chart.DataSeries");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.graphics.color");
|
||||
dojo.require("dojo.graphics.color.hsl");
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:chart");
|
||||
|
||||
dojo.widget.Chart = function(){
|
||||
dojo.widget.Widget.call(this);
|
||||
this.widgetType = "Chart";
|
||||
this.isContainer = false;
|
||||
this.series = [];
|
||||
// FIXME: why is this a mixin method?
|
||||
this.assignColors = function(){
|
||||
var hue=30;
|
||||
var sat=120;
|
||||
var lum=120;
|
||||
var steps = Math.round(330/this.series.length);
|
||||
|
||||
for(var i=0; i<this.series.length; i++){
|
||||
var c=dojo.graphics.color.hsl2rgb(hue,sat,lum);
|
||||
if(!this.series[i].color){
|
||||
this.series[i].color = dojo.graphics.color.rgb2hex(c[0],c[1],c[2]);
|
||||
}
|
||||
hue += steps;
|
||||
}
|
||||
};
|
||||
}
|
||||
dojo.inherits(dojo.widget.Chart, dojo.widget.Widget);
|
||||
|
||||
dojo.widget.Chart.PlotTypes = {
|
||||
Bar:"bar",
|
||||
Line:"line",
|
||||
Scatter:"scatter",
|
||||
Bubble:"bubble"
|
||||
};
|
||||
|
||||
/*
|
||||
* Every chart has a set of data series; this is the series. Note that each
|
||||
* member of value is an object and in the minimum has 2 properties: .x and
|
||||
* .value.
|
||||
*/
|
||||
dojo.widget.Chart.DataSeries = function(key, label, plotType, color){
|
||||
// FIXME: why the hell are plot types specified neumerically? What is this? C?
|
||||
this.id = "DataSeries"+dojo.widget.Chart.DataSeries.count++;
|
||||
this.key = key;
|
||||
this.label = label||this.id;
|
||||
this.plotType = plotType||0;
|
||||
this.color = color;
|
||||
this.values = [];
|
||||
};
|
||||
|
||||
dojo.lang.extend(dojo.widget.Chart.DataSeries, {
|
||||
add: function(v){
|
||||
if(v.x==null||v.value==null){
|
||||
dojo.raise("dojo.widget.Chart.DataSeries.add: v must have both an 'x' and 'value' property.");
|
||||
}
|
||||
this.values.push(v);
|
||||
},
|
||||
|
||||
clear: function(){
|
||||
this.values=[];
|
||||
},
|
||||
|
||||
createRange: function(len){
|
||||
var idx = this.values.length-1;
|
||||
var length = (len||this.values.length);
|
||||
return { "index": idx, "length": length, "start":Math.max(idx-length,0) };
|
||||
},
|
||||
|
||||
// trend values
|
||||
getMean: function(len){
|
||||
var range = this.createRange(len);
|
||||
if(range.index<0){ return 0; }
|
||||
var t = 0;
|
||||
var c = 0;
|
||||
for(var i=range.index; i>=range.start; i--){
|
||||
var n = parseFloat(this.values[i].value);
|
||||
if(!isNaN(n)){ t += n; c++; }
|
||||
}
|
||||
t /= Math.max(c,1);
|
||||
return t;
|
||||
},
|
||||
|
||||
getMovingAverage: function(len){
|
||||
var range = this.createRange(len);
|
||||
if(range.index<0){ return 0; }
|
||||
var t = 0;
|
||||
var c = 0;
|
||||
for(var i=range.index; i>=range.start; i--){
|
||||
var n = parseFloat(this.values[i].value);
|
||||
if(!isNaN(n)){ t += n; c++; }
|
||||
}
|
||||
t /= Math.max(c,1);
|
||||
return t;
|
||||
},
|
||||
|
||||
getVariance: function(len){
|
||||
var range = this.createRange(len);
|
||||
if(range.index < 0){ return 0; }
|
||||
var t = 0; // FIXME: for tom: wtf are t, c, and s?
|
||||
var s = 0;
|
||||
var c = 0;
|
||||
for(var i=range.index; i>=range.start; i--){
|
||||
var n = parseFloat(this.values[i].value);
|
||||
if(!isNaN(n)){
|
||||
t += n;
|
||||
s += Math.pow(n,2);
|
||||
c++;
|
||||
}
|
||||
}
|
||||
return (s/c)-Math.pow(t/c,2);
|
||||
},
|
||||
|
||||
getStandardDeviation: function(len){
|
||||
return Math.sqrt(this.getVariance(len));
|
||||
},
|
||||
|
||||
getMax: function(len){
|
||||
var range = this.createRange(len);
|
||||
if(range.index < 0){ return 0; }
|
||||
var t = 0;
|
||||
for (var i=range.index; i>=range.start; i--){
|
||||
var n=parseFloat(this.values[i].value);
|
||||
if (!isNaN(n)){
|
||||
t=Math.max(n,t);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
},
|
||||
|
||||
getMin: function(len){
|
||||
var range=this.createRange(len);
|
||||
if(range.index < 0){ return 0; }
|
||||
var t = 0;
|
||||
for(var i=range.index; i>=range.start; i--){
|
||||
var n = parseFloat(this.values[i].value);
|
||||
if(!isNaN(n)){
|
||||
t=Math.min(n,t);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
},
|
||||
|
||||
getMedian: function(len){
|
||||
var range = this.createRange(len);
|
||||
|
||||
if(range.index<0){ return 0; }
|
||||
|
||||
var a = [];
|
||||
for (var i=range.index; i>=range.start; i--){
|
||||
var n=parseFloat(this.values[i].value);
|
||||
if (!isNaN(n)){
|
||||
var b=false;
|
||||
for(var j=0; j<a.length&&!b; j++){
|
||||
if (n==a[j]) b=true;
|
||||
}
|
||||
if(!b){ a.push(n); }
|
||||
}
|
||||
}
|
||||
a.sort();
|
||||
if(a.length>0){ return a[Math.ceil(a.length/2)]; }
|
||||
return 0;
|
||||
},
|
||||
|
||||
getMode: function(len){
|
||||
var range=this.createRange(len);
|
||||
if(range.index<0){ return 0; }
|
||||
var o = {};
|
||||
var ret = 0
|
||||
var m = 0;
|
||||
for(var i=range.index; i>=range.start; i--){
|
||||
var n=parseFloat(this.values[i].value);
|
||||
if(!isNaN(n)){
|
||||
if (!o[this.values[i].value]) o[this.values[i].value] = 1;
|
||||
else o[this.values[i].value]++;
|
||||
}
|
||||
}
|
||||
for(var p in o){
|
||||
if(m<o[p]){ m=o[p]; ret=p; }
|
||||
}
|
||||
return parseFloat(ret);
|
||||
}
|
||||
});
|
||||
|
||||
dojo.requireIf(dojo.render.svg.support.builtin, "dojo.widget.svg.Chart");
|
||||
dojo.requireIf(dojo.render.html.ie, "dojo.widget.vml.Chart");
|
13
webapp/web/src/widget/Checkbox.js
Normal file
13
webapp/web/src/widget/Checkbox.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Checkbox");
|
||||
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.Checkbox");
|
118
webapp/web/src/widget/CiviCrmDatePicker.js
Normal file
118
webapp/web/src/widget/CiviCrmDatePicker.js
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.CiviCrmDatePicker");
|
||||
dojo.provide("dojo.widget.HtmlCiviCrmDatePicker");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.widget.DatePicker");
|
||||
dojo.require("dojo.widget.html.DatePicker");
|
||||
dojo.require("dojo.widget.html.TimePicker");
|
||||
dojo.require("dojo.html");
|
||||
|
||||
dojo.widget.HtmlCiviCrmDatePicker = function(){
|
||||
this.widgetType = "CiviCrmDatePicker";
|
||||
this.idPrefix = "scheduled_date_time";
|
||||
this.mode = "datetime"; // can also be date or time
|
||||
|
||||
this.datePicker = null;
|
||||
this.timePicker = null;
|
||||
|
||||
// html nodes
|
||||
this.dateHolderTd = null;
|
||||
this.timeHolderTd = null;
|
||||
this.formItemsTd = null;
|
||||
this.formItemsTr = null;
|
||||
|
||||
this.monthSelect = null;
|
||||
this.daySelect = null;
|
||||
this.yearSelect = null;
|
||||
this.hourSelect = null;
|
||||
this.minSelect = null;
|
||||
this.apSelect = null;
|
||||
|
||||
this.templatePath = dojo.uri.dojoUri("src/widget/templates/HtmlCiviCrmDatePicker.html");
|
||||
|
||||
this.modeFormats = {
|
||||
date: "MdY",
|
||||
time: "hiA"
|
||||
};
|
||||
|
||||
this.formatMappings = {
|
||||
"M": "monthSelect",
|
||||
"d": "daySelect",
|
||||
"Y": "yearSelect",
|
||||
"h": "hourSelect",
|
||||
"i": "minSelect",
|
||||
"A": "apSelect"
|
||||
};
|
||||
|
||||
this.setDateSelects = function(){
|
||||
var dateObj = this.datePicker.date;
|
||||
this.monthSelect.value = new String(dateObj.getMonth()+1);
|
||||
this.daySelect.value = new String(dateObj.getDate());
|
||||
this.yearSelect.value = new String(dateObj.getFullYear());
|
||||
}
|
||||
|
||||
this.setTimeSelects = function(){
|
||||
var st = this.timePicker.selectedTime;
|
||||
this.hourSelect.value = new String(st.hour);
|
||||
this.minSelect.value = new String(st.minute);
|
||||
this.apSelect.value = st.amPm.toUpperCase();
|
||||
}
|
||||
|
||||
this.fillInTemplate = function(args, frag){
|
||||
var nr = frag["dojo:"+this.widgetType.toLowerCase()]["nodeRef"];
|
||||
var sref = {};
|
||||
while(nr.firstChild){
|
||||
if(nr.firstChild.name){
|
||||
sref[nr.firstChild.name] = nr.firstChild;
|
||||
}
|
||||
this.formItemsTd.appendChild(nr.firstChild);
|
||||
}
|
||||
|
||||
if(this.mode.indexOf("date") != -1){
|
||||
this.datePicker = dojo.widget.createWidget("DatePicker", {}, this.dateHolderTd);
|
||||
dojo.event.connect( this.datePicker, "onSetDate",
|
||||
this, "setDateSelects");
|
||||
|
||||
var mfd = this.modeFormats.date;
|
||||
for(var x=0; x<mfd.length; x++){
|
||||
this[this.formatMappings[mfd[x]]] = sref[this.idPrefix+"["+mfd[x]+"]"];
|
||||
}
|
||||
}
|
||||
if(this.mode.indexOf("time") != -1){
|
||||
this.timePicker = dojo.widget.createWidget("TimePicker", {}, this.timeHolderTd);
|
||||
dojo.event.connect( this.timePicker, "onSetTime",
|
||||
this, "setTimeSelects");
|
||||
var mfd = this.modeFormats.time;
|
||||
for(var x=0; x<mfd.length; x++){
|
||||
this[this.formatMappings[mfd[x]]] = sref[this.idPrefix+"["+mfd[x]+"]"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.unhide = function(){
|
||||
this.formItemsTr.style.display = "";
|
||||
}
|
||||
|
||||
this.postCreate = function(){
|
||||
dojo.event.kwConnect({
|
||||
type: "before",
|
||||
srcObj: dojo.html.getParentByType(this.domNode, "form"),
|
||||
srcFunc: "onsubmit",
|
||||
targetObj: this,
|
||||
targetFunc: "unhide"
|
||||
});
|
||||
}
|
||||
}
|
||||
dojo.inherits(dojo.widget.HtmlCiviCrmDatePicker, dojo.widget.HtmlWidget);
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:civicrmdatepicker");
|
||||
|
186
webapp/web/src/widget/ColorPalette.js
Normal file
186
webapp/web/src/widget/ColorPalette.js
Normal file
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.ColorPalette");
|
||||
dojo.provide("dojo.widget.html.ColorPalette");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.Toolbar");
|
||||
dojo.require("dojo.html");
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:ToolbarColorDialog");
|
||||
|
||||
dojo.widget.html.ToolbarColorDialog = function(){
|
||||
dojo.widget.html.ToolbarDialog.call(this);
|
||||
|
||||
/*
|
||||
FIXME: why the fuck did anyone ever think this kind of expensive iteration
|
||||
was a good idea?
|
||||
|
||||
for (var method in this.constructor.prototype) {
|
||||
this[method] = this.constructor.prototype[method];
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.ToolbarColorDialog, dojo.widget.html.ToolbarDialog);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.ToolbarColorDialog, {
|
||||
|
||||
widgetType: "ToolbarColorDialog",
|
||||
|
||||
palette: "7x10",
|
||||
|
||||
fillInTemplate: function (args, frag) {
|
||||
dojo.widget.html.ToolbarColorDialog.superclass.fillInTemplate.call(this, args, frag);
|
||||
this.dialog = dojo.widget.createWidget("ColorPalette", {palette: this.palette});
|
||||
this.dialog.domNode.style.position = "absolute";
|
||||
|
||||
dojo.event.connect(this.dialog, "onColorSelect", this, "_setValue");
|
||||
},
|
||||
|
||||
_setValue: function(color) {
|
||||
this._value = color;
|
||||
this._fireEvent("onSetValue", color);
|
||||
},
|
||||
|
||||
showDialog: function (e) {
|
||||
dojo.widget.html.ToolbarColorDialog.superclass.showDialog.call(this, e);
|
||||
var x = dojo.html.getAbsoluteX(this.domNode);
|
||||
var y = dojo.html.getAbsoluteY(this.domNode) + dojo.html.getInnerHeight(this.domNode);
|
||||
this.dialog.showAt(x, y);
|
||||
},
|
||||
|
||||
hideDialog: function (e) {
|
||||
dojo.widget.html.ToolbarColorDialog.superclass.hideDialog.call(this, e);
|
||||
this.dialog.hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:colorpalette");
|
||||
|
||||
dojo.widget.html.ColorPalette = function () {
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.ColorPalette, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.ColorPalette, {
|
||||
|
||||
widgetType: "colorpalette",
|
||||
|
||||
palette: "7x10",
|
||||
|
||||
bgIframe: null,
|
||||
|
||||
palettes: {
|
||||
"7x10": [["fff", "fcc", "fc9", "ff9", "ffc", "9f9", "9ff", "cff", "ccf", "fcf"],
|
||||
["ccc", "f66", "f96", "ff6", "ff3", "6f9", "3ff", "6ff", "99f", "f9f"],
|
||||
["c0c0c0", "f00", "f90", "fc6", "ff0", "3f3", "6cc", "3cf", "66c", "c6c"],
|
||||
["999", "c00", "f60", "fc3", "fc0", "3c0", "0cc", "36f", "63f", "c3c"],
|
||||
["666", "900", "c60", "c93", "990", "090", "399", "33f", "60c", "939"],
|
||||
["333", "600", "930", "963", "660", "060", "366", "009", "339", "636"],
|
||||
["000", "300", "630", "633", "330", "030", "033", "006", "309", "303"]],
|
||||
|
||||
"3x4": [["ffffff"/*white*/, "00ff00"/*lime*/, "008000"/*green*/, "0000ff"/*blue*/],
|
||||
["c0c0c0"/*silver*/, "ffff00"/*yellow*/, "ff00ff"/*fuchsia*/, "000080"/*navy*/],
|
||||
["808080"/*gray*/, "ff0000"/*red*/, "800080"/*purple*/, "000000"/*black*/]]
|
||||
//["00ffff"/*aqua*/, "808000"/*olive*/, "800000"/*maroon*/, "008080"/*teal*/]];
|
||||
},
|
||||
|
||||
buildRendering: function () {
|
||||
|
||||
this.domNode = document.createElement("table");
|
||||
dojo.html.disableSelection(this.domNode);
|
||||
dojo.event.connect(this.domNode, "onmousedown", function (e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
with (this.domNode) { // set the table's properties
|
||||
cellPadding = "0"; cellSpacing = "1"; border = "1";
|
||||
style.backgroundColor = "white"; //style.position = "absolute";
|
||||
}
|
||||
var tbody = document.createElement("tbody");
|
||||
this.domNode.appendChild(tbody);
|
||||
var colors = this.palettes[this.palette];
|
||||
for (var i = 0; i < colors.length; i++) {
|
||||
var tr = document.createElement("tr");
|
||||
for (var j = 0; j < colors[i].length; j++) {
|
||||
if (colors[i][j].length == 3) {
|
||||
colors[i][j] = colors[i][j].replace(/(.)(.)(.)/, "$1$1$2$2$3$3");
|
||||
}
|
||||
|
||||
var td = document.createElement("td");
|
||||
with (td.style) {
|
||||
backgroundColor = "#" + colors[i][j];
|
||||
border = "1px solid gray";
|
||||
width = height = "15px";
|
||||
fontSize = "1px";
|
||||
}
|
||||
|
||||
td.color = "#" + colors[i][j];
|
||||
|
||||
td.onmouseover = function (e) { this.style.borderColor = "white"; }
|
||||
td.onmouseout = function (e) { this.style.borderColor = "gray"; }
|
||||
dojo.event.connect(td, "onmousedown", this, "click");
|
||||
|
||||
td.innerHTML = " ";
|
||||
tr.appendChild(td);
|
||||
}
|
||||
tbody.appendChild(tr);
|
||||
}
|
||||
|
||||
if(dojo.render.html.ie){
|
||||
this.bgIframe = document.createElement("<iframe frameborder='0' src='javascript:void(0);'>");
|
||||
with(this.bgIframe.style){
|
||||
position = "absolute";
|
||||
left = top = "0px";
|
||||
display = "none";
|
||||
}
|
||||
document.body.appendChild(this.bgIframe);
|
||||
dojo.style.setOpacity(this.bgIframe, 0);
|
||||
}
|
||||
},
|
||||
|
||||
click: function (e) {
|
||||
this.onColorSelect(e.currentTarget.color);
|
||||
e.currentTarget.style.borderColor = "gray";
|
||||
},
|
||||
|
||||
onColorSelect: function (color) { },
|
||||
|
||||
hide: function (){
|
||||
this.domNode.parentNode.removeChild(this.domNode);
|
||||
if(this.bgIframe){
|
||||
this.bgIframe.style.display = "none";
|
||||
}
|
||||
},
|
||||
|
||||
showAt: function (x, y) {
|
||||
with(this.domNode.style){
|
||||
top = y + "px";
|
||||
left = x + "px";
|
||||
zIndex = 999;
|
||||
}
|
||||
document.body.appendChild(this.domNode);
|
||||
if(this.bgIframe){
|
||||
with(this.bgIframe.style){
|
||||
display = "block";
|
||||
top = y + "px";
|
||||
left = x + "px";
|
||||
zIndex = 998;
|
||||
width = dojo.html.getOuterWidth(this.domNode) + "px";
|
||||
height = dojo.html.getOuterHeight(this.domNode) + "px";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
});
|
236
webapp/web/src/widget/ComboBox.js
Normal file
236
webapp/web/src/widget/ComboBox.js
Normal file
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.ComboBox");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.event.*");
|
||||
|
||||
dojo.widget.incrementalComboBoxDataProvider = function(url, limit, timeout){
|
||||
this.searchUrl = url;
|
||||
this.inFlight = false;
|
||||
this.activeRequest = null;
|
||||
this.allowCache = false;
|
||||
|
||||
this.cache = {};
|
||||
|
||||
this.init = function(cbox){
|
||||
this.searchUrl = cbox.dataUrl;
|
||||
}
|
||||
|
||||
this.addToCache = function(keyword, data){
|
||||
if(this.allowCache){
|
||||
this.cache[keyword] = data;
|
||||
}
|
||||
}
|
||||
|
||||
this.startSearch = function(searchStr, type, ignoreLimit){
|
||||
if(this.inFlight){
|
||||
// FIXME: implement backoff!
|
||||
}
|
||||
var tss = encodeURIComponent(searchStr);
|
||||
var realUrl = dojo.string.paramString(this.searchUrl, {"searchString": tss});
|
||||
var _this = this;
|
||||
var request = dojo.io.bind({
|
||||
url: realUrl,
|
||||
method: "get",
|
||||
mimetype: "text/json",
|
||||
load: function(type, data, evt){
|
||||
_this.inFlight = false;
|
||||
if(!dojo.lang.isArray(data)){
|
||||
var arrData = [];
|
||||
for(var key in data){
|
||||
arrData.push([data[key], key]);
|
||||
}
|
||||
data = arrData;
|
||||
}
|
||||
_this.addToCache(searchStr, data);
|
||||
_this.provideSearchResults(data);
|
||||
}
|
||||
});
|
||||
this.inFlight = true;
|
||||
}
|
||||
}
|
||||
|
||||
dojo.widget.ComboBoxDataProvider = function(dataPairs, limit, timeout){
|
||||
// NOTE: this data provider is designed as a naive reference
|
||||
// implementation, and as such it is written more for readability than
|
||||
// speed. A deployable data provider would implement lookups, search
|
||||
// caching (and invalidation), and a significantly less naive data
|
||||
// structure for storage of items.
|
||||
|
||||
this.data = [];
|
||||
this.searchTimeout = 500;
|
||||
this.searchLimit = 30;
|
||||
this.searchType = "STARTSTRING"; // may also be "STARTWORD" or "SUBSTRING"
|
||||
this.caseSensitive = false;
|
||||
// for caching optimizations
|
||||
this._lastSearch = "";
|
||||
this._lastSearchResults = null;
|
||||
|
||||
this.init = function(cbox, node){
|
||||
if(!dojo.string.isBlank(cbox.dataUrl)){
|
||||
this.getData(cbox.dataUrl);
|
||||
}else{
|
||||
// check to see if we can populate the list from <option> elements
|
||||
if((node)&&(node.nodeName.toLowerCase() == "select")){
|
||||
// NOTE: we're not handling <optgroup> here yet
|
||||
var opts = node.getElementsByTagName("option");
|
||||
var ol = opts.length;
|
||||
var data = [];
|
||||
for(var x=0; x<ol; x++){
|
||||
var keyValArr = [new String(opts[x].innerHTML), new String(opts[x].value)];
|
||||
data.push(keyValArr);
|
||||
if(opts[x].selected){
|
||||
cbox.setAllValues(keyValArr[0], keyValArr[1]);
|
||||
}
|
||||
}
|
||||
this.setData(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.getData = function(url){
|
||||
dojo.io.bind({
|
||||
url: url,
|
||||
load: dojo.lang.hitch(this, function(type, data, evt){
|
||||
if(!dojo.lang.isArray(data)){
|
||||
var arrData = [];
|
||||
for(var key in data){
|
||||
arrData.push([data[key], key]);
|
||||
}
|
||||
data = arrData;
|
||||
}
|
||||
this.setData(data);
|
||||
}),
|
||||
mimetype: "text/json"
|
||||
});
|
||||
}
|
||||
|
||||
this.startSearch = function(searchStr, type, ignoreLimit){
|
||||
// FIXME: need to add timeout handling here!!
|
||||
this._preformSearch(searchStr, type, ignoreLimit);
|
||||
}
|
||||
|
||||
this._preformSearch = function(searchStr, type, ignoreLimit){
|
||||
//
|
||||
// NOTE: this search is LINEAR, which means that it exhibits perhaps
|
||||
// the worst possible speed characteristics of any search type. It's
|
||||
// written this way to outline the responsibilities and interfaces for
|
||||
// a search.
|
||||
//
|
||||
var st = type||this.searchType;
|
||||
// FIXME: this is just an example search, which means that we implement
|
||||
// only a linear search without any of the attendant (useful!) optimizations
|
||||
var ret = [];
|
||||
if(!this.caseSensitive){
|
||||
searchStr = searchStr.toLowerCase();
|
||||
}
|
||||
for(var x=0; x<this.data.length; x++){
|
||||
if((!ignoreLimit)&&(ret.length >= this.searchLimit)){
|
||||
break;
|
||||
}
|
||||
// FIXME: we should avoid copies if possible!
|
||||
var dataLabel = new String((!this.caseSensitive) ? this.data[x][0].toLowerCase() : this.data[x][0]);
|
||||
if(dataLabel.length < searchStr.length){
|
||||
// this won't ever be a good search, will it? What if we start
|
||||
// to support regex search?
|
||||
continue;
|
||||
}
|
||||
|
||||
if(st == "STARTSTRING"){
|
||||
// jum.debug(dataLabel.substr(0, searchStr.length))
|
||||
// jum.debug(searchStr);
|
||||
if(searchStr == dataLabel.substr(0, searchStr.length)){
|
||||
ret.push(this.data[x]);
|
||||
}
|
||||
}else if(st == "SUBSTRING"){
|
||||
// this one is a gimmie
|
||||
if(dataLabel.indexOf(searchStr) >= 0){
|
||||
ret.push(this.data[x]);
|
||||
}
|
||||
}else if(st == "STARTWORD"){
|
||||
// do a substring search and then attempt to determine if the
|
||||
// preceeding char was the beginning of the string or a
|
||||
// whitespace char.
|
||||
var idx = dataLabel.indexOf(searchStr);
|
||||
if(idx == 0){
|
||||
// implicit match
|
||||
ret.push(this.data[x]);
|
||||
}
|
||||
if(idx <= 0){
|
||||
// if we didn't match or implicily matched, march onward
|
||||
continue;
|
||||
}
|
||||
// otherwise, we have to go figure out if the match was at the
|
||||
// start of a word...
|
||||
// this code is taken almost directy from nWidgets
|
||||
var matches = false;
|
||||
while(idx!=-1){
|
||||
// make sure the match either starts whole string, or
|
||||
// follows a space, or follows some punctuation
|
||||
if(" ,/(".indexOf(dataLabel.charAt(idx-1)) != -1){
|
||||
// FIXME: what about tab chars?
|
||||
matches = true; break;
|
||||
}
|
||||
idx = dataLabel.indexOf(searchStr, idx+1);
|
||||
}
|
||||
if(!matches){
|
||||
continue;
|
||||
}else{
|
||||
ret.push(this.data[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.provideSearchResults(ret);
|
||||
}
|
||||
|
||||
this.provideSearchResults = function(resultsDataPairs){
|
||||
}
|
||||
|
||||
this.addData = function(pairs){
|
||||
// FIXME: incredibly naive and slow!
|
||||
this.data = this.data.concat(pairs);
|
||||
}
|
||||
|
||||
this.setData = function(pdata){
|
||||
// populate this.data and initialize lookup structures
|
||||
this.data = pdata;
|
||||
}
|
||||
|
||||
if(dataPairs){
|
||||
this.setData(dataPairs);
|
||||
}
|
||||
}
|
||||
|
||||
dojo.declare(
|
||||
"dojo.widget.ComboBox",
|
||||
null,
|
||||
{
|
||||
widgetType: "ComboBox",
|
||||
isContainer: false,
|
||||
|
||||
forceValidOption: false,
|
||||
searchType: "stringstart",
|
||||
dataProvider: null,
|
||||
|
||||
startSearch: function(searchString){},
|
||||
openResultList: function(results){},
|
||||
clearResultList: function(){},
|
||||
hideResultList: function(){},
|
||||
selectNextResult: function(){},
|
||||
selectPrevResult: function(){},
|
||||
setSelectedResult: function(){}
|
||||
}
|
||||
);
|
||||
|
||||
// render-specific includes
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.ComboBox");
|
||||
|
16
webapp/web/src/widget/ContentPane.js
Normal file
16
webapp/web/src/widget/ContentPane.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
// This widget doesn't do anything; is basically the same as <div>.
|
||||
// It's useful as a child of LayoutContainer, SplitContainer, or TabContainer.
|
||||
// But note that those classes can contain any widget as a child.
|
||||
|
||||
dojo.provide("dojo.widget.ContentPane");
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.ContentPane");
|
33
webapp/web/src/widget/ContextMenu.js
Normal file
33
webapp/web/src/widget/ContextMenu.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.ContextMenu");
|
||||
|
||||
dojo.deprecated("dojo.widget.ContextMenu", "use dojo.widget.Menu2", "0.4");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.DomWidget");
|
||||
|
||||
dojo.widget.ContextMenu = function(){
|
||||
dojo.widget.Widget.call(this);
|
||||
this.widgetType = "ContextMenu";
|
||||
this.isContainer = true;
|
||||
this.isOpened = false;
|
||||
|
||||
// copy children widgets output directly to parent (this node), to avoid
|
||||
// errors trying to insert an <li> under a <div>
|
||||
this.snarfChildDomOutput = true;
|
||||
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.ContextMenu, dojo.widget.Widget);
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:contextmenu");
|
||||
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.ContextMenu");
|
61
webapp/web/src/widget/DatePicker.js
Normal file
61
webapp/web/src/widget/DatePicker.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.DatePicker");
|
||||
dojo.provide("dojo.widget.DatePicker.util");
|
||||
dojo.require("dojo.widget.DomWidget");
|
||||
dojo.require("dojo.date");
|
||||
|
||||
// NOTE: this function is only used as mixin (never as a constructor)
|
||||
dojo.widget.DatePicker = function() {
|
||||
// the following aliases prevent breaking people using 0.2.x
|
||||
this.months = dojo.date.months,
|
||||
this.weekdays = dojo.date.days,
|
||||
this.toRfcDate = dojo.widget.DatePicker.util.toRfcDate,
|
||||
this.fromRfcDate = dojo.widget.DatePicker.util.fromRfcDate,
|
||||
this.initFirstSaturday = dojo.widget.DatePicker.util.initFirstSaturday
|
||||
};
|
||||
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.DatePicker");
|
||||
|
||||
dojo.widget.DatePicker.util = new function() {
|
||||
this.months = dojo.date.months;
|
||||
this.weekdays = dojo.date.days;
|
||||
|
||||
this.toRfcDate = function(jsDate) {
|
||||
if(!jsDate) {
|
||||
var jsDate = new Date();
|
||||
}
|
||||
// because this is a date picker and not a time picker, we don't return a time
|
||||
return dojo.date.format(jsDate, "%Y-%m-%d");
|
||||
}
|
||||
|
||||
this.fromRfcDate = function(rfcDate) {
|
||||
// backwards compatible support for use of "any" instead of just not
|
||||
// including the time
|
||||
if(rfcDate.indexOf("Tany")!=-1) {
|
||||
rfcDate = rfcDate.replace("Tany","");
|
||||
}
|
||||
var jsDate = new Date();
|
||||
dojo.date.setIso8601(jsDate, rfcDate);
|
||||
return jsDate;
|
||||
}
|
||||
|
||||
this.initFirstSaturday = function(month, year) {
|
||||
if(!month) {
|
||||
month = this.date.getMonth();
|
||||
}
|
||||
if(!year) {
|
||||
year = this.date.getFullYear();
|
||||
}
|
||||
var firstOfMonth = new Date(year, month, 1);
|
||||
return {year: year, month: month, date: 7 - firstOfMonth.getDay()};
|
||||
}
|
||||
}
|
22
webapp/web/src/widget/DebugConsole.js
Normal file
22
webapp/web/src/widget/DebugConsole.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.DebugConsole");
|
||||
dojo.require("dojo.widget.Widget");
|
||||
|
||||
dojo.widget.DebugConsole= function(){
|
||||
dojo.widget.Widget.call(this);
|
||||
|
||||
this.widgetType = "DebugConsole";
|
||||
this.isContainer = true;
|
||||
}
|
||||
dojo.inherits(dojo.widget.DebugConsole, dojo.widget.Widget);
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:debugconsole");
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.DebugConsole");
|
269
webapp/web/src/widget/Dialog.js
Normal file
269
webapp/web/src/widget/Dialog.js
Normal file
|
@ -0,0 +1,269 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Dialog");
|
||||
dojo.provide("dojo.widget.html.Dialog");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.ContentPane");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.graphics.color");
|
||||
dojo.require("dojo.html");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.Dialog",
|
||||
dojo.widget.html.ContentPane,
|
||||
{
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlDialog.html"),
|
||||
isContainer: true,
|
||||
_scrollConnected: false,
|
||||
|
||||
// provide a focusable element or element id if you need to
|
||||
// work around FF's tendency to send focus into outer space on hide
|
||||
focusElement: "",
|
||||
|
||||
bg: null,
|
||||
bgColor: "black",
|
||||
bgOpacity: 0.4,
|
||||
followScroll: true,
|
||||
_fromTrap: false,
|
||||
anim: null,
|
||||
blockDuration: 0,
|
||||
lifetime: 0,
|
||||
|
||||
trapTabs: function(e){
|
||||
if(e.target == this.tabStart) {
|
||||
if(this._fromTrap) {
|
||||
this._fromTrap = false;
|
||||
} else {
|
||||
this._fromTrap = true;
|
||||
this.tabEnd.focus();
|
||||
}
|
||||
} else if(e.target == this.tabEnd) {
|
||||
if(this._fromTrap) {
|
||||
this._fromTrap = false;
|
||||
} else {
|
||||
this._fromTrap = true;
|
||||
this.tabStart.focus();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
clearTrap: function(e) {
|
||||
var _this = this;
|
||||
setTimeout(function() {
|
||||
_this._fromTrap = false;
|
||||
}, 100);
|
||||
},
|
||||
|
||||
postCreate: function(args, frag, parentComp) {
|
||||
with(this.domNode.style) {
|
||||
position = "absolute";
|
||||
zIndex = 999;
|
||||
display = "none";
|
||||
overflow = "visible";
|
||||
}
|
||||
var b = document.body;
|
||||
b.appendChild(this.domNode);
|
||||
|
||||
this.bg = document.createElement("div");
|
||||
this.bg.className = "dialogUnderlay";
|
||||
with(this.bg.style) {
|
||||
position = "absolute";
|
||||
left = top = "0px";
|
||||
zIndex = 998;
|
||||
display = "none";
|
||||
}
|
||||
this.setBackgroundColor(this.bgColor);
|
||||
b.appendChild(this.bg);
|
||||
|
||||
this.bgIframe = new dojo.html.BackgroundIframe(this.bg);
|
||||
},
|
||||
|
||||
setBackgroundColor: function(color) {
|
||||
if(arguments.length >= 3) {
|
||||
color = new dojo.graphics.color.Color(arguments[0], arguments[1], arguments[2]);
|
||||
} else {
|
||||
color = new dojo.graphics.color.Color(color);
|
||||
}
|
||||
this.bg.style.backgroundColor = color.toString();
|
||||
return this.bgColor = color;
|
||||
},
|
||||
|
||||
setBackgroundOpacity: function(op) {
|
||||
if(arguments.length == 0) { op = this.bgOpacity; }
|
||||
dojo.style.setOpacity(this.bg, op);
|
||||
try {
|
||||
this.bgOpacity = dojo.style.getOpacity(this.bg);
|
||||
} catch (e) {
|
||||
this.bgOpacity = op;
|
||||
}
|
||||
return this.bgOpacity;
|
||||
},
|
||||
|
||||
sizeBackground: function() {
|
||||
if(this.bgOpacity > 0) {
|
||||
var h = Math.max(
|
||||
document.documentElement.scrollHeight || document.body.scrollHeight,
|
||||
dojo.html.getViewportHeight());
|
||||
var w = dojo.html.getViewportWidth();
|
||||
this.bg.style.width = w + "px";
|
||||
this.bg.style.height = h + "px";
|
||||
}
|
||||
this.bgIframe.onResized();
|
||||
},
|
||||
|
||||
showBackground: function() {
|
||||
this.sizeBackground();
|
||||
if(this.bgOpacity > 0) {
|
||||
this.bg.style.display = "block";
|
||||
}
|
||||
},
|
||||
|
||||
placeDialog: function() {
|
||||
var scroll_offset = dojo.html.getScrollOffset();
|
||||
var viewport_size = dojo.html.getViewportSize();
|
||||
|
||||
// find the size of the dialog
|
||||
var w = dojo.style.getOuterWidth(this.containerNode);
|
||||
var h = dojo.style.getOuterHeight(this.containerNode);
|
||||
|
||||
var x = scroll_offset[0] + (viewport_size[0] - w)/2;
|
||||
var y = scroll_offset[1] + (viewport_size[1] - h)/2;
|
||||
|
||||
with(this.domNode.style) {
|
||||
left = x + "px";
|
||||
top = y + "px";
|
||||
}
|
||||
},
|
||||
|
||||
show: function() {
|
||||
this.setBackgroundOpacity();
|
||||
this.showBackground();
|
||||
|
||||
dojo.widget.html.Dialog.superclass.show.call(this);
|
||||
|
||||
// FIXME: moz doesn't generate onscroll events for mouse or key scrolling (wtf)
|
||||
// we should create a fake event by polling the scrolltop/scrollleft every X ms.
|
||||
// this smells like it should be a dojo feature rather than just for this widget.
|
||||
|
||||
if (this.followScroll && !this._scrollConnected){
|
||||
this._scrollConnected = true;
|
||||
dojo.event.connect(window, "onscroll", this, "onScroll");
|
||||
}
|
||||
|
||||
if(this.lifetime){
|
||||
this.timeRemaining = this.lifetime;
|
||||
if(!this.blockDuration){
|
||||
dojo.event.connect(this.bg, "onclick", this, "hide");
|
||||
}else{
|
||||
dojo.event.disconnect(this.bg, "onclick", this, "hide");
|
||||
}
|
||||
if(this.timerNode){
|
||||
this.timerNode.innerHTML = Math.ceil(this.timeRemaining/1000);
|
||||
}
|
||||
if(this.blockDuration && this.closeNode){
|
||||
if(this.lifetime > this.blockDuration){
|
||||
this.closeNode.style.visibility = "hidden";
|
||||
}else{
|
||||
this.closeNode.style.display = "none";
|
||||
}
|
||||
}
|
||||
this.timer = setInterval(dojo.lang.hitch(this, "onTick"), 100);
|
||||
}
|
||||
|
||||
this.checkSize();
|
||||
},
|
||||
|
||||
onLoad: function(){
|
||||
// when href is specified we need to reposition
|
||||
// the dialog after the data is loaded
|
||||
this.placeDialog();
|
||||
},
|
||||
|
||||
fillInTemplate: function(){
|
||||
// dojo.event.connect(this.domNode, "onclick", this, "killEvent");
|
||||
},
|
||||
|
||||
hide: function(){
|
||||
// workaround for FF focus going into outer space
|
||||
if (this.focusElement) {
|
||||
dojo.byId(this.focusElement).focus();
|
||||
dojo.byId(this.focusElement).blur();
|
||||
}
|
||||
|
||||
if(this.timer){
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
|
||||
this.bg.style.display = "none";
|
||||
this.bg.style.width = this.bg.style.height = "1px";
|
||||
|
||||
dojo.widget.html.Dialog.superclass.hide.call(this);
|
||||
|
||||
if (this._scrollConnected){
|
||||
this._scrollConnected = false;
|
||||
dojo.event.disconnect(window, "onscroll", this, "onScroll");
|
||||
}
|
||||
},
|
||||
|
||||
setTimerNode: function(node){
|
||||
this.timerNode = node;
|
||||
},
|
||||
|
||||
setCloseControl: function(node) {
|
||||
this.closeNode = node;
|
||||
dojo.event.connect(node, "onclick", this, "hide");
|
||||
},
|
||||
|
||||
setShowControl: function(node) {
|
||||
dojo.event.connect(node, "onclick", this, "show");
|
||||
},
|
||||
|
||||
onTick: function(){
|
||||
if(this.timer){
|
||||
this.timeRemaining -= 100;
|
||||
if(this.lifetime - this.timeRemaining >= this.blockDuration){
|
||||
dojo.event.connect(this.bg, "onclick", this, "hide");
|
||||
if(this.closeNode){
|
||||
this.closeNode.style.visibility = "visible";
|
||||
}
|
||||
}
|
||||
if(!this.timeRemaining){
|
||||
clearInterval(this.timer);
|
||||
this.hide();
|
||||
}else if(this.timerNode){
|
||||
this.timerNode.innerHTML = Math.ceil(this.timeRemaining/1000);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onScroll: function(){
|
||||
this.placeDialog();
|
||||
this.domNode.style.display = "block";
|
||||
},
|
||||
|
||||
// Called when the browser window's size is changed
|
||||
checkSize: function() {
|
||||
if(this.isShowing()){
|
||||
this.sizeBackground();
|
||||
this.placeDialog();
|
||||
this.domNode.style.display="block";
|
||||
this.onResized();
|
||||
}
|
||||
},
|
||||
|
||||
killEvent: function(evt){
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
}
|
||||
|
||||
}
|
||||
);
|
12
webapp/web/src/widget/DocPane.js
Normal file
12
webapp/web/src/widget/DocPane.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.DocPane");
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.DocPane");
|
593
webapp/web/src/widget/DomWidget.js
Normal file
593
webapp/web/src/widget/DomWidget.js
Normal file
|
@ -0,0 +1,593 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.DomWidget");
|
||||
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.widget.Widget");
|
||||
dojo.require("dojo.dom");
|
||||
dojo.require("dojo.xml.Parse");
|
||||
dojo.require("dojo.uri.*");
|
||||
dojo.require("dojo.lang.func");
|
||||
dojo.require("dojo.lang.extras");
|
||||
|
||||
dojo.widget._cssFiles = {};
|
||||
dojo.widget._cssStrings = {};
|
||||
dojo.widget._templateCache = {};
|
||||
|
||||
dojo.widget.defaultStrings = {
|
||||
dojoRoot: dojo.hostenv.getBaseScriptUri(),
|
||||
baseScriptUri: dojo.hostenv.getBaseScriptUri()
|
||||
};
|
||||
|
||||
dojo.widget.buildFromTemplate = function() {
|
||||
dojo.lang.forward("fillFromTemplateCache");
|
||||
}
|
||||
|
||||
// static method to build from a template w/ or w/o a real widget in place
|
||||
dojo.widget.fillFromTemplateCache = function(obj, templatePath, templateCssPath, templateString, avoidCache){
|
||||
// dojo.debug("avoidCache:", avoidCache);
|
||||
var tpath = templatePath || obj.templatePath;
|
||||
var cpath = templateCssPath || obj.templateCssPath;
|
||||
|
||||
// DEPRECATED: use Uri objects, not strings
|
||||
if (tpath && !(tpath instanceof dojo.uri.Uri)) {
|
||||
tpath = dojo.uri.dojoUri(tpath);
|
||||
dojo.deprecated("templatePath should be of type dojo.uri.Uri", null, "0.4");
|
||||
}
|
||||
if (cpath && !(cpath instanceof dojo.uri.Uri)) {
|
||||
cpath = dojo.uri.dojoUri(cpath);
|
||||
dojo.deprecated("templateCssPath should be of type dojo.uri.Uri", null, "0.4");
|
||||
}
|
||||
|
||||
var tmplts = dojo.widget._templateCache;
|
||||
if(!obj["widgetType"]) { // don't have a real template here
|
||||
do {
|
||||
var dummyName = "__dummyTemplate__" + dojo.widget._templateCache.dummyCount++;
|
||||
} while(tmplts[dummyName]);
|
||||
obj.widgetType = dummyName;
|
||||
}
|
||||
var wt = obj.widgetType;
|
||||
|
||||
if(cpath && !dojo.widget._cssFiles[cpath.toString()]){
|
||||
if((!obj.templateCssString)&&(cpath)){
|
||||
obj.templateCssString = dojo.hostenv.getText(cpath);
|
||||
obj.templateCssPath = null;
|
||||
}
|
||||
if((obj["templateCssString"])&&(!obj.templateCssString["loaded"])){
|
||||
dojo.style.insertCssText(obj.templateCssString, null, cpath);
|
||||
if(!obj.templateCssString){ obj.templateCssString = ""; }
|
||||
obj.templateCssString.loaded = true;
|
||||
}
|
||||
dojo.widget._cssFiles[cpath.toString()] = true;
|
||||
}
|
||||
|
||||
var ts = tmplts[wt];
|
||||
if(!ts){
|
||||
tmplts[wt] = { "string": null, "node": null };
|
||||
if(avoidCache){
|
||||
ts = {};
|
||||
}else{
|
||||
ts = tmplts[wt];
|
||||
}
|
||||
}
|
||||
if((!obj.templateString)&&(!avoidCache)){
|
||||
obj.templateString = templateString || ts["string"];
|
||||
}
|
||||
if((!obj.templateNode)&&(!avoidCache)){
|
||||
obj.templateNode = ts["node"];
|
||||
}
|
||||
if((!obj.templateNode)&&(!obj.templateString)&&(tpath)){
|
||||
// fetch a text fragment and assign it to templateString
|
||||
// NOTE: we rely on blocking IO here!
|
||||
var tstring = dojo.hostenv.getText(tpath);
|
||||
if(tstring){
|
||||
// strip <?xml ...?> declarations so that external SVG and XML
|
||||
// documents can be added to a document without worry
|
||||
tstring = tstring.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, "");
|
||||
var matches = tstring.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
|
||||
if(matches){
|
||||
tstring = matches[1];
|
||||
}
|
||||
}else{
|
||||
tstring = "";
|
||||
}
|
||||
obj.templateString = tstring;
|
||||
if(!avoidCache){
|
||||
tmplts[wt]["string"] = tstring;
|
||||
}
|
||||
}
|
||||
if((!ts["string"])&&(!avoidCache)){
|
||||
ts.string = obj.templateString;
|
||||
}
|
||||
}
|
||||
dojo.widget._templateCache.dummyCount = 0;
|
||||
|
||||
dojo.widget.attachProperties = ["dojoAttachPoint", "id"];
|
||||
dojo.widget.eventAttachProperty = "dojoAttachEvent";
|
||||
dojo.widget.onBuildProperty = "dojoOnBuild";
|
||||
dojo.widget.waiNames = ["waiRole", "waiState"];
|
||||
dojo.widget.wai = {
|
||||
waiRole: { name: "waiRole",
|
||||
namespace: "http://www.w3.org/TR/xhtml2",
|
||||
alias: "x2",
|
||||
prefix: "wairole:",
|
||||
nsName: "role"
|
||||
},
|
||||
waiState: { name: "waiState",
|
||||
namespace: "http://www.w3.org/2005/07/aaa" ,
|
||||
alias: "aaa",
|
||||
prefix: "",
|
||||
nsName: "state"
|
||||
},
|
||||
setAttr: function(node, attr, value){
|
||||
if(dojo.render.html.ie){
|
||||
node.setAttribute(this[attr].alias+":"+this[attr].nsName, this[attr].prefix+value);
|
||||
}else{
|
||||
node.setAttributeNS(this[attr].namespace, this[attr].nsName, this[attr].prefix+value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
dojo.widget.attachTemplateNodes = function(rootNode, targetObj, events){
|
||||
// FIXME: this method is still taking WAAAY too long. We need ways of optimizing:
|
||||
// a.) what we are looking for on each node
|
||||
// b.) the nodes that are subject to interrogation (use xpath instead?)
|
||||
// c.) how expensive event assignment is (less eval(), more connect())
|
||||
// var start = new Date();
|
||||
var elementNodeType = dojo.dom.ELEMENT_NODE;
|
||||
|
||||
function trim(str){
|
||||
return str.replace(/^\s+|\s+$/g, "");
|
||||
}
|
||||
|
||||
if(!rootNode){
|
||||
rootNode = targetObj.domNode;
|
||||
}
|
||||
|
||||
if(rootNode.nodeType != elementNodeType){
|
||||
return;
|
||||
}
|
||||
// alert(events.length);
|
||||
|
||||
var nodes = rootNode.all || rootNode.getElementsByTagName("*");
|
||||
var _this = targetObj;
|
||||
for(var x=-1; x<nodes.length; x++){
|
||||
var baseNode = (x == -1) ? rootNode : nodes[x];
|
||||
// FIXME: is this going to have capitalization problems? Could use getAttribute(name, 0); to get attributes case-insensitve
|
||||
var attachPoint = [];
|
||||
for(var y=0; y<this.attachProperties.length; y++){
|
||||
var tmpAttachPoint = baseNode.getAttribute(this.attachProperties[y]);
|
||||
if(tmpAttachPoint){
|
||||
attachPoint = tmpAttachPoint.split(";");
|
||||
for(var z=0; z<attachPoint.length; z++){
|
||||
if(dojo.lang.isArray(targetObj[attachPoint[z]])){
|
||||
targetObj[attachPoint[z]].push(baseNode);
|
||||
}else{
|
||||
targetObj[attachPoint[z]]=baseNode;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// continue;
|
||||
|
||||
// FIXME: we need to put this into some kind of lookup structure
|
||||
// instead of direct assignment
|
||||
var tmpltPoint = baseNode.getAttribute(this.templateProperty);
|
||||
if(tmpltPoint){
|
||||
targetObj[tmpltPoint]=baseNode;
|
||||
}
|
||||
|
||||
dojo.lang.forEach(dojo.widget.waiNames, function(name){
|
||||
var wai = dojo.widget.wai[name];
|
||||
var val = baseNode.getAttribute(wai.name);
|
||||
if(val){
|
||||
dojo.widget.wai.setAttr(baseNode, wai.name, val);
|
||||
}
|
||||
}, this);
|
||||
|
||||
var attachEvent = baseNode.getAttribute(this.eventAttachProperty);
|
||||
if(attachEvent){
|
||||
// NOTE: we want to support attributes that have the form
|
||||
// "domEvent: nativeEvent; ..."
|
||||
var evts = attachEvent.split(";");
|
||||
for(var y=0; y<evts.length; y++){
|
||||
if((!evts[y])||(!evts[y].length)){ continue; }
|
||||
var thisFunc = null;
|
||||
var tevt = trim(evts[y]);
|
||||
if(evts[y].indexOf(":") >= 0){
|
||||
// oh, if only JS had tuple assignment
|
||||
var funcNameArr = tevt.split(":");
|
||||
tevt = trim(funcNameArr[0]);
|
||||
thisFunc = trim(funcNameArr[1]);
|
||||
}
|
||||
if(!thisFunc){
|
||||
thisFunc = tevt;
|
||||
}
|
||||
|
||||
var tf = function(){
|
||||
var ntf = new String(thisFunc);
|
||||
return function(evt){
|
||||
if(_this[ntf]){
|
||||
_this[ntf](dojo.event.browser.fixEvent(evt, this));
|
||||
}
|
||||
};
|
||||
}();
|
||||
dojo.event.browser.addListener(baseNode, tevt, tf, false, true);
|
||||
// dojo.event.browser.addListener(baseNode, tevt, dojo.lang.hitch(_this, thisFunc));
|
||||
}
|
||||
}
|
||||
|
||||
for(var y=0; y<events.length; y++){
|
||||
//alert(events[x]);
|
||||
var evtVal = baseNode.getAttribute(events[y]);
|
||||
if((evtVal)&&(evtVal.length)){
|
||||
var thisFunc = null;
|
||||
var domEvt = events[y].substr(4); // clober the "dojo" prefix
|
||||
thisFunc = trim(evtVal);
|
||||
var funcs = [thisFunc];
|
||||
if(thisFunc.indexOf(";")>=0){
|
||||
funcs = dojo.lang.map(thisFunc.split(";"), trim);
|
||||
}
|
||||
for(var z=0; z<funcs.length; z++){
|
||||
if(!funcs[z].length){ continue; }
|
||||
var tf = function(){
|
||||
var ntf = new String(funcs[z]);
|
||||
return function(evt){
|
||||
if(_this[ntf]){
|
||||
_this[ntf](dojo.event.browser.fixEvent(evt, this));
|
||||
}
|
||||
}
|
||||
}();
|
||||
dojo.event.browser.addListener(baseNode, domEvt, tf, false, true);
|
||||
// dojo.event.browser.addListener(baseNode, domEvt, dojo.lang.hitch(_this, funcs[z]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var onBuild = baseNode.getAttribute(this.onBuildProperty);
|
||||
if(onBuild){
|
||||
eval("var node = baseNode; var widget = targetObj; "+onBuild);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dojo.widget.getDojoEventsFromStr = function(str){
|
||||
// var lstr = str.toLowerCase();
|
||||
var re = /(dojoOn([a-z]+)(\s?))=/gi;
|
||||
var evts = str ? str.match(re)||[] : [];
|
||||
var ret = [];
|
||||
var lem = {};
|
||||
for(var x=0; x<evts.length; x++){
|
||||
if(evts[x].legth < 1){ continue; }
|
||||
var cm = evts[x].replace(/\s/, "");
|
||||
cm = (cm.slice(0, cm.length-1));
|
||||
if(!lem[cm]){
|
||||
lem[cm] = true;
|
||||
ret.push(cm);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
dojo.widget.buildAndAttachTemplate = function(obj, templatePath, templateCssPath, templateString, targetObj) {
|
||||
this.buildFromTemplate(obj, templatePath, templateCssPath, templateString);
|
||||
var node = dojo.dom.createNodesFromText(obj.templateString, true)[0];
|
||||
this.attachTemplateNodes(node, targetObj||obj, dojo.widget.getDojoEventsFromStr(templateString));
|
||||
return node;
|
||||
}
|
||||
*/
|
||||
|
||||
dojo.declare("dojo.widget.DomWidget", dojo.widget.Widget, {
|
||||
initializer: function() {
|
||||
if((arguments.length>0)&&(typeof arguments[0] == "object")){
|
||||
this.create(arguments[0]);
|
||||
}
|
||||
},
|
||||
|
||||
templateNode: null,
|
||||
templateString: null,
|
||||
templateCssString: null,
|
||||
preventClobber: false,
|
||||
domNode: null, // this is our visible representation of the widget!
|
||||
containerNode: null, // holds child elements
|
||||
|
||||
// Process the given child widget, inserting it's dom node as a child of our dom node
|
||||
// FIXME: should we support addition at an index in the children arr and
|
||||
// order the display accordingly? Right now we always append.
|
||||
addChild: function(widget, overrideContainerNode, pos, ref, insertIndex){
|
||||
if(!this.isContainer){ // we aren't allowed to contain other widgets, it seems
|
||||
dojo.debug("dojo.widget.DomWidget.addChild() attempted on non-container widget");
|
||||
return null;
|
||||
}else{
|
||||
this.addWidgetAsDirectChild(widget, overrideContainerNode, pos, ref, insertIndex);
|
||||
this.registerChild(widget, insertIndex);
|
||||
}
|
||||
return widget;
|
||||
},
|
||||
|
||||
addWidgetAsDirectChild: function(widget, overrideContainerNode, pos, ref, insertIndex){
|
||||
if((!this.containerNode)&&(!overrideContainerNode)){
|
||||
this.containerNode = this.domNode;
|
||||
}
|
||||
var cn = (overrideContainerNode) ? overrideContainerNode : this.containerNode;
|
||||
if(!pos){ pos = "after"; }
|
||||
if(!ref){
|
||||
// if(!cn){ cn = document.body; }
|
||||
if(!cn){ cn = document.body; }
|
||||
ref = cn.lastChild;
|
||||
}
|
||||
if(!insertIndex) { insertIndex = 0; }
|
||||
widget.domNode.setAttribute("dojoinsertionindex", insertIndex);
|
||||
|
||||
// insert the child widget domNode directly underneath my domNode, in the
|
||||
// specified position (by default, append to end)
|
||||
if(!ref){
|
||||
cn.appendChild(widget.domNode);
|
||||
}else{
|
||||
// FIXME: was this meant to be the (ugly hack) way to support insert @ index?
|
||||
//dojo.dom[pos](widget.domNode, ref, insertIndex);
|
||||
|
||||
// CAL: this appears to be the intended way to insert a node at a given position...
|
||||
if (pos == 'insertAtIndex'){
|
||||
// dojo.debug("idx:", insertIndex, "isLast:", ref === cn.lastChild);
|
||||
dojo.dom.insertAtIndex(widget.domNode, ref.parentNode, insertIndex);
|
||||
}else{
|
||||
// dojo.debug("pos:", pos, "isLast:", ref === cn.lastChild);
|
||||
if((pos == "after")&&(ref === cn.lastChild)){
|
||||
cn.appendChild(widget.domNode);
|
||||
}else{
|
||||
dojo.dom.insertAtPosition(widget.domNode, cn, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Record that given widget descends from me
|
||||
registerChild: function(widget, insertionIndex){
|
||||
|
||||
// we need to insert the child at the right point in the parent's
|
||||
// 'children' array, based on the insertionIndex
|
||||
|
||||
widget.dojoInsertionIndex = insertionIndex;
|
||||
|
||||
var idx = -1;
|
||||
for(var i=0; i<this.children.length; i++){
|
||||
if (this.children[i].dojoInsertionIndex < insertionIndex){
|
||||
idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
this.children.splice(idx+1, 0, widget);
|
||||
|
||||
widget.parent = this;
|
||||
widget.addedTo(this);
|
||||
|
||||
// If this widget was created programatically, then it was erroneously added
|
||||
// to dojo.widget.manager.topWidgets. Fix that here.
|
||||
delete dojo.widget.manager.topWidgets[widget.widgetId];
|
||||
},
|
||||
|
||||
removeChild: function(widget){
|
||||
// detach child domNode from parent domNode
|
||||
dojo.dom.removeNode(widget.domNode);
|
||||
|
||||
// remove child widget from parent widget
|
||||
return dojo.widget.DomWidget.superclass.removeChild.call(this, widget);
|
||||
},
|
||||
|
||||
getFragNodeRef: function(frag){
|
||||
if( !frag || !frag["dojo:"+this.widgetType.toLowerCase()] ){
|
||||
dojo.raise("Error: no frag for widget type " + this.widgetType +
|
||||
", id " + this.widgetId + " (maybe a widget has set it's type incorrectly)");
|
||||
}
|
||||
return (frag ? frag["dojo:"+this.widgetType.toLowerCase()]["nodeRef"] : null);
|
||||
},
|
||||
|
||||
// Replace source domNode with generated dom structure, and register
|
||||
// widget with parent.
|
||||
postInitialize: function(args, frag, parentComp){
|
||||
var sourceNodeRef = this.getFragNodeRef(frag);
|
||||
// Stick my generated dom into the output tree
|
||||
//alert(this.widgetId + ": replacing " + sourceNodeRef + " with " + this.domNode.innerHTML);
|
||||
if (parentComp && (parentComp.snarfChildDomOutput || !sourceNodeRef)){
|
||||
// Add my generated dom as a direct child of my parent widget
|
||||
// This is important for generated widgets, and also cases where I am generating an
|
||||
// <li> node that can't be inserted back into the original DOM tree
|
||||
parentComp.addWidgetAsDirectChild(this, "", "insertAtIndex", "", args["dojoinsertionindex"], sourceNodeRef);
|
||||
} else if (sourceNodeRef){
|
||||
// Do in-place replacement of the my source node with my generated dom
|
||||
if(this.domNode && (this.domNode !== sourceNodeRef)){
|
||||
var oldNode = sourceNodeRef.parentNode.replaceChild(this.domNode, sourceNodeRef);
|
||||
}
|
||||
}
|
||||
|
||||
// Register myself with my parent, or with the widget manager if
|
||||
// I have no parent
|
||||
// TODO: the code below erroneously adds all programatically generated widgets
|
||||
// to topWidgets (since we don't know who the parent is until after creation finishes)
|
||||
if ( parentComp ) {
|
||||
parentComp.registerChild(this, args.dojoinsertionindex);
|
||||
} else {
|
||||
dojo.widget.manager.topWidgets[this.widgetId]=this;
|
||||
}
|
||||
|
||||
// Expand my children widgets
|
||||
if(this.isContainer){
|
||||
//alert("recurse from " + this.widgetId);
|
||||
// build any sub-components with us as the parent
|
||||
var fragParser = dojo.widget.getParser();
|
||||
fragParser.createSubComponents(frag, this);
|
||||
}
|
||||
},
|
||||
|
||||
// method over-ride
|
||||
buildRendering: function(args, frag){
|
||||
// DOM widgets construct themselves from a template
|
||||
var ts = dojo.widget._templateCache[this.widgetType];
|
||||
if(
|
||||
(!this.preventClobber)&&(
|
||||
(this.templatePath)||
|
||||
(this.templateNode)||
|
||||
(
|
||||
(this["templateString"])&&(this.templateString.length)
|
||||
)||
|
||||
(
|
||||
(typeof ts != "undefined")&&( (ts["string"])||(ts["node"]) )
|
||||
)
|
||||
)
|
||||
){
|
||||
// if it looks like we can build the thing from a template, do it!
|
||||
this.buildFromTemplate(args, frag);
|
||||
}else{
|
||||
// otherwise, assign the DOM node that was the source of the widget
|
||||
// parsing to be the root node
|
||||
this.domNode = this.getFragNodeRef(frag);
|
||||
}
|
||||
this.fillInTemplate(args, frag); // this is where individual widgets
|
||||
// will handle population of data
|
||||
// from properties, remote data
|
||||
// sets, etc.
|
||||
},
|
||||
|
||||
buildFromTemplate: function(args, frag){
|
||||
// var start = new Date();
|
||||
// copy template properties if they're already set in the templates object
|
||||
// dojo.debug("buildFromTemplate:", this);
|
||||
var avoidCache = false;
|
||||
if(args["templatecsspath"]){
|
||||
args["templateCssPath"] = args["templatecsspath"];
|
||||
}
|
||||
if(args["templatepath"]){
|
||||
avoidCache = true;
|
||||
args["templatePath"] = args["templatepath"];
|
||||
}
|
||||
dojo.widget.fillFromTemplateCache( this,
|
||||
args["templatePath"],
|
||||
args["templateCssPath"],
|
||||
null,
|
||||
avoidCache);
|
||||
var ts = dojo.widget._templateCache[this.widgetType];
|
||||
if((ts)&&(!avoidCache)){
|
||||
if(!this.templateString.length){
|
||||
this.templateString = ts["string"];
|
||||
}
|
||||
if(!this.templateNode){
|
||||
this.templateNode = ts["node"];
|
||||
}
|
||||
}
|
||||
var matches = false;
|
||||
var node = null;
|
||||
// var tstr = new String(this.templateString);
|
||||
var tstr = this.templateString;
|
||||
// attempt to clone a template node, if there is one
|
||||
if((!this.templateNode)&&(this.templateString)){
|
||||
matches = this.templateString.match(/\$\{([^\}]+)\}/g);
|
||||
if(matches) {
|
||||
// if we do property replacement, don't create a templateNode
|
||||
// to clone from.
|
||||
var hash = this.strings || {};
|
||||
// FIXME: should this hash of default replacements be cached in
|
||||
// templateString?
|
||||
for(var key in dojo.widget.defaultStrings) {
|
||||
if(dojo.lang.isUndefined(hash[key])) {
|
||||
hash[key] = dojo.widget.defaultStrings[key];
|
||||
}
|
||||
}
|
||||
// FIXME: this is a lot of string munging. Can we make it faster?
|
||||
for(var i = 0; i < matches.length; i++) {
|
||||
var key = matches[i];
|
||||
key = key.substring(2, key.length-1);
|
||||
var kval = (key.substring(0, 5) == "this.") ? dojo.lang.getObjPathValue(key.substring(5), this) : hash[key];
|
||||
var value;
|
||||
if((kval)||(dojo.lang.isString(kval))){
|
||||
value = (dojo.lang.isFunction(kval)) ? kval.call(this, key, this.templateString) : kval;
|
||||
tstr = tstr.replace(matches[i], value);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
// otherwise, we are required to instantiate a copy of the template
|
||||
// string if one is provided.
|
||||
|
||||
// FIXME: need to be able to distinguish here what should be done
|
||||
// or provide a generic interface across all DOM implementations
|
||||
// FIMXE: this breaks if the template has whitespace as its first
|
||||
// characters
|
||||
// node = this.createNodesFromText(this.templateString, true);
|
||||
// this.templateNode = node[0].cloneNode(true); // we're optimistic here
|
||||
this.templateNode = this.createNodesFromText(this.templateString, true)[0];
|
||||
if(!avoidCache){
|
||||
ts.node = this.templateNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
if((!this.templateNode)&&(!matches)){
|
||||
dojo.debug("weren't able to create template!");
|
||||
return false;
|
||||
}else if(!matches){
|
||||
node = this.templateNode.cloneNode(true);
|
||||
if(!node){ return false; }
|
||||
}else{
|
||||
node = this.createNodesFromText(tstr, true)[0];
|
||||
}
|
||||
|
||||
// recurse through the node, looking for, and attaching to, our
|
||||
// attachment points which should be defined on the template node.
|
||||
|
||||
this.domNode = node;
|
||||
// dojo.profile.start("attachTemplateNodes");
|
||||
this.attachTemplateNodes(this.domNode, this);
|
||||
// dojo.profile.end("attachTemplateNodes");
|
||||
|
||||
// relocate source contents to templated container node
|
||||
// this.containerNode must be able to receive children, or exceptions will be thrown
|
||||
if (this.isContainer && this.containerNode){
|
||||
var src = this.getFragNodeRef(frag);
|
||||
if (src){
|
||||
dojo.dom.moveChildren(src, this.containerNode);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
attachTemplateNodes: function(baseNode, targetObj){
|
||||
if(!targetObj){ targetObj = this; }
|
||||
return dojo.widget.attachTemplateNodes(baseNode, targetObj,
|
||||
dojo.widget.getDojoEventsFromStr(this.templateString));
|
||||
},
|
||||
|
||||
fillInTemplate: function(){
|
||||
// dojo.unimplemented("dojo.widget.DomWidget.fillInTemplate");
|
||||
},
|
||||
|
||||
// method over-ride
|
||||
destroyRendering: function(){
|
||||
try{
|
||||
delete this.domNode;
|
||||
}catch(e){ /* squelch! */ }
|
||||
},
|
||||
|
||||
// FIXME: method over-ride
|
||||
cleanUp: function(){},
|
||||
|
||||
getContainerHeight: function(){
|
||||
dojo.unimplemented("dojo.widget.DomWidget.getContainerHeight");
|
||||
},
|
||||
|
||||
getContainerWidth: function(){
|
||||
dojo.unimplemented("dojo.widget.DomWidget.getContainerWidth");
|
||||
},
|
||||
|
||||
createNodesFromText: function(){
|
||||
dojo.unimplemented("dojo.widget.DomWidget.createNodesFromText");
|
||||
}
|
||||
});
|
29
webapp/web/src/widget/DropdownButton.js
Normal file
29
webapp/web/src/widget/DropdownButton.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.DropdownButton");
|
||||
|
||||
dojo.deprecated("dojo.widget.DropdownButton", "use dojo.widget.ComboButton", "0.4");
|
||||
|
||||
// Draws a button with a down arrow;
|
||||
// when you press the down arrow something appears (usually a menu)
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:dropdownbutton");
|
||||
|
||||
dojo.widget.DropdownButton = function(){
|
||||
dojo.widget.Widget.call(this);
|
||||
|
||||
this.widgetType = "DropdownButton";
|
||||
}
|
||||
dojo.inherits(dojo.widget.DropdownButton, dojo.widget.Widget);
|
||||
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.DropdownButton");
|
118
webapp/web/src/widget/DropdownContainer.js
Normal file
118
webapp/web/src/widget/DropdownContainer.js
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.DropdownContainer");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.html");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.DropdownContainer",
|
||||
dojo.widget.HtmlWidget,
|
||||
{
|
||||
initializer: function(){
|
||||
},
|
||||
|
||||
inputWidth: "7em",
|
||||
inputId: "",
|
||||
inputName: "",
|
||||
iconURL: dojo.uri.dojoUri("src/widget/templates/images/combo_box_arrow.png"),
|
||||
iconAlt: "",
|
||||
|
||||
inputNode: null,
|
||||
buttonNode: null,
|
||||
containerNode: null,
|
||||
subWidgetNode: null,
|
||||
|
||||
containerToggle: "plain",
|
||||
containerToggleDuration: 150,
|
||||
containerAnimInProgress: false,
|
||||
|
||||
templateString: '<div><span style="white-space:nowrap"><input type="text" value="" style="vertical-align:middle;" dojoAttachPoint="inputNode" autocomplete="off" /> <img src="${this.iconURL}" alt="${this.iconAlt}" dojoAttachPoint="buttonNode" dojoAttachEvent="onclick: onIconClick;" style="vertical-align:middle; cursor:pointer; cursor:hand;" /></span><br /><div dojoAttachPoint="containerNode" style="display:none;position:absolute;width:12em;background-color:#fff;"></div></div>',
|
||||
templateCssPath: "",
|
||||
|
||||
fillInTemplate: function(args, frag){
|
||||
var source = this.getFragNodeRef(frag);
|
||||
|
||||
this.containerNode.style.left = "";
|
||||
this.containerNode.style.top = "";
|
||||
|
||||
if(this.inputId){ this.inputNode.id = this.inputId; }
|
||||
if(this.inputName){ this.inputNode.name = this.inputName; }
|
||||
this.inputNode.style.width = this.inputWidth;
|
||||
|
||||
dojo.event.connect(this.inputNode, "onchange", this, "onInputChange");
|
||||
|
||||
this.containerIframe = new dojo.html.BackgroundIframe(this.containerNode);
|
||||
this.containerIframe.size([0,0,0,0]);
|
||||
},
|
||||
|
||||
postMixInProperties: function(args, frag, parentComp){
|
||||
// now that we know the setting for toggle, get toggle object
|
||||
// (default to plain toggler if user specified toggler not present)
|
||||
this.containerToggleObj =
|
||||
dojo.lfx.toggle[this.containerToggle.toLowerCase()] || dojo.lfx.toggle.plain;
|
||||
dojo.widget.DropdownContainer.superclass.postMixInProperties.call(this, args, frag, parentComp);
|
||||
},
|
||||
|
||||
onIconClick: function(evt){
|
||||
this.toggleContainerShow();
|
||||
},
|
||||
|
||||
toggleContainerShow: function(){
|
||||
if(dojo.html.isShowing(this.containerNode)){
|
||||
this.hideContainer();
|
||||
}else{
|
||||
this.showContainer();
|
||||
}
|
||||
},
|
||||
|
||||
showContainer: function(){
|
||||
this.containerAnimInProgress=true;
|
||||
this.containerToggleObj.show(this.containerNode, this.containerToggleDuration, null,
|
||||
dojo.lang.hitch(this, this.onContainerShow), this.explodeSrc);
|
||||
dojo.lang.setTimeout(this, this.sizeBackgroundIframe, this.containerToggleDuration);
|
||||
},
|
||||
|
||||
onContainerShow: function(){
|
||||
this.containerAnimInProgress=false;
|
||||
},
|
||||
|
||||
hideContainer: function(){
|
||||
this.containerAnimInProgress=true;
|
||||
this.containerToggleObj.hide(this.containerNode, this.containerToggleDuration, null,
|
||||
dojo.lang.hitch(this, this.onContainerHide), this.explodeSrc);
|
||||
dojo.lang.setTimeout(this, this.sizeBackgroundIframe, this.containerToggleDuration);
|
||||
},
|
||||
|
||||
onContainerHide: function(){
|
||||
this.containerAnimInProgress=false;
|
||||
},
|
||||
|
||||
sizeBackgroundIframe: function(){
|
||||
var w = dojo.style.getOuterWidth(this.containerNode);
|
||||
var h = dojo.style.getOuterHeight(this.containerNode);
|
||||
if(w==0||h==0){
|
||||
// need more time to calculate size
|
||||
dojo.lang.setTimeout(this, "sizeBackgroundIframe", 100);
|
||||
return;
|
||||
}
|
||||
if(dojo.html.isShowing(this.containerNode)){
|
||||
this.containerIframe.size([0,0,w,h]);
|
||||
}
|
||||
},
|
||||
|
||||
onInputChange: function(){}
|
||||
},
|
||||
"html"
|
||||
);
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:dropdowncontainer");
|
67
webapp/web/src/widget/DropdownDatePicker.js
Normal file
67
webapp/web/src/widget/DropdownDatePicker.js
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.DropdownDatePicker");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.DropdownContainer");
|
||||
dojo.require("dojo.widget.DatePicker");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.html");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.DropdownDatePicker",
|
||||
dojo.widget.DropdownContainer,
|
||||
{
|
||||
iconURL: dojo.uri.dojoUri("src/widget/templates/images/dateIcon.gif"),
|
||||
iconAlt: "Select a Date",
|
||||
zIndex: "10",
|
||||
datePicker: null,
|
||||
|
||||
dateFormat: "%m/%d/%Y",
|
||||
date: null,
|
||||
|
||||
fillInTemplate: function(args, frag){
|
||||
dojo.widget.DropdownDatePicker.superclass.fillInTemplate.call(this, args, frag);
|
||||
var source = this.getFragNodeRef(frag);
|
||||
|
||||
if(args.date){ this.date = new Date(args.date); }
|
||||
|
||||
var dpNode = document.createElement("div");
|
||||
this.containerNode.appendChild(dpNode);
|
||||
|
||||
var dateProps = { widgetContainerId: this.widgetId };
|
||||
if(this.date){
|
||||
dateProps["date"] = this.date;
|
||||
dateProps["storedDate"] = dojo.widget.DatePicker.util.toRfcDate(this.date);
|
||||
this.inputNode.value = dojo.date.format(this.date, this.dateFormat);
|
||||
}
|
||||
this.datePicker = dojo.widget.createWidget("DatePicker", dateProps, dpNode);
|
||||
dojo.event.connect(this.datePicker, "onSetDate", this, "onSetDate");
|
||||
this.containerNode.style.zIndex = this.zIndex;
|
||||
this.containerNode.style.backgroundColor = "transparent";
|
||||
},
|
||||
|
||||
onSetDate: function(){
|
||||
this.inputNode.value = dojo.date.format(this.datePicker.date, this.dateFormat);
|
||||
this.hideContainer();
|
||||
},
|
||||
|
||||
onInputChange: function(){
|
||||
var tmp = new Date(this.inputNode.value);
|
||||
this.datePicker.date = tmp;
|
||||
this.datePicker.setDate(dojo.widget.DatePicker.util.toRfcDate(tmp));
|
||||
this.datePicker.initData();
|
||||
this.datePicker.initUI();
|
||||
}
|
||||
},
|
||||
"html"
|
||||
);
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:dropdowndatepicker");
|
533
webapp/web/src/widget/Editor.js
Normal file
533
webapp/web/src/widget/Editor.js
Normal file
|
@ -0,0 +1,533 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
/* TODO:
|
||||
* - font selector
|
||||
* - test, bug fix, more features :)
|
||||
*/
|
||||
dojo.provide("dojo.widget.Editor");
|
||||
dojo.provide("dojo.widget.html.Editor");
|
||||
dojo.require("dojo.io.*");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.Toolbar");
|
||||
dojo.require("dojo.widget.RichText");
|
||||
dojo.require("dojo.widget.ColorPalette");
|
||||
dojo.require("dojo.string.extras");
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:Editor");
|
||||
|
||||
dojo.widget.html.Editor = function() {
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
this.contentFilters = [];
|
||||
this._toolbars = [];
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.Editor, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.widget.html.Editor.itemGroups = {
|
||||
textGroup: ["bold", "italic", "underline", "strikethrough"],
|
||||
blockGroup: ["formatBlock", "fontName", "fontSize"],
|
||||
justifyGroup: ["justifyleft", "justifycenter", "justifyright"],
|
||||
commandGroup: ["save", "cancel"],
|
||||
colorGroup: ["forecolor", "hilitecolor"],
|
||||
listGroup: ["insertorderedlist", "insertunorderedlist"],
|
||||
indentGroup: ["outdent", "indent"],
|
||||
linkGroup: ["createlink", "insertimage", "inserthorizontalrule"]
|
||||
};
|
||||
|
||||
dojo.widget.html.Editor.formatBlockValues = {
|
||||
"Normal": "p",
|
||||
"Main heading": "h2",
|
||||
"Sub heading": "h3",
|
||||
"Sub sub heading": "h4",
|
||||
"Preformatted": "pre"
|
||||
};
|
||||
|
||||
dojo.widget.html.Editor.fontNameValues = {
|
||||
"Arial": "Arial, Helvetica, sans-serif",
|
||||
"Verdana": "Verdana, sans-serif",
|
||||
"Times New Roman": "Times New Roman, serif",
|
||||
"Courier": "Courier New, monospace"
|
||||
};
|
||||
|
||||
dojo.widget.html.Editor.fontSizeValues = {
|
||||
"1 (8 pt)" : "1",
|
||||
"2 (10 pt)": "2",
|
||||
"3 (12 pt)": "3",
|
||||
"4 (14 pt)": "4",
|
||||
"5 (18 pt)": "5",
|
||||
"6 (24 pt)": "6",
|
||||
"7 (36 pt)": "7"
|
||||
};
|
||||
|
||||
dojo.widget.html.Editor.defaultItems = [
|
||||
"commandGroup", "|", "blockGroup", "|", "textGroup", "|", "colorGroup", "|", "justifyGroup", "|", "listGroup", "indentGroup", "|", "linkGroup"
|
||||
];
|
||||
|
||||
// ones we support by default without asking the RichText component
|
||||
// NOTE: you shouldn't put buttons like bold, italic, etc in here
|
||||
dojo.widget.html.Editor.supportedCommands = ["save", "cancel", "|", "-", "/", " "];
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.Editor, {
|
||||
widgetType: "Editor",
|
||||
|
||||
saveUrl: "",
|
||||
saveMethod: "post",
|
||||
saveArgName: "editorContent",
|
||||
closeOnSave: false,
|
||||
items: dojo.widget.html.Editor.defaultItems,
|
||||
formatBlockItems: dojo.lang.shallowCopy(dojo.widget.html.Editor.formatBlockValues),
|
||||
fontNameItems: dojo.lang.shallowCopy(dojo.widget.html.Editor.fontNameValues),
|
||||
fontSizeItems: dojo.lang.shallowCopy(dojo.widget.html.Editor.fontSizeValues),
|
||||
|
||||
// used to get the properties of an item if it is given as a string
|
||||
getItemProperties: function(name) {
|
||||
var props = {};
|
||||
switch(name.toLowerCase()) {
|
||||
case "bold":
|
||||
case "italic":
|
||||
case "underline":
|
||||
case "strikethrough":
|
||||
props.toggleItem = true;
|
||||
break;
|
||||
|
||||
case "justifygroup":
|
||||
props.defaultButton = "justifyleft";
|
||||
props.preventDeselect = true;
|
||||
props.buttonGroup = true;
|
||||
break;
|
||||
|
||||
case "listgroup":
|
||||
props.buttonGroup = true;
|
||||
break;
|
||||
|
||||
case "save":
|
||||
case "cancel":
|
||||
props.label = dojo.string.capitalize(name);
|
||||
break;
|
||||
|
||||
case "forecolor":
|
||||
case "hilitecolor":
|
||||
props.name = name;
|
||||
props.toggleItem = true; // FIXME: they aren't exactly toggle items
|
||||
props.icon = this.getCommandImage(name);
|
||||
break;
|
||||
|
||||
case "formatblock":
|
||||
props.name = "formatBlock";
|
||||
props.values = this.formatBlockItems;
|
||||
break;
|
||||
|
||||
case "fontname":
|
||||
props.name = "fontName";
|
||||
props.values = this.fontNameItems;
|
||||
|
||||
case "fontsize":
|
||||
props.name = "fontSize";
|
||||
props.values = this.fontSizeItems;
|
||||
}
|
||||
return props;
|
||||
},
|
||||
|
||||
validateItems: true, // set to false to add items, regardless of support
|
||||
focusOnLoad: true,
|
||||
minHeight: "1em",
|
||||
|
||||
_richText: null, // RichText widget
|
||||
_richTextType: "RichText",
|
||||
|
||||
_toolbarContainer: null, // ToolbarContainer widget
|
||||
_toolbarContainerType: "ToolbarContainer",
|
||||
|
||||
_toolbars: [],
|
||||
_toolbarType: "Toolbar",
|
||||
|
||||
_toolbarItemType: "ToolbarItem",
|
||||
|
||||
buildRendering: function(args, frag) {
|
||||
// get the node from args/frag
|
||||
var node = frag["dojo:"+this.widgetType.toLowerCase()]["nodeRef"];
|
||||
var trt = dojo.widget.createWidget(this._richTextType, {
|
||||
focusOnLoad: this.focusOnLoad,
|
||||
minHeight: this.minHeight
|
||||
}, node)
|
||||
var _this = this;
|
||||
// this appears to fix a weird timing bug on Safari
|
||||
setTimeout(function(){
|
||||
_this.setRichText(trt);
|
||||
|
||||
_this.initToolbar();
|
||||
|
||||
_this.fillInTemplate(args, frag);
|
||||
}, 0);
|
||||
},
|
||||
|
||||
setRichText: function(richText) {
|
||||
if(this._richText && this._richText == richText) {
|
||||
dojo.debug("Already set the richText to this richText!");
|
||||
return;
|
||||
}
|
||||
|
||||
if(this._richText && !this._richText.isClosed) {
|
||||
dojo.debug("You are switching richTexts yet you haven't closed the current one. Losing reference!");
|
||||
}
|
||||
this._richText = richText;
|
||||
dojo.event.connect(this._richText, "close", this, "onClose");
|
||||
dojo.event.connect(this._richText, "onLoad", this, "onLoad");
|
||||
dojo.event.connect(this._richText, "onDisplayChanged", this, "updateToolbar");
|
||||
if(this._toolbarContainer) {
|
||||
this._toolbarContainer.enable();
|
||||
this.updateToolbar(true);
|
||||
}
|
||||
},
|
||||
|
||||
initToolbar: function() {
|
||||
// var tic = new Date();
|
||||
if(this._toolbarContainer) { return; } // only create it once
|
||||
this._toolbarContainer = dojo.widget.createWidget(this._toolbarContainerType);
|
||||
var tb = this.addToolbar();
|
||||
var last = true;
|
||||
for(var i = 0; i < this.items.length; i++) {
|
||||
if(this.items[i] == "\n") { // new row
|
||||
tb = this.addToolbar();
|
||||
} else {
|
||||
if((this.items[i] == "|")&&(!last)){
|
||||
last = true;
|
||||
}else{
|
||||
last = this.addItem(this.items[i], tb);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.insertToolbar(this._toolbarContainer.domNode, this._richText.domNode);
|
||||
// alert(new Date - tic);
|
||||
},
|
||||
|
||||
// allow people to override this so they can make their own placement logic
|
||||
insertToolbar: function(tbNode, richTextNode) {
|
||||
dojo.html.insertBefore(tbNode, richTextNode);
|
||||
//dojo.html.insertBefore(this._toolbarContainer.domNode, this._richText.domNode);
|
||||
},
|
||||
|
||||
addToolbar: function(toolbar) {
|
||||
this.initToolbar();
|
||||
if(!(toolbar instanceof dojo.widget.html.Toolbar)) {
|
||||
toolbar = dojo.widget.createWidget(this._toolbarType);
|
||||
}
|
||||
this._toolbarContainer.addChild(toolbar);
|
||||
this._toolbars.push(toolbar);
|
||||
return toolbar;
|
||||
},
|
||||
|
||||
addItem: function(item, tb, dontValidate) {
|
||||
if(!tb) { tb = this._toolbars[0]; }
|
||||
var cmd = ((item)&&(!dojo.lang.isUndefined(item["getValue"]))) ? cmd = item["getValue"](): item;
|
||||
|
||||
var groups = dojo.widget.html.Editor.itemGroups;
|
||||
if(item instanceof dojo.widget.ToolbarItem) {
|
||||
tb.addChild(item);
|
||||
} else if(groups[cmd]) {
|
||||
var group = groups[cmd];
|
||||
var worked = true;
|
||||
if(cmd == "justifyGroup" || cmd == "listGroup") {
|
||||
var btnGroup = [cmd];
|
||||
for(var i = 0 ; i < group.length; i++) {
|
||||
if(dontValidate || this.isSupportedCommand(group[i])) {
|
||||
btnGroup.push(this.getCommandImage(group[i]));
|
||||
}else{
|
||||
worked = false;
|
||||
}
|
||||
}
|
||||
if(btnGroup.length){
|
||||
/*
|
||||
// the addChild interface is assinine. Work around it.
|
||||
var tprops = this.getItemProperties(cmd);
|
||||
var tmpGroup = dojo.widget.createWidget("ToolbarButtonGroup", tprops);
|
||||
dojo.debug(btnGroup);
|
||||
dojo.event.connect(tmpGroup, "onClick", this, "_action");
|
||||
dojo.event.connect(tmpGroup, "onChangeSelect", this, "_action");
|
||||
*/
|
||||
var btn = tb.addChild(btnGroup, null, this.getItemProperties(cmd));
|
||||
dojo.event.connect(btn, "onClick", this, "_action");
|
||||
dojo.event.connect(btn, "onChangeSelect", this, "_action");
|
||||
}
|
||||
return worked;
|
||||
} else {
|
||||
for(var i = 0; i < group.length; i++) {
|
||||
if(!this.addItem(group[i], tb)){
|
||||
worked = false;
|
||||
}
|
||||
}
|
||||
return worked;
|
||||
}
|
||||
} else {
|
||||
if((!dontValidate)&&(!this.isSupportedCommand(cmd))){
|
||||
return false;
|
||||
}
|
||||
if(dontValidate || this.isSupportedCommand(cmd)) {
|
||||
cmd = cmd.toLowerCase();
|
||||
if(cmd == "formatblock") {
|
||||
var select = dojo.widget.createWidget("ToolbarSelect", {
|
||||
name: "formatBlock",
|
||||
values: this.formatBlockItems
|
||||
});
|
||||
tb.addChild(select);
|
||||
var _this = this;
|
||||
dojo.event.connect(select, "onSetValue", function(item, value) {
|
||||
_this.onAction("formatBlock", value);
|
||||
});
|
||||
} else if(cmd == "fontname") {
|
||||
var select = dojo.widget.createWidget("ToolbarSelect", {
|
||||
name: "fontName",
|
||||
values: this.fontNameItems
|
||||
});
|
||||
tb.addChild(select);
|
||||
dojo.event.connect(select, "onSetValue", dojo.lang.hitch(this, function(item, value) {
|
||||
this.onAction("fontName", value);
|
||||
}));
|
||||
} else if(cmd == "fontsize") {
|
||||
var select = dojo.widget.createWidget("ToolbarSelect", {
|
||||
name: "fontSize",
|
||||
values: this.fontSizeItems
|
||||
});
|
||||
tb.addChild(select);
|
||||
dojo.event.connect(select, "onSetValue", dojo.lang.hitch(this, function(item, value) {
|
||||
this.onAction("fontSize", value);
|
||||
}));
|
||||
} else if(dojo.lang.inArray(cmd, ["forecolor", "hilitecolor"])) {
|
||||
var btn = tb.addChild(dojo.widget.createWidget("ToolbarColorDialog", this.getItemProperties(cmd)));
|
||||
dojo.event.connect(btn, "onSetValue", this, "_setValue");
|
||||
} else {
|
||||
var btn = tb.addChild(this.getCommandImage(cmd), null, this.getItemProperties(cmd));
|
||||
if(cmd == "save"){
|
||||
dojo.event.connect(btn, "onClick", this, "_save");
|
||||
}else if(cmd == "cancel"){
|
||||
dojo.event.connect(btn, "onClick", this, "_close");
|
||||
} else {
|
||||
dojo.event.connect(btn, "onClick", this, "_action");
|
||||
dojo.event.connect(btn, "onChangeSelect", this, "_action");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
enableToolbar: function() {
|
||||
if(this._toolbarContainer) {
|
||||
this._toolbarContainer.domNode.style.display = "";
|
||||
this._toolbarContainer.enable();
|
||||
}
|
||||
},
|
||||
|
||||
disableToolbar: function(hide){
|
||||
if(hide){
|
||||
if(this._toolbarContainer){
|
||||
this._toolbarContainer.domNode.style.display = "none";
|
||||
}
|
||||
}else{
|
||||
if(this._toolbarContainer){
|
||||
this._toolbarContainer.disable();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_updateToolbarLastRan: null,
|
||||
_updateToolbarTimer: null,
|
||||
_updateToolbarFrequency: 500,
|
||||
|
||||
updateToolbar: function(force) {
|
||||
if(!this._toolbarContainer) { return; }
|
||||
|
||||
// keeps the toolbar from updating too frequently
|
||||
// TODO: generalize this functionality?
|
||||
var diff = new Date() - this._updateToolbarLastRan;
|
||||
if(!force && this._updateToolbarLastRan && (diff < this._updateToolbarFrequency)) {
|
||||
clearTimeout(this._updateToolbarTimer);
|
||||
var _this = this;
|
||||
this._updateToolbarTimer = setTimeout(function() {
|
||||
_this.updateToolbar();
|
||||
}, this._updateToolbarFrequency/2);
|
||||
return;
|
||||
} else {
|
||||
this._updateToolbarLastRan = new Date();
|
||||
}
|
||||
// end frequency checker
|
||||
|
||||
var items = this._toolbarContainer.getItems();
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
if(item instanceof dojo.widget.html.ToolbarSeparator) { continue; }
|
||||
var cmd = item._name;
|
||||
if (cmd == "save" || cmd == "cancel") { continue; }
|
||||
else if(cmd == "justifyGroup") {
|
||||
try {
|
||||
if(!this._richText.queryCommandEnabled("justifyleft")) {
|
||||
item.disable(false, true);
|
||||
} else {
|
||||
item.enable(false, true);
|
||||
var jitems = item.getItems();
|
||||
for(var j = 0; j < jitems.length; j++) {
|
||||
var name = jitems[j]._name;
|
||||
var value = this._richText.queryCommandValue(name);
|
||||
if(typeof value == "boolean" && value) {
|
||||
value = name;
|
||||
break;
|
||||
} else if(typeof value == "string") {
|
||||
value = "justify"+value;
|
||||
} else {
|
||||
value = null;
|
||||
}
|
||||
}
|
||||
if(!value) { value = "justifyleft"; } // TODO: query actual style
|
||||
item.setValue(value, false, true);
|
||||
}
|
||||
} catch(err) {}
|
||||
} else if(cmd == "listGroup") {
|
||||
var litems = item.getItems();
|
||||
for(var j = 0; j < litems.length; j++) {
|
||||
this.updateItem(litems[j]);
|
||||
}
|
||||
} else {
|
||||
this.updateItem(item);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
updateItem: function(item) {
|
||||
try {
|
||||
var cmd = item._name;
|
||||
var enabled = this._richText.queryCommandEnabled(cmd);
|
||||
item.setEnabled(enabled, false, true);
|
||||
|
||||
var active = this._richText.queryCommandState(cmd);
|
||||
if(active && cmd == "underline") {
|
||||
// don't activate underlining if we are on a link
|
||||
active = !this._richText.queryCommandEnabled("unlink");
|
||||
}
|
||||
item.setSelected(active, false, true);
|
||||
return true;
|
||||
} catch(err) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
supportedCommands: dojo.widget.html.Editor.supportedCommands.concat(),
|
||||
|
||||
isSupportedCommand: function(cmd) {
|
||||
// FIXME: how do we check for ActiveX?
|
||||
var yes = dojo.lang.inArray(cmd, this.supportedCommands);
|
||||
if(!yes) {
|
||||
try {
|
||||
var richText = this._richText || dojo.widget.HtmlRichText.prototype;
|
||||
yes = richText.queryCommandAvailable(cmd);
|
||||
} catch(E) {}
|
||||
}
|
||||
return yes;
|
||||
},
|
||||
|
||||
getCommandImage: function(cmd) {
|
||||
if(cmd == "|") {
|
||||
return cmd;
|
||||
} else {
|
||||
return dojo.uri.dojoUri("src/widget/templates/buttons/" + cmd + ".gif");
|
||||
}
|
||||
},
|
||||
|
||||
_action: function(e) {
|
||||
this._fire("onAction", e.getValue());
|
||||
},
|
||||
|
||||
_setValue: function(a, b) {
|
||||
this._fire("onAction", a.getValue(), b);
|
||||
},
|
||||
|
||||
_save: function(e){
|
||||
// FIXME: how should this behave when there's a larger form in play?
|
||||
if(!this._richText.isClosed){
|
||||
if(this.saveUrl.length){
|
||||
var content = {};
|
||||
content[this.saveArgName] = this.getHtml();
|
||||
dojo.io.bind({
|
||||
method: this.saveMethod,
|
||||
url: this.saveUrl,
|
||||
content: content
|
||||
});
|
||||
}else{
|
||||
dojo.debug("please set a saveUrl for the editor");
|
||||
}
|
||||
if(this.closeOnSave){
|
||||
this._richText.close(e.getName().toLowerCase() == "save");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_close: function(e) {
|
||||
if(!this._richText.isClosed) {
|
||||
this._richText.close(e.getName().toLowerCase() == "save");
|
||||
}
|
||||
},
|
||||
|
||||
onAction: function(cmd, value) {
|
||||
switch(cmd) {
|
||||
case "createlink":
|
||||
if(!(value = prompt("Please enter the URL of the link:", "http://"))) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "insertimage":
|
||||
if(!(value = prompt("Please enter the URL of the image:", "http://"))) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
this._richText.execCommand(cmd, value);
|
||||
},
|
||||
|
||||
fillInTemplate: function(args, frag) {
|
||||
// dojo.event.connect(this, "onResized", this._richText, "onResized");
|
||||
},
|
||||
|
||||
_fire: function(eventName) {
|
||||
if(dojo.lang.isFunction(this[eventName])) {
|
||||
var args = [];
|
||||
if(arguments.length == 1) {
|
||||
args.push(this);
|
||||
} else {
|
||||
for(var i = 1; i < arguments.length; i++) {
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
}
|
||||
this[eventName].apply(this, args);
|
||||
}
|
||||
},
|
||||
|
||||
getHtml: function(){
|
||||
this._richText.contentFilters = this._richText.contentFilters.concat(this.contentFilters);
|
||||
return this._richText.getEditorContent();
|
||||
},
|
||||
|
||||
getEditorContent: function(){
|
||||
return this.getHtml();
|
||||
},
|
||||
|
||||
onClose: function(save, hide){
|
||||
this.disableToolbar(hide);
|
||||
if(save) {
|
||||
this._fire("onSave");
|
||||
} else {
|
||||
this._fire("onCancel");
|
||||
}
|
||||
},
|
||||
|
||||
// events baby!
|
||||
onLoad: function(){},
|
||||
onSave: function(){},
|
||||
onCancel: function(){}
|
||||
});
|
||||
|
395
webapp/web/src/widget/Editor2.js
Normal file
395
webapp/web/src/widget/Editor2.js
Normal file
|
@ -0,0 +1,395 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
/* TODO:
|
||||
* - font selector
|
||||
* - test, bug fix, more features :)
|
||||
*/
|
||||
dojo.provide("dojo.widget.Editor2");
|
||||
dojo.provide("dojo.widget.html.Editor2");
|
||||
dojo.require("dojo.io.*");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.RichText");
|
||||
dojo.require("dojo.widget.Editor2Toolbar");
|
||||
// dojo.require("dojo.widget.ColorPalette");
|
||||
// dojo.require("dojo.string.extras");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.Editor2",
|
||||
dojo.widget.html.RichText,
|
||||
{
|
||||
saveUrl: "",
|
||||
saveMethod: "post",
|
||||
saveArgName: "editorContent",
|
||||
closeOnSave: false,
|
||||
shareToolbar: false,
|
||||
toolbarAlwaysVisible: false,
|
||||
htmlEditing: false,
|
||||
_inHtmlMode: false,
|
||||
_htmlEditNode: null,
|
||||
|
||||
commandList: dojo.widget.html.Editor2Toolbar.prototype.commandList,
|
||||
toolbarWidget: null,
|
||||
scrollInterval: null,
|
||||
|
||||
|
||||
editorOnLoad: function(){
|
||||
var toolbars = dojo.widget.byType("Editor2Toolbar");
|
||||
if((!toolbars.length)||(!this.shareToolbar)){
|
||||
var tbOpts = {};
|
||||
tbOpts.templatePath = dojo.uri.dojoUri("src/widget/templates/HtmlEditorToolbarOneline.html");
|
||||
this.toolbarWidget = dojo.widget.createWidget("Editor2Toolbar",
|
||||
tbOpts, this.domNode, "before");
|
||||
dojo.event.connect(this, "destroy", this.toolbarWidget, "destroy");
|
||||
this.toolbarWidget.hideUnusableButtons(this);
|
||||
|
||||
if(this.object){
|
||||
this.tbBgIframe = new dojo.html.BackgroundIframe(this.toolbarWidget.domNode);
|
||||
this.tbBgIframe.iframe.style.height = "30px";
|
||||
}
|
||||
|
||||
// need to set position fixed to wherever this thing has landed
|
||||
if(this.toolbarAlwaysVisible){
|
||||
var src = document["documentElement"]||window;
|
||||
this.scrollInterval = setInterval(dojo.lang.hitch(this, "globalOnScrollHandler"), 100);
|
||||
// dojo.event.connect(src, "onscroll", this, "globalOnScrollHandler");
|
||||
dojo.event.connect("before", this, "destroyRendering", this, "unhookScroller");
|
||||
}
|
||||
}else{
|
||||
// FIXME: should we try harder to explicitly manage focus in
|
||||
// order to prevent too many editors from all querying
|
||||
// for button status concurrently?
|
||||
// FIXME: selecting in one shared toolbar doesn't clobber
|
||||
// selection in the others. This is problematic.
|
||||
this.toolbarWidget = toolbars[0];
|
||||
}
|
||||
dojo.event.topic.registerPublisher("Editor2.clobberFocus", this.editNode, "onfocus");
|
||||
// dojo.event.topic.registerPublisher("Editor2.clobberFocus", this.editNode, "onclick");
|
||||
dojo.event.topic.subscribe("Editor2.clobberFocus", this, "setBlur");
|
||||
dojo.event.connect(this.editNode, "onfocus", this, "setFocus");
|
||||
dojo.event.connect(this.toolbarWidget.linkButton, "onclick",
|
||||
dojo.lang.hitch(this, function(){
|
||||
var range;
|
||||
if(this.document.selection){
|
||||
range = this.document.selection.createRange().text;
|
||||
}else if(dojo.render.html.mozilla){
|
||||
range = this.window.getSelection().toString();
|
||||
}
|
||||
if(range.length){
|
||||
this.toolbarWidget.exec("createlink",
|
||||
prompt("Please enter the URL of the link:", "http://"));
|
||||
}else{
|
||||
alert("Please select text to link");
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
var focusFunc = dojo.lang.hitch(this, function(){
|
||||
if(dojo.render.html.ie){
|
||||
this.editNode.focus();
|
||||
}else{
|
||||
this.window.focus();
|
||||
}
|
||||
});
|
||||
|
||||
dojo.event.connect(this.toolbarWidget, "formatSelectClick", focusFunc);
|
||||
dojo.event.connect(this, "execCommand", focusFunc);
|
||||
|
||||
if(this.htmlEditing){
|
||||
var tb = this.toolbarWidget.htmltoggleButton;
|
||||
if(tb){
|
||||
tb.style.display = "";
|
||||
dojo.event.connect(this.toolbarWidget, "htmltoggleClick",
|
||||
this, "toggleHtmlEditing");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
toggleHtmlEditing: function(){
|
||||
if(!this._inHtmlMode){
|
||||
this._inHtmlMode = true;
|
||||
this.toolbarWidget.highlightButton("htmltoggle");
|
||||
if(!this._htmlEditNode){
|
||||
this._htmlEditNode = document.createElement("textarea");
|
||||
dojo.html.insertBefore(this._htmlEditNode, this.domNode);
|
||||
}
|
||||
this._htmlEditNode.style.display = "";
|
||||
this._htmlEditNode.style.width = "100%";
|
||||
this._htmlEditNode.style.height = dojo.style.getInnerHeight(this.editNode)+"px";
|
||||
this._htmlEditNode.value = this.editNode.innerHTML;
|
||||
this.domNode.style.display = "none";
|
||||
}else{
|
||||
this._inHtmlMode = false;
|
||||
this.domNode.style.display = "";
|
||||
this.toolbarWidget.unhighlightButton("htmltoggle");
|
||||
dojo.lang.setTimeout(this, "replaceEditorContent", 1, this._htmlEditNode.value);
|
||||
this._htmlEditNode.style.display = "none";
|
||||
this.editNode.focus();
|
||||
}
|
||||
},
|
||||
|
||||
setFocus: function(){
|
||||
// dojo.debug("setFocus:", this);
|
||||
dojo.event.connect(this.toolbarWidget, "exec", this, "execCommand");
|
||||
},
|
||||
|
||||
setBlur: function(){
|
||||
// dojo.debug("setBlur:", this);
|
||||
dojo.event.disconnect(this.toolbarWidget, "exec", this, "execCommand");
|
||||
},
|
||||
|
||||
_scrollSetUp: false,
|
||||
_fixEnabled: false,
|
||||
_scrollThreshold: false,
|
||||
_handleScroll: true,
|
||||
globalOnScrollHandler: function(){
|
||||
var isIE = dojo.render.html.ie;
|
||||
if(!this._handleScroll){ return; }
|
||||
var ds = dojo.style;
|
||||
var tdn = this.toolbarWidget.domNode;
|
||||
var db = document["body"];
|
||||
var totalHeight = ds.getOuterHeight(tdn);
|
||||
if(!this._scrollSetUp){
|
||||
this._scrollSetUp = true;
|
||||
var editorWidth = ds.getOuterWidth(this.domNode);
|
||||
this._scrollThreshold = ds.abs(tdn, false).y;
|
||||
// dojo.debug("threshold:", this._scrollThreshold);
|
||||
if((isIE)&&(db)&&(ds.getStyle(db, "background-image")=="none")){
|
||||
with(db.style){
|
||||
backgroundImage = "url(" + dojo.uri.dojoUri("src/widget/templates/images/blank.gif") + ")";
|
||||
backgroundAttachment = "fixed";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var scrollPos = (window["pageYOffset"]) ? window["pageYOffset"] : (document["documentElement"]||document["body"]).scrollTop;
|
||||
|
||||
// FIXME: need to have top and bottom thresholds so toolbar doesn't keep scrolling past the bottom
|
||||
if(scrollPos > this._scrollThreshold){
|
||||
// dojo.debug(scrollPos);
|
||||
if(!this._fixEnabled){
|
||||
this.domNode.style.marginTop = totalHeight+"px";
|
||||
if(isIE){
|
||||
// FIXME: should we just use setBehvior() here instead?
|
||||
var cl = dojo.style.abs(tdn).x;
|
||||
document.body.appendChild(tdn);
|
||||
tdn.style.left = cl+dojo.style.getPixelValue(document.body, "margin-left")+"px";
|
||||
dojo.html.addClass(tdn, "IEFixedToolbar");
|
||||
if(this.object){
|
||||
dojo.html.addClass(this.tbBgIframe, "IEFixedToolbar");
|
||||
}
|
||||
|
||||
}else{
|
||||
with(tdn.style){
|
||||
position = "fixed";
|
||||
top = "0px";
|
||||
}
|
||||
}
|
||||
tdn.style.zIndex = 1000;
|
||||
this._fixEnabled = true;
|
||||
}
|
||||
// if we're showing the floating toolbar, make sure that if
|
||||
// we've scrolled past the bottom of the editor that we hide
|
||||
// the toolbar for this instance of the editor.
|
||||
|
||||
// TODO: when we get multiple editor toolbar support working
|
||||
// correctly, ensure that we check this against the scroll
|
||||
// position of the bottom-most editor instance.
|
||||
if(!dojo.render.html.safari){
|
||||
// safari reports a bunch of things incorrectly here
|
||||
var eHeight = (this.height) ? parseInt(this.height) : ((this.object) ? dojo.style.getInnerHeight(this.editNode) : this._lastHeight);
|
||||
if(scrollPos > (this._scrollThreshold+eHeight)){
|
||||
tdn.style.display = "none";
|
||||
}else{
|
||||
tdn.style.display = "";
|
||||
}
|
||||
}
|
||||
|
||||
}else if(this._fixEnabled){
|
||||
this.domNode.style.marginTop = null;
|
||||
with(tdn.style){
|
||||
position = "";
|
||||
top = "";
|
||||
zIndex = "";
|
||||
if(isIE){
|
||||
marginTop = "";
|
||||
}
|
||||
}
|
||||
if(isIE){
|
||||
dojo.html.removeClass(tdn, "IEFixedToolbar");
|
||||
dojo.html.insertBefore(tdn, this._htmlEditNode||this.domNode);
|
||||
}
|
||||
this._fixEnabled = false;
|
||||
}
|
||||
},
|
||||
|
||||
unhookScroller: function(){
|
||||
this._handleScroll = false;
|
||||
clearInterval(this.scrollInterval);
|
||||
// var src = document["documentElement"]||window;
|
||||
// dojo.event.disconnect(src, "onscroll", this, "globalOnScrollHandler");
|
||||
if(dojo.render.html.ie){
|
||||
dojo.html.removeClass(this.toolbarWidget.domNode, "IEFixedToolbar");
|
||||
}
|
||||
},
|
||||
|
||||
_updateToolbarLastRan: null,
|
||||
_updateToolbarTimer: null,
|
||||
_updateToolbarFrequency: 500,
|
||||
|
||||
updateToolbar: function(force){
|
||||
if((!this.isLoaded)||(!this.toolbarWidget)){ return; }
|
||||
|
||||
// keeps the toolbar from updating too frequently
|
||||
// TODO: generalize this functionality?
|
||||
var diff = new Date() - this._updateToolbarLastRan;
|
||||
if( (!force)&&(this._updateToolbarLastRan)&&
|
||||
((diff < this._updateToolbarFrequency)) ){
|
||||
|
||||
clearTimeout(this._updateToolbarTimer);
|
||||
var _this = this;
|
||||
this._updateToolbarTimer = setTimeout(function() {
|
||||
_this.updateToolbar();
|
||||
}, this._updateToolbarFrequency/2);
|
||||
return;
|
||||
|
||||
}else{
|
||||
this._updateToolbarLastRan = new Date();
|
||||
}
|
||||
// end frequency checker
|
||||
|
||||
dojo.lang.forEach(this.commandList, function(cmd){
|
||||
if(cmd == "inserthtml"){ return; }
|
||||
try{
|
||||
if(this.queryCommandEnabled(cmd)){
|
||||
if(this.queryCommandState(cmd)){
|
||||
this.toolbarWidget.highlightButton(cmd);
|
||||
}else{
|
||||
this.toolbarWidget.unhighlightButton(cmd);
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
// alert(cmd+":"+e);
|
||||
}
|
||||
}, this);
|
||||
|
||||
var h = dojo.render.html;
|
||||
|
||||
// safari f's us for selection primitives
|
||||
if(h.safari){ return; }
|
||||
|
||||
var selectedNode = (h.ie) ? this.document.selection.createRange().parentElement() : this.window.getSelection().anchorNode;
|
||||
// make sure we actuall have an element
|
||||
while((selectedNode)&&(selectedNode.nodeType != 1)){
|
||||
selectedNode = selectedNode.parentNode;
|
||||
}
|
||||
if(!selectedNode){ return; }
|
||||
|
||||
var formats = ["p", "pre", "h1", "h2", "h3", "h4"];
|
||||
// gotta run some specialized updates for the various
|
||||
// formatting options
|
||||
var type = formats[dojo.lang.find(formats, selectedNode.nodeName.toLowerCase())];
|
||||
while((selectedNode)&&(selectedNode!=this.editNode)&&(!type)){
|
||||
selectedNode = selectedNode.parentNode;
|
||||
type = formats[dojo.lang.find(formats, selectedNode.nodeName.toLowerCase())];
|
||||
}
|
||||
if(!type){
|
||||
type = "";
|
||||
}else{
|
||||
if(type.charAt(0)=="h"){
|
||||
this.toolbarWidget.unhighlightButton("bold");
|
||||
}
|
||||
}
|
||||
this.toolbarWidget.selectFormat(type);
|
||||
},
|
||||
|
||||
updateItem: function(item) {
|
||||
try {
|
||||
var cmd = item._name;
|
||||
var enabled = this._richText.queryCommandEnabled(cmd);
|
||||
item.setEnabled(enabled, false, true);
|
||||
|
||||
var active = this._richText.queryCommandState(cmd);
|
||||
if(active && cmd == "underline") {
|
||||
// don't activate underlining if we are on a link
|
||||
active = !this._richText.queryCommandEnabled("unlink");
|
||||
}
|
||||
item.setSelected(active, false, true);
|
||||
return true;
|
||||
} catch(err) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
_save: function(e){
|
||||
// FIXME: how should this behave when there's a larger form in play?
|
||||
if(!this.isClosed){
|
||||
if(this.saveUrl.length){
|
||||
var content = {};
|
||||
content[this.saveArgName] = this.getHtml();
|
||||
dojo.io.bind({
|
||||
method: this.saveMethod,
|
||||
url: this.saveUrl,
|
||||
content: content
|
||||
});
|
||||
}else{
|
||||
dojo.debug("please set a saveUrl for the editor");
|
||||
}
|
||||
if(this.closeOnSave){
|
||||
this.close(e.getName().toLowerCase() == "save");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
wireUpOnLoad: function(){
|
||||
if(!dojo.render.html.ie){
|
||||
/*
|
||||
dojo.event.kwConnect({
|
||||
srcObj: this.document,
|
||||
srcFunc: "click",
|
||||
targetObj: this.toolbarWidget,
|
||||
targetFunc: "hideAllDropDowns",
|
||||
once: true
|
||||
});
|
||||
*/
|
||||
}
|
||||
}
|
||||
},
|
||||
"html",
|
||||
function(){
|
||||
var cp = dojo.widget.html.Editor2.prototype;
|
||||
if(!cp._wrappersSet){
|
||||
cp._wrappersSet = true;
|
||||
cp.fillInTemplate = (function(fit){
|
||||
return function(){
|
||||
fit.call(this);
|
||||
this.editorOnLoad();
|
||||
};
|
||||
})(cp.fillInTemplate);
|
||||
|
||||
cp.onDisplayChanged = (function(odc){
|
||||
return function(){
|
||||
try{
|
||||
odc.call(this);
|
||||
this.updateToolbar();
|
||||
}catch(e){}
|
||||
};
|
||||
})(cp.onDisplayChanged);
|
||||
|
||||
cp.onLoad = (function(ol){
|
||||
return function(){
|
||||
ol.call(this);
|
||||
this.wireUpOnLoad();
|
||||
};
|
||||
})(cp.onLoad);
|
||||
}
|
||||
}
|
||||
);
|
319
webapp/web/src/widget/Editor2Toolbar.js
Normal file
319
webapp/web/src/widget/Editor2Toolbar.js
Normal file
|
@ -0,0 +1,319 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Editor2Toolbar");
|
||||
dojo.provide("dojo.widget.html.Editor2Toolbar");
|
||||
|
||||
dojo.require("dojo.lang.*");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.widget.RichText");
|
||||
dojo.require("dojo.widget.ColorPalette");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.Editor2Toolbar",
|
||||
dojo.widget.HtmlWidget,
|
||||
{
|
||||
commandList: [ "bold", "italic", "underline", "subscript", "superscript",
|
||||
"fontname", "fontsize", "forecolor", "hilitecolor", "justifycenter",
|
||||
"justifyfull", "justifyleft", "justifyright", "cut", "copy", "paste",
|
||||
"delete", "undo", "redo", "createlink", "unlink", "removeformat",
|
||||
"inserthorizontalrule", "insertimage", "insertorderedlist",
|
||||
"insertunorderedlist", "indent", "outdent", "formatblock", "strikethrough",
|
||||
"inserthtml", "blockdirltr", "blockdirrtl", "dirltr", "dirrtl",
|
||||
"inlinedirltr", "inlinedirrtl", "inserttable", "insertcell",
|
||||
"insertcol", "insertrow", "deletecells", "deletecols", "deleterows",
|
||||
"mergecells", "splitcell"
|
||||
],
|
||||
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlEditorToolbar.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlEditorToolbar.css"),
|
||||
|
||||
forecolorPalette: null,
|
||||
hilitecolorPalette: null,
|
||||
|
||||
// DOM Nodes
|
||||
wikiwordButton: null,
|
||||
htmltoggleButton: null,
|
||||
insertimageButton: null,
|
||||
styleDropdownButton: null,
|
||||
styleDropdownContainer: null,
|
||||
copyButton: null,
|
||||
boldButton: null,
|
||||
italicButton: null,
|
||||
underlineButton: null,
|
||||
justifycenterButton: null,
|
||||
justifyleftButton: null,
|
||||
justifyfullButton: null,
|
||||
justifyrightButton: null,
|
||||
pasteButton: null,
|
||||
undoButton: null,
|
||||
redoButton: null,
|
||||
linkButton: null,
|
||||
insertunorderedlistButton: null,
|
||||
insertorderedlistButton: null,
|
||||
forecolorButton: null,
|
||||
forecolorDropDown: null,
|
||||
hilitecolorButton: null,
|
||||
hilitecolorDropDown: null,
|
||||
formatSelectBox: null,
|
||||
inserthorizontalruleButton: null,
|
||||
strikethroughButton: null,
|
||||
clickInterceptDiv: null,
|
||||
oneLineTr: null,
|
||||
|
||||
buttonClick: function(e){ e.preventDefault(); /* dojo.debug("buttonClick"); */ },
|
||||
|
||||
buttonMouseOver: function(e){ },
|
||||
buttonMouseOut: function(e){ },
|
||||
|
||||
|
||||
// event signals
|
||||
preventSelect: function(e){ if(dojo.render.html.safari){ e.preventDefault(); } },
|
||||
wikiwordClick: function(){ },
|
||||
insertimageClick: function(){ },
|
||||
htmltoggleClick: function(){ },
|
||||
|
||||
styleDropdownClick: function(){
|
||||
dojo.debug("styleDropdownClick:", this.styleDropdownContainer);
|
||||
dojo.style.toggleShowing(this.styleDropdownContainer);
|
||||
},
|
||||
|
||||
|
||||
copyClick: function(){ this.exec("copy"); },
|
||||
boldClick: function(){ this.exec("bold"); },
|
||||
italicClick: function(){ this.exec("italic"); },
|
||||
underlineClick: function(){ this.exec("underline"); },
|
||||
justifyleftClick: function(){ this.exec("justifyleft"); },
|
||||
justifycenterClick: function(){ this.exec("justifycenter"); },
|
||||
justifyfullClick: function(){ this.exec("justifyfull"); },
|
||||
justifyrightClick: function(){ this.exec("justifyright"); },
|
||||
pasteClick: function(){ this.exec("paste"); },
|
||||
undoClick: function(){ this.exec("undo"); },
|
||||
redoClick: function(){ this.exec("redo"); },
|
||||
linkClick: function(){
|
||||
// FIXME: we need to alert the user if they haven't selected any text
|
||||
// this.exec( "createlink",
|
||||
// prompt("Please enter the URL of the link:", "http://"));
|
||||
},
|
||||
insertunorderedlistClick: function(){ this.exec("insertunorderedlist"); },
|
||||
insertorderedlistClick: function(){ this.exec("insertorderedlist"); },
|
||||
inserthorizontalruleClick: function(){ this.exec("inserthorizontalrule"); },
|
||||
strikethroughClick: function(){ this.exec("strikethrough"); },
|
||||
|
||||
formatSelectClick: function(){
|
||||
var sv = this.formatSelectBox.value.toLowerCase();
|
||||
this.exec("formatblock", sv);
|
||||
},
|
||||
|
||||
normalTextClick: function(){ this.exec("formatblock", "p"); },
|
||||
h1TextClick: function(){ this.exec("formatblock", "h1"); },
|
||||
h2TextClick: function(){ this.exec("formatblock", "h2"); },
|
||||
h3TextClick: function(){ this.exec("formatblock", "h3"); },
|
||||
h4TextClick: function(){ this.exec("formatblock", "h4"); },
|
||||
indentClick: function(){ this.exec("indent"); },
|
||||
outdentClick: function(){ this.exec("outdent"); },
|
||||
|
||||
|
||||
hideAllDropDowns: function(){
|
||||
this.domNode.style.height = "";
|
||||
dojo.lang.forEach(dojo.widget.byType("Editor2Toolbar"), function(tb){
|
||||
try{
|
||||
dojo.style.hide(tb.forecolorDropDown);
|
||||
dojo.style.hide(tb.hilitecolorDropDown);
|
||||
dojo.style.hide(tb.styleDropdownContainer);
|
||||
if(tb.clickInterceptDiv){
|
||||
dojo.style.hide(tb.clickInterceptDiv);
|
||||
}
|
||||
}catch(e){}
|
||||
if(dojo.render.html.ie){
|
||||
try{
|
||||
dojo.style.hide(tb.forecolorPalette.bgIframe);
|
||||
}catch(e){}
|
||||
try{
|
||||
dojo.style.hide(tb.hilitecolorPalette.bgIframe);
|
||||
}catch(e){}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
selectFormat: function(format){
|
||||
dojo.lang.forEach(this.formatSelectBox.options, function(item){
|
||||
if(item.value.toLowerCase() == format.toLowerCase()){
|
||||
item.selected = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
forecolorClick: function(e){
|
||||
this.colorClick(e, "forecolor");
|
||||
},
|
||||
|
||||
hilitecolorClick: function(e){
|
||||
this.colorClick(e, "hilitecolor");
|
||||
},
|
||||
|
||||
// FIXME: these methods aren't currently dealing with clicking in the
|
||||
// general document to hide the menu
|
||||
colorClick: function(e, type){
|
||||
var h = dojo.render.html;
|
||||
this.hideAllDropDowns();
|
||||
// FIXME: if we've been "popped out", we need to set the height of the toolbar.
|
||||
e.stopPropagation();
|
||||
var dd = this[type+"DropDown"];
|
||||
var pal = this[type+"Palette"];
|
||||
dojo.style.toggleShowing(dd);
|
||||
if(!pal){
|
||||
pal = this[type+"Palette"] = dojo.widget.createWidget("ColorPalette", {}, dd, "first");
|
||||
var fcp = pal.domNode;
|
||||
with(dd.style){
|
||||
width = dojo.html.getOuterWidth(fcp) + "px";
|
||||
height = dojo.html.getOuterHeight(fcp) + "px";
|
||||
zIndex = 1002;
|
||||
position = "absolute";
|
||||
}
|
||||
|
||||
dojo.event.connect( "after",
|
||||
pal, "onColorSelect",
|
||||
this, "exec",
|
||||
function(mi){ mi.args.unshift(type); return mi.proceed(); }
|
||||
);
|
||||
|
||||
dojo.event.connect( "after",
|
||||
pal, "onColorSelect",
|
||||
dojo.style, "toggleShowing",
|
||||
this, function(mi){ mi.args.unshift(dd); return mi.proceed(); }
|
||||
);
|
||||
|
||||
var cid = this.clickInterceptDiv;
|
||||
if(!cid){
|
||||
cid = this.clickInterceptDiv = document.createElement("div");
|
||||
document.body.appendChild(cid);
|
||||
with(cid.style){
|
||||
backgroundColor = "transparent";
|
||||
top = left = "0px";
|
||||
height = width = "100%";
|
||||
position = "absolute";
|
||||
border = "none";
|
||||
display = "none";
|
||||
zIndex = 1001;
|
||||
}
|
||||
dojo.event.connect(cid, "onclick", function(){ cid.style.display = "none"; });
|
||||
}
|
||||
dojo.event.connect(pal, "onColorSelect", function(){ cid.style.display = "none"; });
|
||||
|
||||
dojo.event.kwConnect({
|
||||
srcObj: document.body,
|
||||
srcFunc: "onclick",
|
||||
targetObj: this,
|
||||
targetFunc: "hideAllDropDowns",
|
||||
once: true
|
||||
});
|
||||
document.body.appendChild(dd);
|
||||
}
|
||||
dojo.style.toggleShowing(this.clickInterceptDiv);
|
||||
var pos = dojo.style.abs(this[type+"Button"]);
|
||||
dojo.html.placeOnScreenPoint(dd, pos.x, pos.y, 0, false);
|
||||
if(pal.bgIframe){
|
||||
with(pal.bgIframe.style){
|
||||
display = "block";
|
||||
left = dd.style.left;
|
||||
top = dd.style.top;
|
||||
width = dojo.style.getOuterWidth(dd)+"px";
|
||||
height = dojo.style.getOuterHeight(dd)+"px";
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
uninitialize: function(){
|
||||
if(!dojo.render.html.ie){
|
||||
// apparently this causes leakage on IE!
|
||||
dojo.event.kwDisconnect({
|
||||
srcObj: document.body,
|
||||
srcFunc: "onclick",
|
||||
targetObj: this,
|
||||
targetFunc: "hideAllDropDowns",
|
||||
once: true
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// stub for observers
|
||||
exec: function(what, arg){ /* dojo.debug(what, new Date()); */ },
|
||||
|
||||
hideUnusableButtons: function(obj){
|
||||
var op = obj||dojo.widget.html.RichText.prototype;
|
||||
dojo.lang.forEach(this.commandList,
|
||||
function(cmd){
|
||||
if(this[cmd+"Button"]){
|
||||
var cb = this[cmd+"Button"];
|
||||
if(!op.queryCommandAvailable(cmd)){
|
||||
cb.style.display = "none";
|
||||
cb.parentNode.style.display = "none";
|
||||
}
|
||||
}
|
||||
},
|
||||
this);
|
||||
if(this.oneLineTr){
|
||||
var lastVisibleIsSpacer = false;
|
||||
var lastVisible = false;
|
||||
var tds = this.oneLineTr.getElementsByTagName("td");
|
||||
dojo.lang.forEach(tds, function(td){
|
||||
if(td.getAttribute("isSpacer")){
|
||||
if(td.style.display != "none"){
|
||||
if(lastVisibleIsSpacer){
|
||||
td.style.display = "none";
|
||||
}
|
||||
lastVisibleIsSpacer = true;
|
||||
}else{
|
||||
lastVisible = td;
|
||||
lastVisibleIsSpacer = true;
|
||||
}
|
||||
}else{
|
||||
if(td.style.display != "none"){
|
||||
lastVisible = td;
|
||||
lastVisibleIsSpacer = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
highlightButton: function(name){
|
||||
var bn = name+"Button";
|
||||
if(this[bn]){
|
||||
with(this[bn].style){
|
||||
backgroundColor = "White";
|
||||
border = "1px solid #aeaeab";
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
unhighlightButton: function(name){
|
||||
var bn = name+"Button";
|
||||
if(this[bn]){
|
||||
// dojo.debug("unhighlighting:", name);
|
||||
with(this[bn].style){
|
||||
backgroundColor = "";
|
||||
border = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"html",
|
||||
function(){
|
||||
// dojo.event.connect(this, "fillInTemplate", this, "hideUnusableButtons");
|
||||
dojo.event.connect(this, "fillInTemplate", dojo.lang.hitch(this, function(){
|
||||
if(dojo.render.html.ie){
|
||||
this.domNode.style.zoom = 1.0;
|
||||
}
|
||||
}));
|
||||
}
|
||||
);
|
743
webapp/web/src/widget/FisheyeList.js
Normal file
743
webapp/web/src/widget/FisheyeList.js
Normal file
|
@ -0,0 +1,743 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.FisheyeList");
|
||||
dojo.provide("dojo.widget.html.FisheyeList");
|
||||
dojo.provide("dojo.widget.html.FisheyeListItem");
|
||||
|
||||
//
|
||||
// TODO
|
||||
// fix SVG support, and turn it on only if the browser supports it
|
||||
// fix really long labels in vertical mode
|
||||
//
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.dom");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.style");
|
||||
dojo.require("dojo.event");
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:FisheyeList");
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:FisheyeListItem");
|
||||
|
||||
dojo.widget.html.FisheyeList = function(){
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.FisheyeList, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.FisheyeList, {
|
||||
|
||||
templateString: '<div class="dojoHtmlFisheyeListBar"></div>',
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlFisheyeList.css"),
|
||||
widgetType: "FisheyeList",
|
||||
|
||||
EDGE: {
|
||||
CENTER: 0,
|
||||
LEFT: 1,
|
||||
RIGHT: 2,
|
||||
TOP: 3,
|
||||
BOTTOM: 4
|
||||
},
|
||||
|
||||
isContainer: true,
|
||||
snarfChildDomOutput: true,
|
||||
|
||||
pos: {x: -1, y: -1}, // current cursor position, relative to the grid
|
||||
|
||||
// for conservative trigger mode, when triggered, timerScale is gradually increased from 0 to 1
|
||||
timerScale: 1.0,
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// i spy OPTIONS!!!!
|
||||
//
|
||||
|
||||
itemWidth: 40,
|
||||
itemHeight: 40,
|
||||
|
||||
itemMaxWidth: 150,
|
||||
itemMaxHeight: 150,
|
||||
|
||||
orientation: 'horizontal',
|
||||
|
||||
conservativeTrigger: false, // don't active menu until mouse is over an image (macintosh style)
|
||||
|
||||
effectUnits: 2,
|
||||
itemPadding: 10,
|
||||
|
||||
attachEdge: 'center',
|
||||
labelEdge: 'bottom',
|
||||
|
||||
enableCrappySvgSupport: false,
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
fillInTemplate: function(args, frag) {
|
||||
//dojo.debug(this.orientation);
|
||||
|
||||
dojo.html.disableSelection(this.domNode);
|
||||
|
||||
this.isHorizontal = (this.orientation == 'horizontal') ? 1 : 0;
|
||||
this.selectedNode = -1;
|
||||
|
||||
this.isOver = false;
|
||||
this.hitX1 = -1;
|
||||
this.hitY1 = -1;
|
||||
this.hitX2 = -1;
|
||||
this.hitY2 = -1;
|
||||
|
||||
//
|
||||
// only some edges make sense...
|
||||
//
|
||||
|
||||
this.anchorEdge = this.toEdge(this.attachEdge, this.EDGE.CENTER);
|
||||
this.labelEdge = this.toEdge(this.labelEdge, this.EDGE.TOP);
|
||||
|
||||
if ( this.isHorizontal && (this.anchorEdge == this.EDGE.LEFT )){ this.anchorEdge = this.EDGE.CENTER; }
|
||||
if ( this.isHorizontal && (this.anchorEdge == this.EDGE.RIGHT )){ this.anchorEdge = this.EDGE.CENTER; }
|
||||
if (!this.isHorizontal && (this.anchorEdge == this.EDGE.TOP )){ this.anchorEdge = this.EDGE.CENTER; }
|
||||
if (!this.isHorizontal && (this.anchorEdge == this.EDGE.BOTTOM)){ this.anchorEdge = this.EDGE.CENTER; }
|
||||
|
||||
if (this.labelEdge == this.EDGE.CENTER){ this.labelEdge = this.EDGE.TOP; }
|
||||
if ( this.isHorizontal && (this.labelEdge == this.EDGE.LEFT )){ this.labelEdge = this.EDGE.TOP; }
|
||||
if ( this.isHorizontal && (this.labelEdge == this.EDGE.RIGHT )){ this.labelEdge = this.EDGE.TOP; }
|
||||
if (!this.isHorizontal && (this.labelEdge == this.EDGE.TOP )){ this.labelEdge = this.EDGE.LEFT; }
|
||||
if (!this.isHorizontal && (this.labelEdge == this.EDGE.BOTTOM)){ this.labelEdge = this.EDGE.LEFT; }
|
||||
|
||||
|
||||
//
|
||||
// figure out the proximity size
|
||||
//
|
||||
|
||||
this.proximityLeft = this.itemWidth * (this.effectUnits - 0.5);
|
||||
this.proximityRight = this.itemWidth * (this.effectUnits - 0.5);
|
||||
this.proximityTop = this.itemHeight * (this.effectUnits - 0.5);
|
||||
this.proximityBottom = this.itemHeight * (this.effectUnits - 0.5);
|
||||
|
||||
if (this.anchorEdge == this.EDGE.LEFT){
|
||||
this.proximityLeft = 0;
|
||||
}
|
||||
if (this.anchorEdge == this.EDGE.RIGHT){
|
||||
this.proximityRight = 0;
|
||||
}
|
||||
if (this.anchorEdge == this.EDGE.TOP){
|
||||
this.proximityTop = 0;
|
||||
}
|
||||
if (this.anchorEdge == this.EDGE.BOTTOM){
|
||||
this.proximityBottom = 0;
|
||||
}
|
||||
if (this.anchorEdge == this.EDGE.CENTER){
|
||||
this.proximityLeft /= 2;
|
||||
this.proximityRight /= 2;
|
||||
this.proximityTop /= 2;
|
||||
this.proximityBottom /= 2;
|
||||
}
|
||||
},
|
||||
|
||||
postCreate: function(args, frag) {
|
||||
this.initializePositioning();
|
||||
|
||||
//
|
||||
// in liberal trigger mode, activate menu whenever mouse is close
|
||||
//
|
||||
if( !this.conservativeTrigger ){
|
||||
dojo.event.connect(document.documentElement, "onmousemove", this, "mouseHandler");
|
||||
}
|
||||
|
||||
// Deactivate the menu if mouse is moved off screen (doesn't work for FF?)
|
||||
dojo.event.connect(document.documentElement, "onmouseout", this, "onBodyOut");
|
||||
dojo.event.connect(this, "addChild", this, "initializePositioning");
|
||||
},
|
||||
|
||||
initializePositioning: function(){
|
||||
this.itemCount = this.children.length;
|
||||
|
||||
this.barWidth = (this.isHorizontal ? this.itemCount : 1) * this.itemWidth;
|
||||
this.barHeight = (this.isHorizontal ? 1 : this.itemCount) * this.itemHeight;
|
||||
|
||||
this.totalWidth = this.proximityLeft + this.proximityRight + this.barWidth;
|
||||
this.totalHeight = this.proximityTop + this.proximityBottom + this.barHeight;
|
||||
|
||||
//
|
||||
// calculate effect ranges for each item
|
||||
//
|
||||
|
||||
for (var i=0; i<this.children.length; i++){
|
||||
|
||||
this.children[i].posX = this.itemWidth * (this.isHorizontal ? i : 0);
|
||||
this.children[i].posY = this.itemHeight * (this.isHorizontal ? 0 : i);
|
||||
|
||||
this.children[i].cenX = this.children[i].posX + (this.itemWidth / 2);
|
||||
this.children[i].cenY = this.children[i].posY + (this.itemHeight / 2);
|
||||
|
||||
var isz = this.isHorizontal ? this.itemWidth : this.itemHeight;
|
||||
var r = this.effectUnits * isz;
|
||||
var c = this.isHorizontal ? this.children[i].cenX : this.children[i].cenY;
|
||||
var lhs = this.isHorizontal ? this.proximityLeft : this.proximityTop;
|
||||
var rhs = this.isHorizontal ? this.proximityRight : this.proximityBottom;
|
||||
var siz = this.isHorizontal ? this.barWidth : this.barHeight;
|
||||
|
||||
var range_lhs = r;
|
||||
var range_rhs = r;
|
||||
|
||||
if (range_lhs > c+lhs){ range_lhs = c+lhs; }
|
||||
if (range_rhs > (siz-c+rhs)){ range_rhs = siz-c+rhs; }
|
||||
|
||||
this.children[i].effectRangeLeft = range_lhs / isz;
|
||||
this.children[i].effectRangeRght = range_rhs / isz;
|
||||
|
||||
//dojo.debug('effect range for '+i+' is '+range_lhs+'/'+range_rhs);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// create the bar
|
||||
//
|
||||
|
||||
this.domNode.style.width = this.barWidth + 'px';
|
||||
this.domNode.style.height = this.barHeight + 'px';
|
||||
|
||||
|
||||
//
|
||||
// position the items
|
||||
//
|
||||
for (var i=0; i<this.children.length; i++){
|
||||
var itm = this.children[i];
|
||||
var elm = itm.domNode;
|
||||
elm.style.left = itm.posX + 'px';
|
||||
elm.style.top = itm.posY + 'px';
|
||||
elm.style.width = this.itemWidth + 'px';
|
||||
elm.style.height = this.itemHeight + 'px';
|
||||
|
||||
if ( itm.svgNode ) {
|
||||
itm.svgNode.style.position = 'absolute';
|
||||
itm.svgNode.style.left = this.itemPadding+'%';
|
||||
itm.svgNode.style.top = this.itemPadding+'%';
|
||||
itm.svgNode.style.width = (100 - 2 * this.itemPadding) + '%';
|
||||
itm.svgNode.style.height = (100 - 2 * this.itemPadding) + '%';
|
||||
itm.svgNode.style.zIndex = 1;
|
||||
|
||||
itm.svgNode.setSize(this.itemWidth, this.itemHeight);
|
||||
} else {
|
||||
itm.imgNode.style.left = this.itemPadding+'%';
|
||||
itm.imgNode.style.top = this.itemPadding+'%';
|
||||
itm.imgNode.style.width = (100 - 2 * this.itemPadding) + '%';
|
||||
itm.imgNode.style.height = (100 - 2 * this.itemPadding) + '%';
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// calc the grid
|
||||
//
|
||||
|
||||
this.calcHitGrid();
|
||||
},
|
||||
|
||||
onBodyOut: function(e){
|
||||
// clicking over an object inside of body causes this event to fire; ignore that case
|
||||
if( dojo.html.overElement(document.body, e) ){
|
||||
return;
|
||||
}
|
||||
this.setDormant(e);
|
||||
},
|
||||
|
||||
// when mouse moves out of menu's range
|
||||
setDormant: function(e){
|
||||
if( !this.isOver ){ return; } // already dormant?
|
||||
this.isOver = false;
|
||||
|
||||
if ( this.conservativeTrigger ) {
|
||||
// user can't re-trigger the menu expansion
|
||||
// until he mouses over a icon again
|
||||
dojo.event.disconnect(document.documentElement, "onmousemove", this, "mouseHandler");
|
||||
}
|
||||
this.onGridMouseMove(-1, -1);
|
||||
},
|
||||
|
||||
// when mouse is moved into menu's range
|
||||
setActive: function(e){
|
||||
if( this.isOver ){ return; } // already activated?
|
||||
this.isOver = true;
|
||||
|
||||
if ( this.conservativeTrigger ) {
|
||||
// switch event handlers so that we handle mouse events from anywhere near
|
||||
// the menu
|
||||
dojo.event.connect(document.documentElement, "onmousemove", this, "mouseHandler");
|
||||
|
||||
this.timerScale=0.0;
|
||||
|
||||
// call mouse handler to do some initial necessary calculations/positioning
|
||||
this.mouseHandler(e);
|
||||
|
||||
// slowly expand the icon size so it isn't jumpy
|
||||
this.expandSlowly();
|
||||
}
|
||||
},
|
||||
|
||||
// when mouse is moved
|
||||
mouseHandler: function(e) {
|
||||
if ((e.pageX >= this.hitX1) && (e.pageX <= this.hitX2) &&
|
||||
(e.pageY >= this.hitY1) && (e.pageY <= this.hitY2)){
|
||||
if( !this.isOver ){
|
||||
this.setActive(e);
|
||||
}
|
||||
this.onGridMouseMove(e.pageX-this.hitX1, e.pageY-this.hitY1);
|
||||
}else{
|
||||
if (this.isOver){
|
||||
this.setDormant(e);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onResized: function() {
|
||||
this.calcHitGrid();
|
||||
},
|
||||
|
||||
onGridMouseMove: function(x, y){
|
||||
this.pos = {x:x, y:y};
|
||||
this.paint();
|
||||
},
|
||||
|
||||
paint: function(){
|
||||
var x=this.pos.x;
|
||||
var y=this.pos.y;
|
||||
|
||||
if( this.itemCount <= 0 ){ return; }
|
||||
|
||||
//
|
||||
// figure out our main index
|
||||
//
|
||||
|
||||
var pos = this.isHorizontal ? x : y;
|
||||
var prx = this.isHorizontal ? this.proximityLeft : this.proximityTop;
|
||||
var siz = this.isHorizontal ? this.itemWidth : this.itemHeight;
|
||||
var sim = this.isHorizontal ?
|
||||
(1.0-this.timerScale)*this.itemWidth + this.timerScale*this.itemMaxWidth :
|
||||
(1.0-this.timerScale)*this.itemHeight + this.timerScale*this.itemMaxHeight ;
|
||||
|
||||
var cen = ((pos - prx) / siz) - 0.5;
|
||||
var max_off_cen = (sim / siz) - 0.5;
|
||||
|
||||
if (max_off_cen > this.effectUnits){ max_off_cen = this.effectUnits; }
|
||||
|
||||
|
||||
//
|
||||
// figure out our off-axis weighting
|
||||
//
|
||||
|
||||
var off_weight = 0;
|
||||
|
||||
if (this.anchorEdge == this.EDGE.BOTTOM){
|
||||
var cen2 = (y - this.proximityTop) / this.itemHeight;
|
||||
off_weight = (cen2 > 0.5) ? 1 : y / (this.proximityTop + (this.itemHeight / 2));
|
||||
}
|
||||
if (this.anchorEdge == this.EDGE.TOP){
|
||||
var cen2 = (y - this.proximityTop) / this.itemHeight;
|
||||
off_weight = (cen2 < 0.5) ? 1 : (this.totalHeight - y) / (this.proximityBottom + (this.itemHeight / 2));
|
||||
}
|
||||
if (this.anchorEdge == this.EDGE.RIGHT){
|
||||
var cen2 = (x - this.proximityLeft) / this.itemWidth;
|
||||
off_weight = (cen2 > 0.5) ? 1 : x / (this.proximityLeft + (this.itemWidth / 2));
|
||||
}
|
||||
if (this.anchorEdge == this.EDGE.LEFT){
|
||||
var cen2 = (x - this.proximityLeft) / this.itemWidth;
|
||||
off_weight = (cen2 < 0.5) ? 1 : (this.totalWidth - x) / (this.proximityRight + (this.itemWidth / 2));
|
||||
}
|
||||
if (this.anchorEdge == this.EDGE.CENTER){
|
||||
|
||||
if (this.isHorizontal){
|
||||
off_weight = y / (this.totalHeight);
|
||||
}else{
|
||||
off_weight = x / (this.totalWidth);
|
||||
}
|
||||
|
||||
if (off_weight > 0.5){
|
||||
off_weight = 1 - off_weight;
|
||||
}
|
||||
|
||||
off_weight *= 2;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// set the sizes
|
||||
//
|
||||
|
||||
for(var i=0; i<this.itemCount; i++){
|
||||
|
||||
var weight = this.weightAt(cen, i);
|
||||
|
||||
if (weight < 0){weight = 0;}
|
||||
|
||||
this.setitemsize(i, weight * off_weight);
|
||||
}
|
||||
|
||||
//
|
||||
// set the positions
|
||||
//
|
||||
|
||||
var main_p = Math.round(cen);
|
||||
var offset = 0;
|
||||
|
||||
if (cen < 0){
|
||||
main_p = 0;
|
||||
|
||||
}else if (cen > this.itemCount - 1){
|
||||
|
||||
main_p = this.itemCount -1;
|
||||
|
||||
}else{
|
||||
|
||||
offset = (cen - main_p) * ((this.isHorizontal ? this.itemWidth : this.itemHeight) - this.children[main_p].sizeMain);
|
||||
}
|
||||
|
||||
this.positionElementsFrom(main_p, offset);
|
||||
},
|
||||
|
||||
weightAt: function(cen, i){
|
||||
|
||||
var dist = Math.abs(cen - i);
|
||||
|
||||
var limit = ((cen - i) > 0) ? this.children[i].effectRangeRght : this.children[i].effectRangeLeft;
|
||||
|
||||
return (dist > limit) ? 0 : (1 - dist / limit);
|
||||
},
|
||||
|
||||
positionFromNode: function(p, w){
|
||||
|
||||
//
|
||||
// we need to grow all the nodes growing out from node 'i'
|
||||
//
|
||||
|
||||
this.setitemsize(p, w);
|
||||
|
||||
var wx = w;
|
||||
for(var i=p; i<this.itemCount; i++){
|
||||
wx = 0.8 * wx;
|
||||
this.setitemsize(i, wx);
|
||||
}
|
||||
|
||||
var wx = w;
|
||||
for(var i=p; i>=0; i--){
|
||||
wx = 0.8 * wx;
|
||||
this.setitemsize(i, wx);
|
||||
}
|
||||
},
|
||||
|
||||
setitemsize: function(p, scale){
|
||||
scale *= this.timerScale;
|
||||
var w = Math.round(this.itemWidth + ((this.itemMaxWidth - this.itemWidth ) * scale));
|
||||
var h = Math.round(this.itemHeight + ((this.itemMaxHeight - this.itemHeight) * scale));
|
||||
|
||||
if (this.isHorizontal){
|
||||
|
||||
this.children[p].sizeW = w;
|
||||
this.children[p].sizeH = h;
|
||||
|
||||
this.children[p].sizeMain = w;
|
||||
this.children[p].sizeOff = h;
|
||||
|
||||
var y = 0;
|
||||
|
||||
if (this.anchorEdge == this.EDGE.TOP){
|
||||
|
||||
y = (this.children[p].cenY - (this.itemHeight / 2));
|
||||
|
||||
}else if (this.anchorEdge == this.EDGE.BOTTOM){
|
||||
|
||||
y = (this.children[p].cenY - (h - (this.itemHeight / 2)));
|
||||
|
||||
}else{
|
||||
|
||||
y = (this.children[p].cenY - (h / 2));
|
||||
}
|
||||
|
||||
this.children[p].usualX = Math.round(this.children[p].cenX - (w / 2));
|
||||
|
||||
this.children[p].domNode.style.top = y + 'px';
|
||||
|
||||
this.children[p].domNode.style.left = this.children[p].usualX + 'px';
|
||||
|
||||
}else{
|
||||
|
||||
this.children[p].sizeW = w;
|
||||
this.children[p].sizeH = h;
|
||||
|
||||
this.children[p].sizeOff = w;
|
||||
this.children[p].sizeMain = h;
|
||||
|
||||
var x = 0;
|
||||
|
||||
if (this.anchorEdge == this.EDGE.LEFT){
|
||||
|
||||
x = this.children[p].cenX - (this.itemWidth / 2);
|
||||
|
||||
}else if (this.anchorEdge == this.EDGE.RIGHT){
|
||||
|
||||
x = this.children[p].cenX - (w - (this.itemWidth / 2));
|
||||
}else{
|
||||
|
||||
x = this.children[p].cenX - (w / 2);
|
||||
}
|
||||
|
||||
this.children[p].domNode.style.left = x + 'px';
|
||||
this.children[p].usualY = Math.round(this.children[p].cenY - (h / 2));
|
||||
|
||||
this.children[p].domNode.style.top = this.children[p].usualY + 'px';
|
||||
}
|
||||
|
||||
this.children[p].domNode.style.width = w + 'px';
|
||||
this.children[p].domNode.style.height = h + 'px';
|
||||
|
||||
if (this.children[p].svgNode){
|
||||
this.children[p].svgNode.setSize(w, h);
|
||||
}
|
||||
},
|
||||
|
||||
positionElementsFrom: function(p, offset){
|
||||
|
||||
var pos = 0;
|
||||
|
||||
if (this.isHorizontal){
|
||||
pos = Math.round(this.children[p].usualX + offset);
|
||||
this.children[p].domNode.style.left = pos + 'px';
|
||||
}else{
|
||||
pos = Math.round(this.children[p].usualY + offset);
|
||||
this.children[p].domNode.style.top = pos + 'px';
|
||||
}
|
||||
this.positionLabel(this.children[p]);
|
||||
|
||||
|
||||
//
|
||||
// position before
|
||||
//
|
||||
|
||||
var bpos = pos;
|
||||
|
||||
for(var i=p-1; i>=0; i--){
|
||||
|
||||
bpos -= this.children[i].sizeMain;
|
||||
|
||||
if (this.isHorizontal){
|
||||
this.children[i].domNode.style.left = bpos + 'px';
|
||||
}else{
|
||||
this.children[i].domNode.style.top = bpos + 'px';
|
||||
}
|
||||
this.positionLabel(this.children[i]);
|
||||
}
|
||||
|
||||
//
|
||||
// position after
|
||||
//
|
||||
|
||||
var apos = pos;
|
||||
|
||||
for(var i=p+1; i<this.itemCount; i++){
|
||||
|
||||
apos += this.children[i-1].sizeMain;
|
||||
|
||||
if (this.isHorizontal){
|
||||
this.children[i].domNode.style.left = apos + 'px';
|
||||
}else{
|
||||
this.children[i].domNode.style.top = apos + 'px';
|
||||
}
|
||||
this.positionLabel(this.children[i]);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
positionLabel: function(itm){
|
||||
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
|
||||
var labelW = dojo.style.getOuterWidth(itm.lblNode);
|
||||
var labelH = dojo.style.getOuterHeight(itm.lblNode);
|
||||
|
||||
if (this.labelEdge == this.EDGE.TOP){
|
||||
x = Math.round((itm.sizeW / 2) - (labelW / 2));
|
||||
y = -labelH;
|
||||
}
|
||||
|
||||
if (this.labelEdge == this.EDGE.BOTTOM){
|
||||
x = Math.round((itm.sizeW / 2) - (labelW / 2));
|
||||
y = itm.sizeH;
|
||||
}
|
||||
|
||||
if (this.labelEdge == this.EDGE.LEFT){
|
||||
x = -labelW;
|
||||
y = Math.round((itm.sizeH / 2) - (labelH / 2));
|
||||
}
|
||||
|
||||
if (this.labelEdge == this.EDGE.RIGHT){
|
||||
x = itm.sizeW;
|
||||
y = Math.round((itm.sizeH / 2) - (labelH / 2));
|
||||
}
|
||||
|
||||
itm.lblNode.style.left = x + 'px';
|
||||
itm.lblNode.style.top = y + 'px';
|
||||
},
|
||||
|
||||
calcHitGrid: function(){
|
||||
|
||||
var pos = dojo.style.getAbsolutePosition(this.domNode, true);
|
||||
|
||||
this.hitX1 = pos.x - this.proximityLeft;
|
||||
this.hitY1 = pos.y - this.proximityTop;
|
||||
this.hitX2 = this.hitX1 + this.totalWidth;
|
||||
this.hitY2 = this.hitY1 + this.totalHeight;
|
||||
|
||||
//dojo.debug(this.hitX1+','+this.hitY1+' // '+this.hitX2+','+this.hitY2);
|
||||
},
|
||||
|
||||
toEdge: function(inp, def){
|
||||
return this.EDGE[inp.toUpperCase()] || def;
|
||||
},
|
||||
|
||||
// slowly expand the image to user specified max size
|
||||
expandSlowly: function(){
|
||||
if( !this.isOver ){ return; }
|
||||
this.timerScale += 0.2;
|
||||
this.paint();
|
||||
if ( this.timerScale<1.0 ) {
|
||||
dojo.lang.setTimeout(this, "expandSlowly", 10);
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function(){
|
||||
// need to disconnect when we destroy
|
||||
dojo.event.disconnect(document.documentElement, "onmouseout", this, "onBodyOut");
|
||||
dojo.event.disconnect(document.documentElement, "onmousemove", this, "mouseHandler");
|
||||
dojo.widget.html.FisheyeList.superclass.destroy.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
dojo.widget.html.FisheyeListItem = function(){
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.FisheyeListItem, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.FisheyeListItem, {
|
||||
widgetType: "FisheyeListItem",
|
||||
|
||||
// Constructor arguments
|
||||
iconSrc: "",
|
||||
svgSrc: "",
|
||||
caption: "",
|
||||
|
||||
blankImgPath: dojo.uri.dojoUri("src/widget/templates/images/blank.gif"),
|
||||
|
||||
templateString:
|
||||
'<div class="dojoHtmlFisheyeListItem">' +
|
||||
' <img class="dojoHtmlFisheyeListItemImage" dojoAttachPoint="imgNode" dojoAttachEvent="onMouseOver;onMouseOut;onClick">' +
|
||||
' <div class="dojoHtmlFisheyeListItemLabel" dojoAttachPoint="lblNode"></div>' +
|
||||
'</div>',
|
||||
|
||||
imgNode: null,
|
||||
|
||||
fillInTemplate: function() {
|
||||
//
|
||||
// set image
|
||||
// TODO: turn on/off SVG support based on browser version.
|
||||
// this.parent.enableCrappySvgSupport is not available to this function
|
||||
//
|
||||
if (this.svgSrc != ""){
|
||||
this.svgNode = this.createSvgNode(this.svgSrc);
|
||||
this.domNode.appendChild(this.svgNode);
|
||||
this.imgNode.style.display = 'none';
|
||||
} else if((this.iconSrc.toLowerCase().substring(this.iconSrc.length-4)==".png")&&(dojo.render.html.ie)){
|
||||
this.imgNode.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.iconSrc+"', sizingMethod='scale')";
|
||||
this.imgNode.src = this.blankImgPath.toString();
|
||||
} else {
|
||||
this.imgNode.src = this.iconSrc;
|
||||
}
|
||||
|
||||
//
|
||||
// Label
|
||||
//
|
||||
if ( this.lblNode ) {
|
||||
this.lblNode.appendChild(document.createTextNode(this.caption));
|
||||
}
|
||||
dojo.html.disableSelection(this.domNode);
|
||||
},
|
||||
|
||||
createSvgNode: function(src){
|
||||
|
||||
var elm = document.createElement('embed');
|
||||
elm.src = src;
|
||||
elm.type = 'image/svg+xml';
|
||||
//elm.style.border = '1px solid black';
|
||||
elm.style.width = '1px';
|
||||
elm.style.height = '1px';
|
||||
elm.loaded = 0;
|
||||
elm.setSizeOnLoad = false;
|
||||
|
||||
elm.onload = function(){
|
||||
this.svgRoot = this.getSVGDocument().rootElement;
|
||||
this.svgDoc = this.getSVGDocument().documentElement;
|
||||
this.zeroWidth = this.svgRoot.width.baseVal.value;
|
||||
this.zeroHeight = this.svgRoot.height.baseVal.value;
|
||||
this.loaded = true;
|
||||
|
||||
if (this.setSizeOnLoad){
|
||||
this.setSize(this.setWidth, this.setHeight);
|
||||
}
|
||||
}
|
||||
|
||||
elm.setSize = function(w, h){
|
||||
if (!this.loaded){
|
||||
this.setWidth = w;
|
||||
this.setHeight = h;
|
||||
this.setSizeOnLoad = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this.style.width = w+'px';
|
||||
this.style.height = h+'px';
|
||||
this.svgRoot.width.baseVal.value = w;
|
||||
this.svgRoot.height.baseVal.value = h;
|
||||
|
||||
var scale_x = w / this.zeroWidth;
|
||||
var scale_y = h / this.zeroHeight;
|
||||
|
||||
for(var i=0; i<this.svgDoc.childNodes.length; i++){
|
||||
if (this.svgDoc.childNodes[i].setAttribute){
|
||||
this.svgDoc.childNodes[i].setAttribute( "transform", "scale("+scale_x+","+scale_y+")" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return elm;
|
||||
},
|
||||
|
||||
onMouseOver: function(e) {
|
||||
// in conservative mode, don't activate the menu until user mouses over an icon
|
||||
if( !this.parent.isOver ){
|
||||
this.parent.setActive(e);
|
||||
}
|
||||
if ( this.caption != "" ) {
|
||||
dojo.html.addClass(this.lblNode, "selected");
|
||||
this.parent.positionLabel(this);
|
||||
}
|
||||
},
|
||||
|
||||
onMouseOut: function() {
|
||||
dojo.html.removeClass(this.lblNode, "selected");
|
||||
},
|
||||
|
||||
onClick: function() {
|
||||
}
|
||||
});
|
||||
|
305
webapp/web/src/widget/FloatingPane.js
Normal file
305
webapp/web/src/widget/FloatingPane.js
Normal file
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.FloatingPane");
|
||||
dojo.provide("dojo.widget.html.FloatingPane");
|
||||
|
||||
//
|
||||
// this widget provides a window-like floating pane
|
||||
//
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.Manager");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.html.shadow");
|
||||
dojo.require("dojo.style");
|
||||
dojo.require("dojo.dom");
|
||||
dojo.require("dojo.html.layout");
|
||||
dojo.require("dojo.widget.ContentPane");
|
||||
dojo.require("dojo.dnd.HtmlDragMove");
|
||||
dojo.require("dojo.dnd.HtmlDragMoveSource");
|
||||
dojo.require("dojo.dnd.HtmlDragMoveObject");
|
||||
dojo.require("dojo.widget.ResizeHandle");
|
||||
|
||||
dojo.widget.html.FloatingPane = function(){
|
||||
dojo.widget.html.ContentPane.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.FloatingPane, dojo.widget.html.ContentPane);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.FloatingPane, {
|
||||
widgetType: "FloatingPane",
|
||||
|
||||
// Constructor arguments
|
||||
title: '',
|
||||
iconSrc: '',
|
||||
hasShadow: false,
|
||||
constrainToContainer: false,
|
||||
taskBarId: "",
|
||||
resizable: true,
|
||||
titleBarDisplay: "fancy",
|
||||
|
||||
windowState: "normal",
|
||||
displayCloseAction: false,
|
||||
displayMinimizeAction: false,
|
||||
displayMaximizeAction: false,
|
||||
|
||||
maxTaskBarConnectAttempts: 5,
|
||||
taskBarConnectAttempts: 0,
|
||||
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlFloatingPane.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlFloatingPane.css"),
|
||||
|
||||
drag: null,
|
||||
|
||||
fillInTemplate: function(args, frag){
|
||||
// Copy style info from input node to output node
|
||||
var source = this.getFragNodeRef(frag);
|
||||
dojo.html.copyStyle(this.domNode, source);
|
||||
|
||||
// necessary for safari, khtml (for computing width/height)
|
||||
document.body.appendChild(this.domNode);
|
||||
|
||||
// if display:none then state=minimized, otherwise state=normal
|
||||
if(!this.isShowing()){
|
||||
this.windowState="minimized";
|
||||
}
|
||||
|
||||
// <img src=""> can hang IE! better get rid of it
|
||||
if(this.iconSrc==""){
|
||||
dojo.dom.removeNode(this.titleBarIcon);
|
||||
}else{
|
||||
this.titleBarIcon.src = this.iconSrc.toString();// dojo.uri.Uri obj req. toString()
|
||||
}
|
||||
|
||||
if(this.titleBarDisplay!="none"){
|
||||
this.titleBar.style.display="";
|
||||
dojo.html.disableSelection(this.titleBar);
|
||||
|
||||
this.titleBarIcon.style.display = (this.iconSrc=="" ? "none" : "");
|
||||
|
||||
this.minimizeAction.style.display = (this.displayMinimizeAction ? "" : "none");
|
||||
this.maximizeAction.style.display=
|
||||
(this.displayMaximizeAction && this.windowState!="maximized" ? "" : "none");
|
||||
this.restoreAction.style.display=
|
||||
(this.displayMaximizeAction && this.windowState=="maximized" ? "" : "none");
|
||||
this.closeAction.style.display= (this.displayCloseAction ? "" : "none");
|
||||
|
||||
this.drag = new dojo.dnd.HtmlDragMoveSource(this.domNode);
|
||||
if (this.constrainToContainer) {
|
||||
this.drag.constrainTo();
|
||||
}
|
||||
this.drag.setDragHandle(this.titleBar);
|
||||
|
||||
var self = this;
|
||||
|
||||
dojo.event.topic.subscribe("dragMove",
|
||||
function (info){
|
||||
if (info.source.domNode == self.domNode){
|
||||
dojo.event.topic.publish('floatingPaneMove', { source: self } );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
if(this.resizable){
|
||||
this.resizeBar.style.display="";
|
||||
var rh = dojo.widget.createWidget("ResizeHandle", {targetElmId: this.widgetId, id:this.widgetId+"_resize"});
|
||||
this.resizeBar.appendChild(rh.domNode);
|
||||
}
|
||||
|
||||
// add a drop shadow
|
||||
if(this.hasShadow){
|
||||
this.shadow=new dojo.html.shadow(this.domNode);
|
||||
}
|
||||
|
||||
// Prevent IE bleed-through problem
|
||||
this.bgIframe = new dojo.html.BackgroundIframe(this.domNode);
|
||||
|
||||
if( this.taskBarId ){
|
||||
this.taskBarSetup();
|
||||
}
|
||||
|
||||
if (dojo.hostenv.post_load_) {
|
||||
this.setInitialWindowState();
|
||||
} else {
|
||||
dojo.addOnLoad(this, "setInitialWindowState");
|
||||
}
|
||||
|
||||
// counteract body.appendChild above
|
||||
document.body.removeChild(this.domNode);
|
||||
|
||||
dojo.widget.html.FloatingPane.superclass.fillInTemplate.call(this, args, frag);
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
if(this.isShowing()){
|
||||
this.width=-1; // force resize
|
||||
this.resizeTo(dojo.style.getOuterWidth(this.domNode), dojo.style.getOuterHeight(this.domNode));
|
||||
}
|
||||
},
|
||||
|
||||
maximizeWindow: function(evt) {
|
||||
this.previous={
|
||||
width: dojo.style.getOuterWidth(this.domNode) || this.width,
|
||||
height: dojo.style.getOuterHeight(this.domNode) || this.height,
|
||||
left: this.domNode.style.left,
|
||||
top: this.domNode.style.top,
|
||||
bottom: this.domNode.style.bottom,
|
||||
right: this.domNode.style.right
|
||||
};
|
||||
this.domNode.style.left =
|
||||
dojo.style.getPixelValue(this.domNode.parentNode, "padding-left", true) + "px";
|
||||
this.domNode.style.top =
|
||||
dojo.style.getPixelValue(this.domNode.parentNode, "padding-top", true) + "px";
|
||||
|
||||
if ((this.domNode.parentNode.nodeName.toLowerCase() == 'body')) {
|
||||
this.resizeTo(
|
||||
dojo.html.getViewportWidth()-dojo.style.getPaddingWidth(document.body),
|
||||
dojo.html.getViewportHeight()-dojo.style.getPaddingHeight(document.body)
|
||||
);
|
||||
} else {
|
||||
this.resizeTo(
|
||||
dojo.style.getContentWidth(this.domNode.parentNode),
|
||||
dojo.style.getContentHeight(this.domNode.parentNode)
|
||||
);
|
||||
}
|
||||
this.maximizeAction.style.display="none";
|
||||
this.restoreAction.style.display="";
|
||||
this.windowState="maximized";
|
||||
},
|
||||
|
||||
minimizeWindow: function(evt) {
|
||||
this.hide();
|
||||
this.windowState = "minimized";
|
||||
},
|
||||
|
||||
restoreWindow: function(evt) {
|
||||
if (this.windowState=="minimized") {
|
||||
this.show()
|
||||
} else {
|
||||
for(var attr in this.previous){
|
||||
this.domNode.style[attr] = this.previous[attr];
|
||||
}
|
||||
this.resizeTo(this.previous.width, this.previous.height);
|
||||
this.previous=null;
|
||||
|
||||
this.restoreAction.style.display="none";
|
||||
this.maximizeAction.style.display=this.displayMaximizeAction ? "" : "none";
|
||||
}
|
||||
|
||||
this.windowState="normal";
|
||||
},
|
||||
|
||||
closeWindow: function(evt) {
|
||||
dojo.dom.removeNode(this.domNode);
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
onMouseDown: function(evt) {
|
||||
this.bringToTop();
|
||||
},
|
||||
|
||||
bringToTop: function() {
|
||||
var floatingPanes= dojo.widget.manager.getWidgetsByType(this.widgetType);
|
||||
var windows = [];
|
||||
for (var x=0; x<floatingPanes.length; x++) {
|
||||
if (this.widgetId != floatingPanes[x].widgetId) {
|
||||
windows.push(floatingPanes[x]);
|
||||
}
|
||||
}
|
||||
|
||||
windows.sort(function(a,b) {
|
||||
return a.domNode.style.zIndex - b.domNode.style.zIndex;
|
||||
});
|
||||
|
||||
windows.push(this);
|
||||
|
||||
var floatingPaneStartingZ = 100;
|
||||
for (x=0; x<windows.length;x++) {
|
||||
windows[x].domNode.style.zIndex = floatingPaneStartingZ + x;
|
||||
}
|
||||
},
|
||||
|
||||
setInitialWindowState: function() {
|
||||
if (this.windowState == "maximized") {
|
||||
this.maximizeWindow();
|
||||
this.show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.windowState=="normal") {
|
||||
this.show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.windowState=="minimized") {
|
||||
this.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
this.windowState="minimized";
|
||||
},
|
||||
|
||||
// add icon to task bar, connected to me
|
||||
taskBarSetup: function() {
|
||||
var taskbar = dojo.widget.getWidgetById(this.taskBarId);
|
||||
if (!taskbar){
|
||||
if (this.taskBarConnectAttempts < this.maxTaskBarConnectAttempts) {
|
||||
dojo.lang.setTimeout(this, this.taskBarSetup, 50);
|
||||
this.taskBarConnectAttempts++;
|
||||
} else {
|
||||
dojo.debug("Unable to connect to the taskBar");
|
||||
}
|
||||
return;
|
||||
}
|
||||
taskbar.addChild(this);
|
||||
},
|
||||
|
||||
show: function(){
|
||||
dojo.widget.html.FloatingPane.superclass.show.apply(this, arguments);
|
||||
this.bringToTop();
|
||||
},
|
||||
|
||||
onShow: function(){
|
||||
dojo.widget.html.FloatingPane.superclass.onShow.call(this);
|
||||
this.resizeTo(dojo.style.getOuterWidth(this.domNode), dojo.style.getOuterHeight(this.domNode));
|
||||
},
|
||||
|
||||
// This is called when the user adjusts the size of the floating pane
|
||||
resizeTo: function(w, h){
|
||||
dojo.style.setOuterWidth(this.domNode, w);
|
||||
dojo.style.setOuterHeight(this.domNode, h);
|
||||
|
||||
dojo.html.layout(this.domNode,
|
||||
[
|
||||
{domNode: this.titleBar, layoutAlign: "top"},
|
||||
{domNode: this.resizeBar, layoutAlign: "bottom"},
|
||||
{domNode: this.containerNode, layoutAlign: "client"}
|
||||
] );
|
||||
|
||||
// If any of the children have layoutAlign specified, obey it
|
||||
dojo.html.layout(this.containerNode, this.children, "top-bottom");
|
||||
|
||||
this.bgIframe.onResized();
|
||||
if(this.shadow){ this.shadow.size(w, h); }
|
||||
this.onResized();
|
||||
},
|
||||
|
||||
checkSize: function() {
|
||||
// checkSize() is called when the user has resized the browser window,
|
||||
// but that doesn't affect this widget (or this widget's children)
|
||||
// so it can be safely ignored...
|
||||
// TODO: unless we are maximized. then we should resize ourself.
|
||||
}
|
||||
});
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:FloatingPane");
|
44
webapp/web/src/widget/GoogleMap.js
Normal file
44
webapp/web/src/widget/GoogleMap.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.GoogleMap");
|
||||
dojo.provide("dojo.widget.GoogleMap.Controls");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:googlemap");
|
||||
|
||||
dojo.widget.GoogleMap=function(){
|
||||
// summary
|
||||
// base class for the Google Map widget
|
||||
dojo.widget.Widget.call(this);
|
||||
this.widgetType="GoogleMap";
|
||||
this.isContainer=false;
|
||||
}
|
||||
dojo.inherits(dojo.widget.GoogleMap, dojo.widget.Widget);
|
||||
|
||||
dojo.widget.GoogleMap.Controls={
|
||||
LargeMap:"largemap",
|
||||
SmallMap:"smallmap",
|
||||
SmallZoom:"smallzoom",
|
||||
Scale:"scale",
|
||||
MapType:"maptype",
|
||||
Overview:"overview",
|
||||
get:function(s){
|
||||
for(var p in this){
|
||||
if(typeof(this[p])=="string"
|
||||
&& this[p]==s
|
||||
){
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.GoogleMap");
|
163
webapp/web/src/widget/HtmlWidget.js
Normal file
163
webapp/web/src/widget/HtmlWidget.js
Normal file
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.widget.DomWidget");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.html.extras");
|
||||
dojo.require("dojo.lang.extras");
|
||||
dojo.require("dojo.lang.func");
|
||||
dojo.require("dojo.lfx.toggle");
|
||||
|
||||
dojo.declare("dojo.widget.HtmlWidget", dojo.widget.DomWidget, {
|
||||
widgetType: "HtmlWidget",
|
||||
|
||||
templateCssPath: null,
|
||||
templatePath: null,
|
||||
|
||||
// for displaying/hiding widget
|
||||
toggle: "plain",
|
||||
toggleDuration: 150,
|
||||
|
||||
animationInProgress: false,
|
||||
|
||||
initialize: function(args, frag){
|
||||
},
|
||||
|
||||
postMixInProperties: function(args, frag){
|
||||
// now that we know the setting for toggle, get toggle object
|
||||
// (default to plain toggler if user specified toggler not present)
|
||||
this.toggleObj =
|
||||
dojo.lfx.toggle[this.toggle.toLowerCase()] || dojo.lfx.toggle.plain;
|
||||
},
|
||||
|
||||
getContainerHeight: function(){
|
||||
// NOTE: container height must be returned as the INNER height
|
||||
dojo.unimplemented("dojo.widget.HtmlWidget.getContainerHeight");
|
||||
},
|
||||
|
||||
getContainerWidth: function(){
|
||||
return this.parent.domNode.offsetWidth;
|
||||
},
|
||||
|
||||
setNativeHeight: function(height){
|
||||
var ch = this.getContainerHeight();
|
||||
},
|
||||
|
||||
createNodesFromText: function(txt, wrap){
|
||||
return dojo.html.createNodesFromText(txt, wrap);
|
||||
},
|
||||
|
||||
destroyRendering: function(finalize){
|
||||
try{
|
||||
if(!finalize){
|
||||
dojo.event.browser.clean(this.domNode);
|
||||
}
|
||||
this.domNode.parentNode.removeChild(this.domNode);
|
||||
delete this.domNode;
|
||||
}catch(e){ /* squelch! */ }
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
// Displaying/hiding the widget
|
||||
/////////////////////////////////////////////////////////
|
||||
isShowing: function(){
|
||||
return dojo.style.isShowing(this.domNode);
|
||||
},
|
||||
|
||||
toggleShowing: function(){
|
||||
// dojo.style.toggleShowing(this.domNode);
|
||||
if(this.isHidden){
|
||||
this.show();
|
||||
}else{
|
||||
this.hide();
|
||||
}
|
||||
},
|
||||
|
||||
show: function(){
|
||||
this.animationInProgress=true;
|
||||
this.isHidden = false;
|
||||
this.toggleObj.show(this.domNode, this.toggleDuration, null,
|
||||
dojo.lang.hitch(this, this.onShow), this.explodeSrc);
|
||||
},
|
||||
|
||||
// called after the show() animation has completed
|
||||
onShow: function(){
|
||||
this.animationInProgress=false;
|
||||
this.checkSize();
|
||||
},
|
||||
|
||||
hide: function(){
|
||||
this.animationInProgress = true;
|
||||
this.isHidden = true;
|
||||
this.toggleObj.hide(this.domNode, this.toggleDuration, null,
|
||||
dojo.lang.hitch(this, this.onHide), this.explodeSrc);
|
||||
},
|
||||
|
||||
// called after the hide() animation has completed
|
||||
onHide: function(){
|
||||
this.animationInProgress=false;
|
||||
},
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Sizing related methods
|
||||
// If the parent changes size then for each child it should call either
|
||||
// - resizeTo(): size the child explicitly
|
||||
// - or checkSize(): notify the child the the parent has changed size
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Test if my size has changed.
|
||||
// If width & height are specified then that's my new size; otherwise,
|
||||
// query outerWidth/outerHeight of my domNode
|
||||
_isResized: function(w, h){
|
||||
// If I'm not being displayed then disregard (show() must
|
||||
// check if the size has changed)
|
||||
if(!this.isShowing()){ return false; }
|
||||
|
||||
// If my parent has been resized and I have style="height: 100%"
|
||||
// or something similar then my size has changed too.
|
||||
w=w||dojo.style.getOuterWidth(this.domNode);
|
||||
h=h||dojo.style.getOuterHeight(this.domNode);
|
||||
if(this.width == w && this.height == h){ return false; }
|
||||
|
||||
this.width=w;
|
||||
this.height=h;
|
||||
return true;
|
||||
},
|
||||
|
||||
// Called when my parent has changed size, but my parent won't call resizeTo().
|
||||
// This is useful if my size is height:100% or something similar.
|
||||
// Also called whenever I am shown, because the first time I am shown I may need
|
||||
// to do size calculations.
|
||||
checkSize: function(){
|
||||
if(!this._isResized()){ return; }
|
||||
this.onResized();
|
||||
},
|
||||
|
||||
// Explicitly set this widget's size (in pixels).
|
||||
resizeTo: function(w, h){
|
||||
if(!this._isResized(w,h)){ return; }
|
||||
dojo.style.setOuterWidth(this.domNode, w);
|
||||
dojo.style.setOuterHeight(this.domNode, h);
|
||||
this.onResized();
|
||||
},
|
||||
|
||||
resizeSoon: function(){
|
||||
if(this.isShowing()){
|
||||
dojo.lang.setTimeout(this, this.onResized, 0);
|
||||
}
|
||||
},
|
||||
|
||||
// Called when my size has changed.
|
||||
// Must notify children if their size has (possibly) changed
|
||||
onResized: function(){
|
||||
dojo.lang.forEach(this.children, function(child){ child.checkSize(); });
|
||||
}
|
||||
});
|
172
webapp/web/src/widget/InlineEditBox.js
Normal file
172
webapp/web/src/widget/InlineEditBox.js
Normal file
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.InlineEditBox");
|
||||
dojo.provide("dojo.widget.html.InlineEditBox");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.lfx.*");
|
||||
dojo.require("dojo.graphics.color");
|
||||
dojo.require("dojo.string");
|
||||
dojo.require("dojo.style");
|
||||
dojo.require("dojo.html");
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:inlineeditbox");
|
||||
|
||||
dojo.widget.html.InlineEditBox = function(){
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
// mutable objects need to be in constructor to give each instance its own copy
|
||||
this.history = [];
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.InlineEditBox, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.InlineEditBox, {
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlInlineEditBox.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlInlineEditBox.css"),
|
||||
widgetType: "InlineEditBox",
|
||||
|
||||
form: null,
|
||||
editBox: null,
|
||||
edit: null,
|
||||
text: null,
|
||||
textarea: null,
|
||||
submitButton: null,
|
||||
cancelButton: null,
|
||||
mode: "text",
|
||||
|
||||
minWidth: 100, //px. minimum width of edit box
|
||||
minHeight: 200, //px. minimum width of edit box, if it's a TA
|
||||
|
||||
editing: false,
|
||||
textValue: "",
|
||||
defaultText: "",
|
||||
doFade: false,
|
||||
|
||||
onSave: function(newValue, oldValue){},
|
||||
onUndo: function(value){},
|
||||
|
||||
postCreate: function(args, frag){
|
||||
// put original node back in the document, and attach handlers
|
||||
// which hide it and display the editor
|
||||
this.editable = this.getFragNodeRef(frag);
|
||||
dojo.dom.insertAfter(this.editable, this.form);
|
||||
dojo.event.connect(this.editable, "onmouseover", this, "mouseover");
|
||||
dojo.event.connect(this.editable, "onmouseout", this, "mouseout");
|
||||
dojo.event.connect(this.editable, "onclick", this, "beginEdit");
|
||||
|
||||
this.textValue = dojo.string.trim(this.editable.innerHTML);
|
||||
if(dojo.string.trim(this.textValue).length == 0){
|
||||
this.editable.innerHTML = this.defaultText;
|
||||
}
|
||||
},
|
||||
|
||||
mouseover: function(e){
|
||||
if(!this.editing){
|
||||
dojo.html.addClass(this.editable, "editableRegion");
|
||||
if(this.mode == "textarea"){
|
||||
dojo.html.addClass(this.editable, "editableTextareaRegion");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mouseout: function(e){
|
||||
if(!this.editing){
|
||||
dojo.html.removeClass(this.editable, "editableRegion");
|
||||
dojo.html.removeClass(this.editable, "editableTextareaRegion");
|
||||
}
|
||||
},
|
||||
|
||||
// When user clicks the text, then start editing.
|
||||
// Hide the text and display the form instead.
|
||||
beginEdit: function(e){
|
||||
if(this.editing){ return; }
|
||||
this.mouseout();
|
||||
this.editing = true;
|
||||
|
||||
// setup the form's <input> or <textarea> field, as specified by mode
|
||||
var ee = this[this.mode.toLowerCase()];
|
||||
ee.value = dojo.string.trim(this.textValue);
|
||||
ee.style.fontSize = dojo.style.getStyle(this.editable, "font-size");
|
||||
ee.style.fontWeight = dojo.style.getStyle(this.editable, "font-weight");
|
||||
ee.style.fontStyle = dojo.style.getStyle(this.editable, "font-style");
|
||||
ee.style.width = Math.max(dojo.html.getInnerWidth(this.editable), this.minWidth) + "px";
|
||||
if(this.mode.toLowerCase()=="textarea"){
|
||||
ee.style.display = "block";
|
||||
ee.style.height = Math.max(dojo.html.getInnerHeight(this.editable), this.minHeight) + "px";
|
||||
} else {
|
||||
ee.style.display = "";
|
||||
}
|
||||
|
||||
// show the edit form and hide the read only version of the text
|
||||
this.form.style.display = "";
|
||||
this.editable.style.display = "none";
|
||||
|
||||
ee.select();
|
||||
this.submitButton.disabled = true;
|
||||
},
|
||||
|
||||
saveEdit: function(e){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var ee = this[this.mode.toLowerCase()];
|
||||
if((this.textValue != ee.value)&&
|
||||
(dojo.string.trim(ee.value) != "")){
|
||||
this.doFade = true;
|
||||
this.history.push(this.textValue);
|
||||
this.onSave(ee.value, this.textValue);
|
||||
this.textValue = ee.value;
|
||||
this.editable.innerHTML = this.textValue;
|
||||
}else{
|
||||
this.doFade = false;
|
||||
}
|
||||
this.finishEdit(e);
|
||||
},
|
||||
|
||||
cancelEdit: function(e){
|
||||
if(!this.editing){ return false; }
|
||||
this.editing = false;
|
||||
this.form.style.display="none";
|
||||
this.editable.style.display = "";
|
||||
return true;
|
||||
},
|
||||
|
||||
finishEdit: function(e){
|
||||
if(!this.cancelEdit(e)){ return; }
|
||||
if(this.doFade) {
|
||||
dojo.lfx.highlight(this.editable, dojo.graphics.color.hex2rgb("#ffc"), 700).play(300);
|
||||
}
|
||||
this.doFade = false;
|
||||
},
|
||||
|
||||
setText: function(txt){
|
||||
// sets the text without informing the server
|
||||
var tt = dojo.string.trim(txt);
|
||||
this.textValue = tt
|
||||
this.editable.innerHTML = tt;
|
||||
},
|
||||
|
||||
undo: function(){
|
||||
if(this.history.length > 0){
|
||||
var value = this.history.pop();
|
||||
this.editable.innerHTML = value;
|
||||
this.textValue = value;
|
||||
this.onUndo(value);
|
||||
}
|
||||
},
|
||||
|
||||
checkForValueChange: function(){
|
||||
var ee = this[this.mode.toLowerCase()];
|
||||
if((this.textValue != ee.value)&&
|
||||
(dojo.string.trim(ee.value) != "")){
|
||||
this.submitButton.disabled = false;
|
||||
}
|
||||
}
|
||||
});
|
70
webapp/web/src/widget/LayoutContainer.js
Normal file
70
webapp/web/src/widget/LayoutContainer.js
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
//
|
||||
// this widget provides Delphi-style panel layout semantics
|
||||
//
|
||||
|
||||
dojo.provide("dojo.widget.LayoutContainer");
|
||||
dojo.provide("dojo.widget.html.LayoutContainer");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.html.layout");
|
||||
|
||||
dojo.widget.html.LayoutContainer = function(){
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.LayoutContainer, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.LayoutContainer, {
|
||||
widgetType: "LayoutContainer",
|
||||
isContainer: true,
|
||||
|
||||
layoutChildPriority: 'top-bottom',
|
||||
|
||||
postCreate: function(){
|
||||
dojo.html.layout(this.domNode, this.children, this.layoutChildPriority);
|
||||
},
|
||||
|
||||
addChild: function(child, overrideContainerNode, pos, ref, insertIndex){
|
||||
dojo.widget.html.LayoutContainer.superclass.addChild.call(this, child, overrideContainerNode, pos, ref, insertIndex);
|
||||
dojo.html.layout(this.domNode, this.children, this.layoutChildPriority);
|
||||
},
|
||||
|
||||
removeChild: function(pane){
|
||||
dojo.widget.html.LayoutContainer.superclass.removeChild.call(this,pane);
|
||||
dojo.html.layout(this.domNode, this.children, this.layoutChildPriority);
|
||||
},
|
||||
|
||||
onResized: function(){
|
||||
dojo.html.layout(this.domNode, this.children, this.layoutChildPriority);
|
||||
},
|
||||
|
||||
show: function(){
|
||||
// If this node was created while display=="none" then it
|
||||
// hasn't been laid out yet. Do that now.
|
||||
this.domNode.style.display="";
|
||||
this.checkSize();
|
||||
this.domNode.style.display="none";
|
||||
this.domNode.style.visibility="";
|
||||
|
||||
dojo.widget.html.LayoutContainer.superclass.show.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
// This argument can be specified for the children of a LayoutContainer.
|
||||
// Since any widget can be specified as a LayoutContainer child, mix it
|
||||
// into the base widget class. (This is a hack, but it's effective.)
|
||||
dojo.lang.extend(dojo.widget.Widget, {
|
||||
layoutAlign: 'none'
|
||||
});
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:LayoutContainer");
|
17
webapp/web/src/widget/LinkPane.js
Normal file
17
webapp/web/src/widget/LinkPane.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.LinkPane");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.LinkPane");
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:LinkPane");
|
||||
|
||||
// NOTE: there's no stub file for this widget
|
306
webapp/web/src/widget/Manager.js
Normal file
306
webapp/web/src/widget/Manager.js
Normal file
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Manager");
|
||||
dojo.require("dojo.lang.array");
|
||||
dojo.require("dojo.lang.func");
|
||||
dojo.require("dojo.event.*");
|
||||
|
||||
// Manager class
|
||||
dojo.widget.manager = new function(){
|
||||
this.widgets = [];
|
||||
this.widgetIds = [];
|
||||
|
||||
// map of widgetId-->widget for widgets without parents (top level widgets)
|
||||
this.topWidgets = {};
|
||||
|
||||
var widgetTypeCtr = {};
|
||||
var renderPrefixCache = [];
|
||||
|
||||
this.getUniqueId = function (widgetType) {
|
||||
return widgetType + "_" + (widgetTypeCtr[widgetType] != undefined ?
|
||||
++widgetTypeCtr[widgetType] : widgetTypeCtr[widgetType] = 0);
|
||||
}
|
||||
|
||||
this.add = function(widget){
|
||||
dojo.profile.start("dojo.widget.manager.add");
|
||||
this.widgets.push(widget);
|
||||
// Opera9 uses ID (caps)
|
||||
if(!widget.extraArgs["id"]){
|
||||
widget.extraArgs["id"] = widget.extraArgs["ID"];
|
||||
}
|
||||
// FIXME: the rest of this method is very slow!
|
||||
if(widget.widgetId == ""){
|
||||
if(widget["id"]){
|
||||
widget.widgetId = widget["id"];
|
||||
}else if(widget.extraArgs["id"]){
|
||||
widget.widgetId = widget.extraArgs["id"];
|
||||
}else{
|
||||
widget.widgetId = this.getUniqueId(widget.widgetType);
|
||||
}
|
||||
}
|
||||
if(this.widgetIds[widget.widgetId]){
|
||||
dojo.debug("widget ID collision on ID: "+widget.widgetId);
|
||||
}
|
||||
this.widgetIds[widget.widgetId] = widget;
|
||||
// Widget.destroy already calls removeById(), so we don't need to
|
||||
// connect() it here
|
||||
dojo.profile.end("dojo.widget.manager.add");
|
||||
}
|
||||
|
||||
this.destroyAll = function(){
|
||||
for(var x=this.widgets.length-1; x>=0; x--){
|
||||
try{
|
||||
// this.widgets[x].destroyChildren();
|
||||
this.widgets[x].destroy(true);
|
||||
delete this.widgets[x];
|
||||
}catch(e){ }
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: we should never allow removal of the root widget until all others
|
||||
// are removed!
|
||||
this.remove = function(widgetIndex){
|
||||
var tw = this.widgets[widgetIndex].widgetId;
|
||||
delete this.widgetIds[tw];
|
||||
this.widgets.splice(widgetIndex, 1);
|
||||
}
|
||||
|
||||
// FIXME: suboptimal performance
|
||||
this.removeById = function(id) {
|
||||
for (var i=0; i<this.widgets.length; i++){
|
||||
if(this.widgets[i].widgetId == id){
|
||||
this.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.getWidgetById = function(id){
|
||||
return this.widgetIds[id];
|
||||
}
|
||||
|
||||
this.getWidgetsByType = function(type){
|
||||
var lt = type.toLowerCase();
|
||||
var ret = [];
|
||||
dojo.lang.forEach(this.widgets, function(x){
|
||||
if(x.widgetType.toLowerCase() == lt){
|
||||
ret.push(x);
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
this.getWidgetsOfType = function (id) {
|
||||
dojo.deprecated("getWidgetsOfType", "use getWidgetsByType", "0.4");
|
||||
return dojo.widget.manager.getWidgetsByType(id);
|
||||
}
|
||||
|
||||
this.getWidgetsByFilter = function(unaryFunc, onlyOne){
|
||||
var ret = [];
|
||||
dojo.lang.every(this.widgets, function(x){
|
||||
if(unaryFunc(x)){
|
||||
ret.push(x);
|
||||
if(onlyOne){return false;}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return (onlyOne ? ret[0] : ret);
|
||||
}
|
||||
|
||||
this.getAllWidgets = function() {
|
||||
return this.widgets.concat();
|
||||
}
|
||||
|
||||
// added, trt 2006-01-20
|
||||
this.getWidgetByNode = function(/* DOMNode */ node){
|
||||
var w=this.getAllWidgets();
|
||||
for (var i=0; i<w.length; i++){
|
||||
if (w[i].domNode==node){
|
||||
return w[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// shortcuts, baby
|
||||
this.byId = this.getWidgetById;
|
||||
this.byType = this.getWidgetsByType;
|
||||
this.byFilter = this.getWidgetsByFilter;
|
||||
this.byNode = this.getWidgetByNode;
|
||||
|
||||
// map of previousally discovered implementation names to constructors
|
||||
var knownWidgetImplementations = {};
|
||||
|
||||
// support manually registered widget packages
|
||||
var widgetPackages = ["dojo.widget"];
|
||||
for (var i=0; i<widgetPackages.length; i++) {
|
||||
// convenience for checking if a package exists (reverse lookup)
|
||||
widgetPackages[widgetPackages[i]] = true;
|
||||
}
|
||||
|
||||
this.registerWidgetPackage = function(pname) {
|
||||
if(!widgetPackages[pname]){
|
||||
widgetPackages[pname] = true;
|
||||
widgetPackages.push(pname);
|
||||
}
|
||||
}
|
||||
|
||||
this.getWidgetPackageList = function() {
|
||||
return dojo.lang.map(widgetPackages, function(elt) { return(elt!==true ? elt : undefined); });
|
||||
}
|
||||
|
||||
this.getImplementation = function(widgetName, ctorObject, mixins){
|
||||
// try and find a name for the widget
|
||||
var impl = this.getImplementationName(widgetName);
|
||||
if(impl){
|
||||
// var tic = new Date();
|
||||
var ret = new impl(ctorObject);
|
||||
// dojo.debug(new Date() - tic);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
this.getImplementationName = function(widgetName){
|
||||
/*
|
||||
* This is the overly-simplistic implemention of getImplementation (har
|
||||
* har). In the future, we are going to want something that allows more
|
||||
* freedom of expression WRT to specifying different specializations of
|
||||
* a widget.
|
||||
*
|
||||
* Additionally, this implementation treats widget names as case
|
||||
* insensitive, which does not necessarialy mesh with the markup which
|
||||
* can construct a widget.
|
||||
*/
|
||||
|
||||
var lowerCaseWidgetName = widgetName.toLowerCase();
|
||||
|
||||
var impl = knownWidgetImplementations[lowerCaseWidgetName];
|
||||
if(impl){
|
||||
return impl;
|
||||
}
|
||||
|
||||
// first store a list of the render prefixes we are capable of rendering
|
||||
if(!renderPrefixCache.length){
|
||||
for(var renderer in dojo.render){
|
||||
if(dojo.render[renderer]["capable"] === true){
|
||||
var prefixes = dojo.render[renderer].prefixes;
|
||||
for(var i = 0; i < prefixes.length; i++){
|
||||
renderPrefixCache.push(prefixes[i].toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
// make sure we don't HAVE to prefix widget implementation names
|
||||
// with anything to get them to render
|
||||
renderPrefixCache.push("");
|
||||
}
|
||||
|
||||
// look for a rendering-context specific version of our widget name
|
||||
for(var i = 0; i < widgetPackages.length; i++){
|
||||
var widgetPackage = dojo.evalObjPath(widgetPackages[i]);
|
||||
if(!widgetPackage) { continue; }
|
||||
|
||||
for (var j = 0; j < renderPrefixCache.length; j++) {
|
||||
if (!widgetPackage[renderPrefixCache[j]]) { continue; }
|
||||
for (var widgetClass in widgetPackage[renderPrefixCache[j]]) {
|
||||
if (widgetClass.toLowerCase() != lowerCaseWidgetName) { continue; }
|
||||
knownWidgetImplementations[lowerCaseWidgetName] =
|
||||
widgetPackage[renderPrefixCache[j]][widgetClass];
|
||||
return knownWidgetImplementations[lowerCaseWidgetName];
|
||||
}
|
||||
}
|
||||
|
||||
for (var j = 0; j < renderPrefixCache.length; j++) {
|
||||
for (var widgetClass in widgetPackage) {
|
||||
if (widgetClass.toLowerCase() !=
|
||||
(renderPrefixCache[j] + lowerCaseWidgetName)) { continue; }
|
||||
|
||||
knownWidgetImplementations[lowerCaseWidgetName] =
|
||||
widgetPackage[widgetClass];
|
||||
return knownWidgetImplementations[lowerCaseWidgetName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('Could not locate "' + widgetName + '" class');
|
||||
}
|
||||
|
||||
// FIXME: does it even belong in this name space?
|
||||
// NOTE: this method is implemented by DomWidget.js since not all
|
||||
// hostenv's would have an implementation.
|
||||
/*this.getWidgetFromPrimitive = function(baseRenderType){
|
||||
dojo.unimplemented("dojo.widget.manager.getWidgetFromPrimitive");
|
||||
}
|
||||
|
||||
this.getWidgetFromEvent = function(nativeEvt){
|
||||
dojo.unimplemented("dojo.widget.manager.getWidgetFromEvent");
|
||||
}*/
|
||||
|
||||
// Catch window resize events and notify top level widgets
|
||||
this.resizing=false;
|
||||
this.onWindowResized = function(){
|
||||
if(this.resizing){
|
||||
return; // duplicate event
|
||||
}
|
||||
try{
|
||||
this.resizing=true;
|
||||
for(var id in this.topWidgets){
|
||||
var child = this.topWidgets[id];
|
||||
if(child.checkSize ){
|
||||
child.checkSize();
|
||||
}
|
||||
};
|
||||
}catch(e){
|
||||
}finally{
|
||||
this.resizing=false;
|
||||
}
|
||||
}
|
||||
if(typeof window != "undefined") {
|
||||
dojo.addOnLoad(this, 'onWindowResized'); // initial sizing
|
||||
dojo.event.connect(window, 'onresize', this, 'onWindowResized'); // window resize
|
||||
}
|
||||
|
||||
// FIXME: what else?
|
||||
};
|
||||
|
||||
(function(){
|
||||
var dw = dojo.widget;
|
||||
var dwm = dw.manager;
|
||||
var h = dojo.lang.curry(dojo.lang, "hitch", dwm);
|
||||
var g = function(oldName, newName){
|
||||
dw[(newName||oldName)] = h(oldName);
|
||||
}
|
||||
// copy the methods from the default manager (this) to the widget namespace
|
||||
g("add", "addWidget");
|
||||
g("destroyAll", "destroyAllWidgets");
|
||||
g("remove", "removeWidget");
|
||||
g("removeById", "removeWidgetById");
|
||||
g("getWidgetById");
|
||||
g("getWidgetById", "byId");
|
||||
g("getWidgetsByType");
|
||||
g("getWidgetsByFilter");
|
||||
g("getWidgetsByType", "byType");
|
||||
g("getWidgetsByFilter", "byFilter");
|
||||
g("getWidgetByNode", "byNode");
|
||||
dw.all = function(n){
|
||||
var widgets = dwm.getAllWidgets.apply(dwm, arguments);
|
||||
if(arguments.length > 0) {
|
||||
return widgets[n];
|
||||
}
|
||||
return widgets;
|
||||
}
|
||||
g("registerWidgetPackage");
|
||||
g("getImplementation", "getWidgetImplementation");
|
||||
g("getImplementationName", "getWidgetImplementationName");
|
||||
|
||||
dw.widgets = dwm.widgets;
|
||||
dw.widgetIds = dwm.widgetIds;
|
||||
dw.root = dwm.root;
|
||||
})();
|
59
webapp/web/src/widget/Menu.js
Normal file
59
webapp/web/src/widget/Menu.js
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Menu");
|
||||
dojo.provide("dojo.widget.DomMenu");
|
||||
|
||||
dojo.deprecated("dojo.widget.Menu, dojo.widget.DomMenu", "use dojo.widget.Menu2", "0.4");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:menu");
|
||||
|
||||
/* Menu
|
||||
*******/
|
||||
|
||||
dojo.widget.Menu = function () {
|
||||
dojo.widget.Menu.superclass.constructor.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.Menu, dojo.widget.Widget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.Menu, {
|
||||
widgetType: "Menu",
|
||||
isContainer: true,
|
||||
|
||||
items: [],
|
||||
push: function(item){
|
||||
dojo.connect.event(item, "onSelect", this, "onSelect");
|
||||
this.items.push(item);
|
||||
},
|
||||
onSelect: function(){}
|
||||
});
|
||||
|
||||
|
||||
/* DomMenu
|
||||
**********/
|
||||
|
||||
dojo.widget.DomMenu = function(){
|
||||
dojo.widget.DomMenu.superclass.constructor.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.DomMenu, dojo.widget.DomWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.DomMenu, {
|
||||
widgetType: "Menu",
|
||||
isContainer: true,
|
||||
|
||||
push: function (item) {
|
||||
dojo.widget.Menu.call(this, item);
|
||||
this.domNode.appendChild(item.domNode);
|
||||
}
|
||||
});
|
||||
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.Menu");
|
1190
webapp/web/src/widget/Menu2.js
Normal file
1190
webapp/web/src/widget/Menu2.js
Normal file
File diff suppressed because it is too large
Load diff
47
webapp/web/src/widget/MenuItem.js
Normal file
47
webapp/web/src/widget/MenuItem.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.MenuItem");
|
||||
dojo.provide("dojo.widget.DomMenuItem");
|
||||
|
||||
dojo.deprecated("dojo.widget.MenuItem, dojo.widget.DomMenuItem", "use dojo.widget.Menu2", "0.4");
|
||||
|
||||
dojo.require("dojo.string");
|
||||
dojo.require("dojo.widget.*");
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:MenuItem");
|
||||
|
||||
/* MenuItem
|
||||
***********/
|
||||
|
||||
dojo.widget.MenuItem = function(){
|
||||
dojo.widget.MenuItem.superclass.constructor.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.MenuItem, dojo.widget.Widget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.MenuItem, {
|
||||
widgetType: "MenuItem",
|
||||
isContainer: true
|
||||
});
|
||||
|
||||
|
||||
/* DomMenuItem
|
||||
**************/
|
||||
dojo.widget.DomMenuItem = function(){
|
||||
dojo.widget.DomMenuItem.superclass.constructor.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.DomMenuItem, dojo.widget.DomWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.DomMenuItem, {
|
||||
widgetType: "MenuItem"
|
||||
});
|
||||
|
||||
dojo.requireAfterIf("html", "dojo.html");
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.MenuItem");
|
74
webapp/web/src/widget/MonthlyCalendar.js
Normal file
74
webapp/web/src/widget/MonthlyCalendar.js
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.MonthlyCalendar");
|
||||
dojo.provide("dojo.widget.MonthlyCalendar.util");
|
||||
dojo.require("dojo.widget.DomWidget");
|
||||
dojo.require("dojo.date");
|
||||
|
||||
dojo.widget.MonthlyCalendar= function(){
|
||||
dojo.widget.Widget.call(this);
|
||||
this.widgetType = "MonthlyCalendar";
|
||||
this.isContainer = false;
|
||||
// the following aliases prevent breaking people using 0.2.x
|
||||
this.months = dojo.date.months;
|
||||
this.weekdays = dojo.date.days;
|
||||
this.toRfcDate = dojo.widget.MonthlyCalendar.util.toRfcDate;
|
||||
this.fromRfcDate = dojo.widget.MonthlyCalendar.util.fromRfcDate;
|
||||
this.initFirstSaturday = dojo.widget.MonthlyCalendar.util.initFirstSaturday;
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.MonthlyCalendar, dojo.widget.Widget);
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:monthlycalendar");
|
||||
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.MonthlyCalendar");
|
||||
|
||||
dojo.widget.MonthlyCalendar.util= new function() {
|
||||
this.months = dojo.date.months;
|
||||
this.weekdays = dojo.date.days;
|
||||
|
||||
this.toRfcDate = function(jsDate) {
|
||||
if(!jsDate) {
|
||||
jsDate = this.today;
|
||||
}
|
||||
var year = jsDate.getFullYear();
|
||||
var month = jsDate.getMonth() + 1;
|
||||
if (month < 10) {
|
||||
month = "0" + month.toString();
|
||||
}
|
||||
var date = jsDate.getDate();
|
||||
if (date < 10) {
|
||||
date = "0" + date.toString();
|
||||
}
|
||||
// because this is a date picker and not a time picker, we treat time
|
||||
// as zero
|
||||
return year + "-" + month + "-" + date + "T00:00:00+00:00";
|
||||
}
|
||||
|
||||
this.fromRfcDate = function(rfcDate) {
|
||||
var tempDate = rfcDate.split("-");
|
||||
if(tempDate.length < 3) {
|
||||
return new Date();
|
||||
}
|
||||
// fullYear, month, date
|
||||
return new Date(parseInt(tempDate[0]), (parseInt(tempDate[1], 10) - 1), parseInt(tempDate[2].substr(0,2), 10));
|
||||
}
|
||||
|
||||
this.initFirstSaturday = function(month, year) {
|
||||
if(!month) {
|
||||
month = this.date.getMonth();
|
||||
}
|
||||
if(!year) {
|
||||
year = this.date.getFullYear();
|
||||
}
|
||||
var firstOfMonth = new Date(year, month, 1);
|
||||
return {year: year, month: month, date: 7 - firstOfMonth.getDay()};
|
||||
}
|
||||
}
|
312
webapp/web/src/widget/Parse.js
Normal file
312
webapp/web/src/widget/Parse.js
Normal file
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Parse");
|
||||
|
||||
dojo.require("dojo.widget.Manager");
|
||||
dojo.require("dojo.dom");
|
||||
|
||||
dojo.widget.Parse = function(fragment) {
|
||||
this.propertySetsList = [];
|
||||
this.fragment = fragment;
|
||||
|
||||
this.createComponents = function(frag, parentComp){
|
||||
var comps = [ ];
|
||||
var built = false;
|
||||
// if we have items to parse/create at this level, do it!
|
||||
try{
|
||||
if((frag)&&(frag["tagName"])&&(frag!=frag["nodeRef"])){
|
||||
var djTags = dojo.widget.tags;
|
||||
// we split so that you can declare multiple
|
||||
// non-destructive widgets from the same ctor node
|
||||
var tna = String(frag["tagName"]).split(";");
|
||||
for(var x=0; x<tna.length; x++){
|
||||
var ltn = (tna[x].replace(/^\s+|\s+$/g, "")).toLowerCase();
|
||||
if(djTags[ltn]){
|
||||
built = true;
|
||||
frag.tagName = ltn;
|
||||
var ret = djTags[ltn](frag, this, parentComp, frag["index"]);
|
||||
comps.push(ret);
|
||||
}else{
|
||||
if((dojo.lang.isString(ltn))&&(ltn.substr(0, 5)=="dojo:")){
|
||||
dojo.debug("no tag handler registed for type: ", ltn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
dojo.debug("dojo.widget.Parse: error:", e);
|
||||
// throw(e);
|
||||
// IE is such a bitch sometimes
|
||||
}
|
||||
// if there's a sub-frag, build widgets from that too
|
||||
if(!built){
|
||||
comps = comps.concat(this.createSubComponents(frag, parentComp));
|
||||
}
|
||||
return comps;
|
||||
}
|
||||
|
||||
/* createSubComponents recurses over a raw JavaScript object structure,
|
||||
and calls the corresponding handler for its normalized tagName if it exists
|
||||
*/
|
||||
this.createSubComponents = function(fragment, parentComp){
|
||||
var frag, comps = [];
|
||||
for(var item in fragment){
|
||||
frag = fragment[item];
|
||||
if ((frag)&&(typeof frag == "object")&&(frag!=fragment.nodeRef)&&(frag!=fragment["tagName"])){
|
||||
comps = comps.concat(this.createComponents(frag, parentComp));
|
||||
}
|
||||
}
|
||||
return comps;
|
||||
}
|
||||
|
||||
/* parsePropertySets checks the top level of a raw JavaScript object
|
||||
structure for any propertySets. It stores an array of references to
|
||||
propertySets that it finds.
|
||||
*/
|
||||
this.parsePropertySets = function(fragment) {
|
||||
return [];
|
||||
var propertySets = [];
|
||||
for(var item in fragment){
|
||||
if( (fragment[item]["tagName"] == "dojo:propertyset") ) {
|
||||
propertySets.push(fragment[item]);
|
||||
}
|
||||
}
|
||||
// FIXME: should we store these propertySets somewhere for later retrieval
|
||||
this.propertySetsList.push(propertySets);
|
||||
return propertySets;
|
||||
}
|
||||
|
||||
/* parseProperties checks a raw JavaScript object structure for
|
||||
properties, and returns an array of properties that it finds.
|
||||
*/
|
||||
this.parseProperties = function(fragment) {
|
||||
var properties = {};
|
||||
for(var item in fragment){
|
||||
// FIXME: need to check for undefined?
|
||||
// case: its a tagName or nodeRef
|
||||
if((fragment[item] == fragment["tagName"])||
|
||||
(fragment[item] == fragment.nodeRef)){
|
||||
// do nothing
|
||||
}else{
|
||||
if((fragment[item]["tagName"])&&
|
||||
(dojo.widget.tags[fragment[item].tagName.toLowerCase()])){
|
||||
// TODO: it isn't a property or property set, it's a fragment,
|
||||
// so do something else
|
||||
// FIXME: needs to be a better/stricter check
|
||||
// TODO: handle xlink:href for external property sets
|
||||
}else if((fragment[item][0])&&(fragment[item][0].value!="")&&(fragment[item][0].value!=null)){
|
||||
try{
|
||||
// FIXME: need to allow more than one provider
|
||||
if(item.toLowerCase() == "dataprovider") {
|
||||
var _this = this;
|
||||
this.getDataProvider(_this, fragment[item][0].value);
|
||||
properties.dataProvider = this.dataProvider;
|
||||
}
|
||||
properties[item] = fragment[item][0].value;
|
||||
var nestedProperties = this.parseProperties(fragment[item]);
|
||||
// FIXME: this kind of copying is expensive and inefficient!
|
||||
for(var property in nestedProperties){
|
||||
properties[property] = nestedProperties[property];
|
||||
}
|
||||
}catch(e){ dojo.debug(e); }
|
||||
}
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
/* getPropertySetById returns the propertySet that matches the provided id
|
||||
*/
|
||||
|
||||
this.getDataProvider = function(objRef, dataUrl) {
|
||||
// FIXME: this is currently sync. To make this async, we made need to move
|
||||
//this step into the widget ctor, so that it is loaded when it is needed
|
||||
// to populate the widget
|
||||
dojo.io.bind({
|
||||
url: dataUrl,
|
||||
load: function(type, evaldObj){
|
||||
if(type=="load"){
|
||||
objRef.dataProvider = evaldObj;
|
||||
}
|
||||
},
|
||||
mimetype: "text/javascript",
|
||||
sync: true
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
this.getPropertySetById = function(propertySetId){
|
||||
for(var x = 0; x < this.propertySetsList.length; x++){
|
||||
if(propertySetId == this.propertySetsList[x]["id"][0].value){
|
||||
return this.propertySetsList[x];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/* getPropertySetsByType returns the propertySet(s) that match(es) the
|
||||
* provided componentClass
|
||||
*/
|
||||
this.getPropertySetsByType = function(componentType){
|
||||
var propertySets = [];
|
||||
for(var x=0; x < this.propertySetsList.length; x++){
|
||||
var cpl = this.propertySetsList[x];
|
||||
var cpcc = cpl["componentClass"]||cpl["componentType"]||null;
|
||||
// FIXME: propertySetId is not in scope here
|
||||
if((cpcc)&&(propertySetId == cpcc[0].value)){
|
||||
propertySets.push(cpl);
|
||||
}
|
||||
}
|
||||
return propertySets;
|
||||
}
|
||||
|
||||
/* getPropertySets returns the propertySet for a given component fragment
|
||||
*/
|
||||
this.getPropertySets = function(fragment){
|
||||
var ppl = "dojo:propertyproviderlist";
|
||||
var propertySets = [];
|
||||
var tagname = fragment["tagName"];
|
||||
if(fragment[ppl]){
|
||||
var propertyProviderIds = fragment[ppl].value.split(" ");
|
||||
// FIXME: should the propertyProviderList attribute contain #
|
||||
// syntax for reference to ids or not?
|
||||
// FIXME: need a better test to see if this is local or external
|
||||
// FIXME: doesn't handle nested propertySets, or propertySets that
|
||||
// just contain information about css documents, etc.
|
||||
for(var propertySetId in propertyProviderIds){
|
||||
if((propertySetId.indexOf("..")==-1)&&(propertySetId.indexOf("://")==-1)){
|
||||
// get a reference to a propertySet within the current parsed structure
|
||||
var propertySet = this.getPropertySetById(propertySetId);
|
||||
if(propertySet != ""){
|
||||
propertySets.push(propertySet);
|
||||
}
|
||||
}else{
|
||||
// FIXME: add code to parse and return a propertySet from
|
||||
// another document
|
||||
// alex: is this even necessaray? Do we care? If so, why?
|
||||
}
|
||||
}
|
||||
}
|
||||
// we put the typed ones first so that the parsed ones override when
|
||||
// iteration happens.
|
||||
return (this.getPropertySetsByType(tagname)).concat(propertySets);
|
||||
}
|
||||
|
||||
/*
|
||||
nodeRef is the node to be replaced... in the future, we might want to add
|
||||
an alternative way to specify an insertion point
|
||||
|
||||
componentName is the expected dojo widget name, i.e. Button of ContextMenu
|
||||
|
||||
properties is an object of name value pairs
|
||||
*/
|
||||
this.createComponentFromScript = function(nodeRef, componentName, properties){
|
||||
var ltn = "dojo:" + componentName.toLowerCase();
|
||||
if(dojo.widget.tags[ltn]){
|
||||
properties.fastMixIn = true;
|
||||
return [dojo.widget.tags[ltn](properties, this, null, null, properties)];
|
||||
}else{
|
||||
if(ltn.substr(0, 5)=="dojo:"){
|
||||
dojo.debug("no tag handler registed for type: ", ltn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dojo.widget._parser_collection = {"dojo": new dojo.widget.Parse() };
|
||||
dojo.widget.getParser = function(name){
|
||||
if(!name){ name = "dojo"; }
|
||||
if(!this._parser_collection[name]){
|
||||
this._parser_collection[name] = new dojo.widget.Parse();
|
||||
}
|
||||
return this._parser_collection[name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates widget.
|
||||
*
|
||||
* @param name The name of the widget to create
|
||||
* @param props Key-Value pairs of properties of the widget
|
||||
* @param refNode If the last argument is specified this node is used as
|
||||
* a reference for inserting this node into a DOM tree else
|
||||
* it beomces the domNode
|
||||
* @param position The position to insert this widget's node relative to the
|
||||
* refNode argument
|
||||
* @return The new Widget object
|
||||
*/
|
||||
|
||||
dojo.widget.createWidget = function(name, props, refNode, position){
|
||||
var lowerCaseName = name.toLowerCase();
|
||||
var namespacedName = "dojo:" + lowerCaseName;
|
||||
var isNode = ( dojo.byId(name) && (!dojo.widget.tags[namespacedName]) );
|
||||
|
||||
// if we got a node or an unambiguious ID, build a widget out of it
|
||||
if( (arguments.length==1) && ((typeof name != "string")||(isNode)) ){
|
||||
// we got a DOM node
|
||||
var xp = new dojo.xml.Parse();
|
||||
// FIXME: we should try to find the parent!
|
||||
var tn = (isNode) ? dojo.byId(name) : name;
|
||||
return dojo.widget.getParser().createComponents(xp.parseElement(tn, null, true))[0];
|
||||
}
|
||||
|
||||
function fromScript (placeKeeperNode, name, props) {
|
||||
props[namespacedName] = {
|
||||
dojotype: [{value: lowerCaseName}],
|
||||
nodeRef: placeKeeperNode,
|
||||
fastMixIn: true
|
||||
};
|
||||
return dojo.widget.getParser().createComponentFromScript(
|
||||
placeKeeperNode, name, props, true);
|
||||
}
|
||||
|
||||
if (typeof name != "string" && typeof props == "string") {
|
||||
dojo.deprecated("dojo.widget.createWidget",
|
||||
"argument order is now of the form " +
|
||||
"dojo.widget.createWidget(NAME, [PROPERTIES, [REFERENCENODE, [POSITION]]])", "0.4");
|
||||
return fromScript(name, props, refNode);
|
||||
}
|
||||
|
||||
props = props||{};
|
||||
var notRef = false;
|
||||
var tn = null;
|
||||
var h = dojo.render.html.capable;
|
||||
if(h){
|
||||
tn = document.createElement("span");
|
||||
}
|
||||
if(!refNode){
|
||||
notRef = true;
|
||||
refNode = tn;
|
||||
if(h){
|
||||
document.body.appendChild(refNode);
|
||||
}
|
||||
}else if(position){
|
||||
dojo.dom.insertAtPosition(tn, refNode, position);
|
||||
}else{ // otherwise don't replace, but build in-place
|
||||
tn = refNode;
|
||||
}
|
||||
var widgetArray = fromScript(tn, name, props);
|
||||
if (!widgetArray || !widgetArray[0] || typeof widgetArray[0].widgetType == "undefined") {
|
||||
throw new Error("createWidget: Creation of \"" + name + "\" widget failed.");
|
||||
}
|
||||
if (notRef) {
|
||||
if (widgetArray[0].domNode.parentNode) {
|
||||
widgetArray[0].domNode.parentNode.removeChild(widgetArray[0].domNode);
|
||||
}
|
||||
}
|
||||
return widgetArray[0]; // just return the widget
|
||||
}
|
||||
|
||||
dojo.widget.fromScript = function(name, props, refNode, position){
|
||||
dojo.deprecated("dojo.widget.fromScript", " use " +
|
||||
"dojo.widget.createWidget instead", "0.4");
|
||||
return dojo.widget.createWidget(name, props, refNode, position);
|
||||
}
|
192
webapp/web/src/widget/PopUpButton.js
Normal file
192
webapp/web/src/widget/PopUpButton.js
Normal file
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.PopUpButton");
|
||||
dojo.provide("dojo.widget.DomPopUpButton");
|
||||
dojo.provide("dojo.widget.HtmlPopUpButton");
|
||||
|
||||
dojo.deprecated("dojo.widget.PopUpButton, dojo.widget.DomPopUpButton, dojo.widget.HtmlPopUpButton", "use dojo.widget.DropDownButton", "0.4");
|
||||
|
||||
//dojo.require("dojo.widget.Button");
|
||||
//dojo.require("dojo.widget.HtmlButton");
|
||||
|
||||
dojo.require("dojo.widget.Menu");
|
||||
dojo.require("dojo.widget.MenuItem");
|
||||
|
||||
dojo.require("dojo.html");
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:PopUpButton");
|
||||
|
||||
/* PopUpButton
|
||||
**************/
|
||||
|
||||
dojo.widget.PopUpButton = function () {
|
||||
dojo.widget.PopUpButton.superclass.constructor.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.PopUpButton, dojo.widget.Widget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.PopUpButton, {
|
||||
widgetType: "PopUpButton",
|
||||
|
||||
label: ""
|
||||
});
|
||||
|
||||
|
||||
/* DomPopUpButton
|
||||
*****************/
|
||||
dojo.widget.DomPopUpButton = function(){
|
||||
dojo.widget.DomPopUpButton.superclass.constructor.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.DomPopUpButton, dojo.widget.DomWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.DomPopUpButton, {
|
||||
widgetType: dojo.widget.PopUpButton.prototype.widgetType
|
||||
});
|
||||
|
||||
|
||||
/* HtmlPopUpButton
|
||||
******************/
|
||||
|
||||
dojo.widget.HtmlPopUpButton = function () {
|
||||
dojo.widget.HtmlPopUpButton.superclass.constructor.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.HtmlPopUpButton, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.HtmlPopUpButton, {
|
||||
widgetType: dojo.widget.PopUpButton.prototype.widgetType,
|
||||
templateString: null,
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/PopUpButton.css"),
|
||||
|
||||
buildRendering: function (args, frag) {
|
||||
dojo.style.insertCssFile(this.templateCssPath, null, true);
|
||||
|
||||
this.domNode = document.createElement("a");
|
||||
this.domNode.className = "PopUpButton";
|
||||
dojo.event.connect(this.domNode, "onmousedown", this, "onMouseDown");
|
||||
|
||||
// draw the arrow
|
||||
var arrow = document.createElement("img");
|
||||
arrow.src = dojo.uri.dojoUri("src/widget/templates/images/dropdownButtonsArrow.gif");
|
||||
dojo.html.setClass(arrow, "downArrow");
|
||||
this.domNode.appendChild(arrow);
|
||||
|
||||
this.menu = dojo.widget.fromScript("Menu");
|
||||
dojo.html.addClass(this.menu.domNode, "PopUpButtonMenu");
|
||||
dojo.event.connect(this.menu, "onSelect", this, "onSelect");
|
||||
|
||||
if (frag["dojo:" + this.widgetType.toLowerCase()].nodeRef) {
|
||||
var node = frag["dojo:" + this.widgetType.toLowerCase()].nodeRef;
|
||||
var options = node.getElementsByTagName("option");
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
var properties = {
|
||||
title: dojo.dom.textContent(options[i]),
|
||||
value: options[i].value
|
||||
}
|
||||
this.addItem(dojo.widget.fromScript("MenuItem", properties));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
addItem: function (item) {
|
||||
// TODO: should be dojo.widget.MenuItem
|
||||
if (item instanceof dojo.widget.html.MenuItem) {
|
||||
this.menu.push(item);
|
||||
} else {
|
||||
// TODO: create one
|
||||
var menuItem = dojo.widget.fromScript("MenuItem", {title: item});
|
||||
this.menu.push(menuItem);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/* Enabled utility methods
|
||||
**************************/
|
||||
|
||||
_enabled: true,
|
||||
|
||||
isEnabled: function() { return this._enabled; },
|
||||
|
||||
setEnabled: function(enabled, force, preventEvent) {
|
||||
enabled = Boolean(enabled);
|
||||
if (force || this._enabled != enabled) {
|
||||
this._enabled = enabled;
|
||||
if (!preventEvent) {
|
||||
this._fireEvent(this._enabled ? "onEnable" : "onDisable");
|
||||
this._fireEvent("onChangeEnabled");
|
||||
}
|
||||
}
|
||||
|
||||
dojo.html[(this._enabled ? "add" : "remove")
|
||||
+ "Class"](this.domNode, "disabled");
|
||||
|
||||
return this._enabled;
|
||||
},
|
||||
|
||||
enable: function(force, preventEvent) {
|
||||
return this.setEnabled(true, force, preventEvent);
|
||||
},
|
||||
|
||||
disable: function(force, preventEvent) {
|
||||
return this.setEnabled(false, force, preventEvent);
|
||||
},
|
||||
|
||||
toggleEnabled: function(force, preventEvent) {
|
||||
return this.setEnabled(!this._enabled, force, preventEvent);
|
||||
},
|
||||
|
||||
|
||||
/* Select utility methods
|
||||
**************************/
|
||||
|
||||
onSelect: function (item, e) {
|
||||
this.domNode.firstChild.nodeValue = item.title;
|
||||
},
|
||||
|
||||
onMouseDown: function (e) {
|
||||
if (!this._menuVisible) {
|
||||
this._showMenu(e);
|
||||
dojo.lang.setTimeout(dojo.event.connect, 1, document, "onmousedown", this, "_hideMenu");
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
_fireEvent: function(evt) {
|
||||
if(typeof this[evt] == "function") {
|
||||
var args = [this];
|
||||
for(var i = 1; i < arguments.length; i++) {
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
this[evt].apply(this, args);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
_showMenu: function (e) {
|
||||
if (!this._enabled) { return; }
|
||||
this._menuVisible = true;
|
||||
with (dojo.html) {
|
||||
var y = getAbsoluteY(this.domNode) + getInnerHeight(this.domNode);
|
||||
var x = getAbsoluteX(this.domNode);
|
||||
}
|
||||
|
||||
document.body.appendChild(this.menu.domNode);
|
||||
with (this.menu.domNode.style) {
|
||||
top = y + "px";
|
||||
left = x + "px";
|
||||
}
|
||||
},
|
||||
|
||||
_hideMenu: function (e) {
|
||||
this.menu.domNode.parentNode.removeChild(this.menu.domNode);
|
||||
dojo.event.disconnect(document, "onmousedown", this, "_hideMenu");
|
||||
this._menuVisible = false;
|
||||
}
|
||||
|
||||
});
|
110
webapp/web/src/widget/ResizableTextarea.js
Normal file
110
webapp/web/src/widget/ResizableTextarea.js
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.ResizableTextarea");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.LayoutContainer");
|
||||
dojo.require("dojo.widget.ResizeHandle");
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:resizabletextarea");
|
||||
|
||||
dojo.widget.ResizableTextarea = function(){
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.ResizableTextarea, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.ResizableTextarea, {
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlResizableTextarea.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlResizableTextarea.css"),
|
||||
widgetType: "ResizableTextarea",
|
||||
tagName: "dojo:resizabletextarea",
|
||||
isContainer: false,
|
||||
textAreaNode: null,
|
||||
textAreaContainer: null,
|
||||
textAreaContainerNode: null,
|
||||
statusBar: null,
|
||||
statusBarContainerNode: null,
|
||||
statusLabelNode: null,
|
||||
statusLabel: null,
|
||||
rootLayoutNode: null,
|
||||
resizeHandleNode: null,
|
||||
resizeHandle: null,
|
||||
|
||||
fillInTemplate: function(args, frag){
|
||||
this.textAreaNode = this.getFragNodeRef(frag).cloneNode(true);
|
||||
|
||||
// FIXME: Safari apparently needs this!
|
||||
document.body.appendChild(this.domNode);
|
||||
|
||||
this.rootLayout = dojo.widget.createWidget(
|
||||
"LayoutContainer",
|
||||
{
|
||||
minHeight: 50,
|
||||
minWidth: 100
|
||||
},
|
||||
this.rootLayoutNode
|
||||
);
|
||||
|
||||
|
||||
this.textAreaContainer = dojo.widget.createWidget(
|
||||
"LayoutContainer",
|
||||
{ layoutAlign: "client" },
|
||||
this.textAreaContainerNode
|
||||
);
|
||||
this.rootLayout.addChild(this.textAreaContainer);
|
||||
|
||||
this.textAreaContainer.domNode.appendChild(this.textAreaNode);
|
||||
with(this.textAreaNode.style){
|
||||
width="100%";
|
||||
height="100%";
|
||||
}
|
||||
|
||||
this.statusBar = dojo.widget.createWidget(
|
||||
"LayoutContainer",
|
||||
{
|
||||
layoutAlign: "bottom",
|
||||
minHeight: 28
|
||||
},
|
||||
this.statusBarContainerNode
|
||||
);
|
||||
this.rootLayout.addChild(this.statusBar);
|
||||
|
||||
this.statusLabel = dojo.widget.createWidget(
|
||||
"LayoutContainer",
|
||||
{
|
||||
layoutAlign: "client",
|
||||
minWidth: 50
|
||||
},
|
||||
this.statusLabelNode
|
||||
);
|
||||
this.statusBar.addChild(this.statusLabel);
|
||||
|
||||
this.resizeHandle = dojo.widget.createWidget(
|
||||
"ResizeHandle",
|
||||
{ targetElmId: this.rootLayout.widgetId },
|
||||
this.resizeHandleNode
|
||||
);
|
||||
this.statusBar.addChild(this.resizeHandle);
|
||||
// dojo.debug(this.rootLayout.widgetId);
|
||||
|
||||
// dojo.event.connect(this.resizeHandle, "beginSizing", this, "hideContent");
|
||||
// dojo.event.connect(this.resizeHandle, "endSizing", this, "showContent");
|
||||
},
|
||||
|
||||
hideContent: function(){
|
||||
this.textAreaNode.style.display = "none";
|
||||
},
|
||||
|
||||
showContent: function(){
|
||||
this.textAreaNode.style.display = "";
|
||||
}
|
||||
});
|
112
webapp/web/src/widget/ResizeHandle.js
Normal file
112
webapp/web/src/widget/ResizeHandle.js
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.ResizeHandle");
|
||||
dojo.provide("dojo.widget.html.ResizeHandle");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.style");
|
||||
dojo.require("dojo.dom");
|
||||
dojo.require("dojo.event");
|
||||
|
||||
dojo.widget.html.ResizeHandle = function(){
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.ResizeHandle, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.ResizeHandle, {
|
||||
widgetType: "ResizeHandle",
|
||||
|
||||
isSizing: false,
|
||||
startPoint: null,
|
||||
startSize: null,
|
||||
minSize: null,
|
||||
|
||||
targetElmId: '',
|
||||
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlResizeHandle.css"),
|
||||
templateString: '<div class="dojoHtmlResizeHandle"><div></div></div>',
|
||||
|
||||
postCreate: function(){
|
||||
dojo.event.connect(this.domNode, "onmousedown", this, "beginSizing");
|
||||
},
|
||||
|
||||
beginSizing: function(e){
|
||||
if (this.isSizing){ return false; }
|
||||
|
||||
// get the target dom node to adjust. targetElmId can refer to either a widget or a simple node
|
||||
this.targetWidget = dojo.widget.byId(this.targetElmId);
|
||||
this.targetDomNode = this.targetWidget ? this.targetWidget.domNode : dojo.byId(this.targetElmId);
|
||||
if (!this.targetDomNode){ return; }
|
||||
|
||||
this.isSizing = true;
|
||||
this.startPoint = {'x':e.clientX, 'y':e.clientY};
|
||||
this.startSize = {'w':dojo.style.getOuterWidth(this.targetDomNode), 'h':dojo.style.getOuterHeight(this.targetDomNode)};
|
||||
|
||||
dojo.event.kwConnect({
|
||||
srcObj: document.body,
|
||||
srcFunc: "onmousemove",
|
||||
targetObj: this,
|
||||
targetFunc: "changeSizing",
|
||||
rate: 25
|
||||
});
|
||||
dojo.event.connect(document.body, "onmouseup", this, "endSizing");
|
||||
|
||||
e.preventDefault();
|
||||
},
|
||||
|
||||
changeSizing: function(e){
|
||||
// On IE, if you move the mouse above/to the left of the object being resized,
|
||||
// sometimes clientX/Y aren't set, apparently. Just ignore the event.
|
||||
try{
|
||||
if(!e.clientX || !e.clientY){ return; }
|
||||
}catch(e){
|
||||
// sometimes you get an exception accessing above fields...
|
||||
return;
|
||||
}
|
||||
var dx = this.startPoint.x - e.clientX;
|
||||
var dy = this.startPoint.y - e.clientY;
|
||||
|
||||
var newW = this.startSize.w - dx;
|
||||
var newH = this.startSize.h - dy;
|
||||
|
||||
// minimum size check
|
||||
if (this.minSize) {
|
||||
if (newW < this.minSize.w) {
|
||||
newW = dojo.style.getOuterWidth(this.targetDomNode);
|
||||
}
|
||||
if (newH < this.minSize.h) {
|
||||
newH = dojo.style.getOuterHeight(this.targetDomNode);
|
||||
}
|
||||
}
|
||||
|
||||
if(this.targetWidget){
|
||||
this.targetWidget.resizeTo(newW, newH);
|
||||
}else{
|
||||
dojo.style.setOuterWidth(this.targetDomNode, newW);
|
||||
dojo.style.setOuterHeight(this.targetDomNode, newH);
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
},
|
||||
|
||||
endSizing: function(e){
|
||||
dojo.event.disconnect(document.body, "onmousemove", this, "changeSizing");
|
||||
dojo.event.disconnect(document.body, "onmouseup", this, "endSizing");
|
||||
|
||||
this.isSizing = false;
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:ResizeHandle");
|
1451
webapp/web/src/widget/RichText.js
Normal file
1451
webapp/web/src/widget/RichText.js
Normal file
File diff suppressed because it is too large
Load diff
713
webapp/web/src/widget/Rounded.js
Normal file
713
webapp/web/src/widget/Rounded.js
Normal file
|
@ -0,0 +1,713 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Rounded");
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:rounded");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.html.ContentPane");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.style");
|
||||
|
||||
/*
|
||||
* The following script is derived (with permission) from curvyCorners,
|
||||
* written by Cameron Cooke (CLA on file) and was adapted to Dojo by Brian
|
||||
* Lucas (CLA on file)
|
||||
*/
|
||||
|
||||
dojo.widget.Rounded = function() {
|
||||
dojo.widget.html.ContentPane.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.Rounded, dojo.widget.html.ContentPane);
|
||||
|
||||
dojo.lang.extend(dojo.widget.Rounded, {
|
||||
isSafari: dojo.render.html.safari,
|
||||
widgetType: "Rounded",
|
||||
boxMargin: "50px", // margin outside rounded corner box
|
||||
radius: 14, // radius of corners
|
||||
domNode: "",
|
||||
corners: "TR,TL,BR,BL", // corner string to render
|
||||
antiAlias: true, // false to disable anti-aliasing
|
||||
|
||||
fillInTemplate: function(args, frag) {
|
||||
dojo.widget.Rounded.superclass.fillInTemplate.call(this, args, frag);
|
||||
|
||||
dojo.style.insertCssFile(this.templateCssPath);
|
||||
|
||||
// Magic to automatically calculate the box height/width if not supplied
|
||||
if (this.domNode.style.height<=0) {
|
||||
var minHeight = (this.radius*1)+this.domNode.clientHeight;
|
||||
this.domNode.style.height = minHeight+"px";
|
||||
}
|
||||
|
||||
if (this.domNode.style.width<=0) {
|
||||
var minWidth = (this.radius*1)+this.domNode.clientWidth;
|
||||
this.domNode.style.width = minWidth+"px";
|
||||
}
|
||||
|
||||
var cornersAvailable = ["TR", "TL", "BR", "BL"];
|
||||
var cornersPassed = this.corners.split(",");
|
||||
|
||||
this.settings = {
|
||||
antiAlias: this.antiAlias
|
||||
};
|
||||
|
||||
var setCorner = function(currentCorner) {
|
||||
var val = currentCorner.toLowerCase();
|
||||
if(dojo.lang.inArray(cornersPassed, currentCorner)) {
|
||||
this.settings[val] = { radius: this.radius, enabled: true };
|
||||
} else {
|
||||
this.settings[val] = { radius: 0 }
|
||||
}
|
||||
}
|
||||
dojo.lang.forEach(cornersAvailable, setCorner, this);
|
||||
|
||||
this.domNode.style.margin = this.boxMargin;
|
||||
this.curvyCorners(this.settings);
|
||||
this.applyCorners();
|
||||
},
|
||||
|
||||
// ------------- curvyCorners OBJECT
|
||||
|
||||
curvyCorners: function(settings){
|
||||
|
||||
// Setup Globals
|
||||
this.box = this.domNode;
|
||||
this.topContainer = null;
|
||||
this.bottomContainer = null;
|
||||
this.masterCorners = [];
|
||||
|
||||
// Get box formatting details
|
||||
var boxHeight = dojo.style.getStyle(this.box, "height");
|
||||
if(boxHeight=="") boxHeight="0px";
|
||||
var boxWidth = dojo.style.getStyle(this.box, "width");
|
||||
var borderWidth = dojo.style.getStyle(this.box, "borderTopWidth");
|
||||
if(borderWidth=="") borderWidth="0px";
|
||||
//alert(borderWidth);
|
||||
|
||||
var borderColour = dojo.style.getStyle(this.box, "borderTopColor");
|
||||
// Set to true if we have a border
|
||||
if(borderWidth>0) this.antiAlias=true;
|
||||
|
||||
var boxColour = dojo.style.getStyle(this.box, "backgroundColor");
|
||||
var backgroundImage = dojo.style.getStyle(this.box, "backgroundImage");
|
||||
var boxPosition = dojo.style.getStyle(this.box, "position");
|
||||
|
||||
// Set formatting propertes
|
||||
this.boxHeight = parseInt(((boxHeight != "" && boxHeight != "auto" && boxHeight.indexOf("%") == -1)? boxHeight.substring(0, boxHeight.indexOf("px")) : this.box.scrollHeight));
|
||||
this.boxWidth = parseInt(((boxWidth != "" && boxWidth != "auto" && boxWidth.indexOf("%") == -1)? boxWidth.substring(0, boxWidth.indexOf("px")) : this.box.scrollWidth));
|
||||
this.borderWidth = parseInt(((borderWidth != "" && borderWidth.indexOf("px") !== -1)? borderWidth.slice(0, borderWidth.indexOf("px")) : 0));
|
||||
|
||||
// DEBUG ME?
|
||||
|
||||
//dojo.debug(this.rgb2Hex(boxColour));
|
||||
var test = new dojo.graphics.color.Color(boxColour);
|
||||
//dojo.debug(test.toHex());
|
||||
|
||||
this.boxColour = ((boxColour != "" && boxColour != "transparent")? ((boxColour.substr(0, 3) == "rgb")? this.rgb2Hex(boxColour) : boxColour) : "#ffffff");
|
||||
this.borderColour = ((borderColour != "" && borderColour != "transparent" && this.borderWidth > 0)? ((borderColour.substr(0, 3) == "rgb")? this.rgb2Hex(borderColour) : borderColour) : this.boxColour);
|
||||
this.borderString = this.borderWidth + "px" + " solid " + this.borderColour;
|
||||
this.backgroundImage = ((backgroundImage != "none")? backgroundImage : "");
|
||||
|
||||
// Make box relative if not already absolute
|
||||
if(boxPosition != "absolute") this.box.style.position = "relative";
|
||||
|
||||
//This method creates the corners and
|
||||
//applies them to the div element.
|
||||
|
||||
this.applyCorners = function() {
|
||||
// Create top and bottom containers.
|
||||
// These will be used as a parent for the corners and bars.
|
||||
for(var t = 0; t < 2; t++) {
|
||||
switch(t) {
|
||||
// Top
|
||||
case 0:
|
||||
// Only build top bar if a top corner is to be draw
|
||||
if(this.settings.tl.enabled || this.settings.tr.enabled ) {
|
||||
var newMainContainer = document.createElement("DIV");
|
||||
|
||||
with(newMainContainer.style){
|
||||
width = "100%";
|
||||
fontSize = "1px";
|
||||
overflow = "hidden";
|
||||
position = "absolute";
|
||||
//backgroundColor = "#FFFFC4";
|
||||
paddingLeft = this.borderWidth + "px";
|
||||
paddingRight = this.borderWidth + "px";
|
||||
var topMaxRadius = Math.max(this.settings.tl ? this.settings.tl.radius : 0, this.settings.tr ? this.settings.tr.radius : 0);
|
||||
height = topMaxRadius + "px";
|
||||
top = 0 - topMaxRadius + "px";
|
||||
left = 0 - this.borderWidth + "px";
|
||||
}
|
||||
|
||||
this.topContainer = this.box.appendChild(newMainContainer);
|
||||
}
|
||||
break;
|
||||
|
||||
// Bottom
|
||||
case 1:
|
||||
// Only build bottom bar if a top corner is to be draw
|
||||
if(this.settings.bl.enabled || this.settings.br.enabled) {
|
||||
var newMainContainer = document.createElement("DIV");
|
||||
with(newMainContainer.style){
|
||||
width = "100%";
|
||||
fontSize = "1px";
|
||||
overflow = "hidden";
|
||||
position = "absolute";
|
||||
//backgroundColor = "#FFFFC4";
|
||||
paddingLeft = this.borderWidth + "px";
|
||||
paddingRight = this.borderWidth + "px";
|
||||
var botMaxRadius = Math.max(this.settings.bl ? this.settings.bl.radius : 0, this.settings.br ? this.settings.br.radius : 0);
|
||||
height = botMaxRadius + "px";
|
||||
bottom = 0 - botMaxRadius + "px";
|
||||
left = 0 - this.borderWidth + "px";
|
||||
}
|
||||
this.bottomContainer = this.box.appendChild(newMainContainer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Turn off current borders
|
||||
if(this.topContainer) this.box.style.borderTopWidth = "0px";
|
||||
if(this.bottomContainer) this.box.style.borderBottomWidth = "0px";
|
||||
|
||||
// Create array of available corners
|
||||
var corners = ["tr", "tl", "br", "bl"];
|
||||
|
||||
//Loop for each corner
|
||||
|
||||
for(var i in corners) {
|
||||
// Get current corner type from array
|
||||
var cc = corners[i];
|
||||
|
||||
// Has the user requested the currentCorner be round?
|
||||
if(!this.settings[cc]) {
|
||||
// No
|
||||
if(((cc == "tr" || cc == "tl") && this.topContainer != null) || ((cc == "br" || cc == "bl") && this.bottomContainer != null)) {
|
||||
// We need to create a filler div to fill the space upto the next horzontal corner.
|
||||
var newCorner = document.createElement("DIV");
|
||||
|
||||
// Setup corners properties
|
||||
newCorner.style.position = "relative";
|
||||
newCorner.style.fontSize = "1px";
|
||||
newCorner.style.overflow = "hidden";
|
||||
|
||||
// Add background image?
|
||||
if(this.backgroundImage == "") {
|
||||
newCorner.style.backgroundColor = this.boxColour;
|
||||
} else {
|
||||
newCorner.style.backgroundImage = this.backgroundImage;
|
||||
}
|
||||
|
||||
switch(cc) {
|
||||
case "tl":
|
||||
with(newCorner.style){
|
||||
height = topMaxRadius - this.borderWidth + "px";
|
||||
marginRight = this.settings.tr.radius - (this.borderWidth*2) + "px";
|
||||
borderLeft = this.borderString;
|
||||
borderTop = this.borderString;
|
||||
left = -this.borderWidth + "px";
|
||||
}
|
||||
break;
|
||||
|
||||
case "tr":
|
||||
with(newCorner.style){
|
||||
height = topMaxRadius - this.borderWidth + "px";
|
||||
marginLeft = this.settings.tl.radius - (this.borderWidth*2) + "px";
|
||||
borderRight = this.borderString;
|
||||
borderTop = this.borderString;
|
||||
backgroundPosition = "-" + this.boxWidth + "px 0px";
|
||||
left = this.borderWidth + "px";
|
||||
}
|
||||
break;
|
||||
|
||||
case "bl":
|
||||
with(newCorner.style){
|
||||
height = botMaxRadius - this.borderWidth + "px";
|
||||
marginRight = this.settings.br.radius - (this.borderWidth*2) + "px";
|
||||
borderLeft = this.borderString;
|
||||
borderBottom = this.borderString;
|
||||
left = -this.borderWidth + "px";
|
||||
}
|
||||
break;
|
||||
|
||||
case "br":
|
||||
with(newCorner.style){
|
||||
height = botMaxRadius - this.borderWidth + "px";
|
||||
marginLeft = this.settings.bl.radius - (this.borderWidth*2) + "px";
|
||||
borderRight = this.borderString;
|
||||
borderBottom = this.borderString;
|
||||
left = this.borderWidth + "px"
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
PERFORMANCE NOTE:
|
||||
|
||||
If more than one corner is requested and a corner has been already
|
||||
created for the same radius then that corner will be used as a master and cloned.
|
||||
The pixel bars will then be repositioned to form the new corner type.
|
||||
All new corners start as a bottom right corner.
|
||||
*/
|
||||
if(this.masterCorners[this.settings[cc].radius]) {
|
||||
// Create clone of the master corner
|
||||
var newCorner = this.masterCorners[this.settings[cc].radius].cloneNode(true);
|
||||
} else {
|
||||
// Yes, we need to create a new corner
|
||||
var newCorner = document.createElement("DIV");
|
||||
with(newCorner.style){
|
||||
height = this.settings[cc].radius + "px";
|
||||
width = this.settings[cc].radius + "px";
|
||||
position = "absolute";
|
||||
fontSize = "1px";
|
||||
overflow = "hidden";
|
||||
}
|
||||
// THE FOLLOWING BLOCK OF CODE CREATES A ROUNDED CORNER
|
||||
// ---------------------------------------------------- TOP
|
||||
|
||||
// Get border radius
|
||||
var borderRadius = parseInt(this.settings[cc].radius - this.borderWidth);
|
||||
|
||||
// Cycle the x-axis
|
||||
for(var intx = 0, j = this.settings[cc].radius; intx < j; intx++) {
|
||||
// Calculate the value of y1 which identifies the pixels inside the border
|
||||
if((intx +1) >= borderRadius) {
|
||||
var y1 = -1;
|
||||
} else {
|
||||
var y1 = (Math.floor(Math.sqrt(Math.pow(borderRadius, 2) - Math.pow((intx+1), 2))) - 1);
|
||||
}
|
||||
|
||||
// Only calculate y2 and y3 if there is a border defined
|
||||
if(borderRadius != j) {
|
||||
if((intx) >= borderRadius) {
|
||||
var y2 = -1;
|
||||
} else {
|
||||
var y2 = Math.ceil(Math.sqrt(Math.pow(borderRadius,2) - Math.pow(intx, 2)));
|
||||
}
|
||||
|
||||
if((intx+1) >= j) {
|
||||
var y3 = -1;
|
||||
} else {
|
||||
var y3 = (Math.floor(Math.sqrt(Math.pow(j ,2) - Math.pow((intx+1), 2))) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate y4
|
||||
if((intx) >= j) {
|
||||
var y4 = -1;
|
||||
} else {
|
||||
var y4 = Math.ceil(Math.sqrt(Math.pow(j ,2) - Math.pow(intx, 2)));
|
||||
}
|
||||
|
||||
// Draw bar on inside of the border with foreground colour
|
||||
if(y1 > -1) this.drawPixel(intx, 0, this.boxColour, 100, (y1+1), newCorner, -1, this.settings[cc].radius);
|
||||
|
||||
// Only draw border/foreground antialiased pixels and border if there is a border defined
|
||||
if(borderRadius != j) {
|
||||
// Draw aa pixels?
|
||||
if(this.antiAlias) {
|
||||
// Cycle the y-axis
|
||||
for(var inty = (y1 + 1); inty < y2; inty++) {
|
||||
// For each of the pixels that need anti aliasing between the foreground and border colour draw single pixel divs
|
||||
if(this.backgroundImage != "") {
|
||||
var borderFract = (this.pixelFraction(intx, inty, borderRadius) * 100);
|
||||
|
||||
if (borderFract < 30) {
|
||||
this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, 0, this.settings[cc].radius);
|
||||
} else {
|
||||
this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, -1, this.settings[cc].radius);
|
||||
}
|
||||
} else {
|
||||
var pixelcolour = dojo.graphics.color.blend(this.boxColour, this.borderColour, this.pixelFraction(intx, inty, borderRadius));
|
||||
this.drawPixel(intx, inty, pixelcolour, 100, 1, newCorner, 0, this.settings[cc].radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw bar for the border
|
||||
if(y3 >= y2) {
|
||||
if (y1 == -1) {
|
||||
y1 = 0;
|
||||
}
|
||||
this.drawPixel(intx, y2, this.borderColour, 100, (y3 - y2 + 1), newCorner, 0, this.settings[cc].radius);
|
||||
}
|
||||
// Set the colour for the outside curve
|
||||
var outsideColour = this.borderColour;
|
||||
} else {
|
||||
// Set the coour for the outside curve
|
||||
var outsideColour = this.boxColour;
|
||||
var y3 = y1;
|
||||
}
|
||||
|
||||
// Draw aa pixels?
|
||||
if(this.antiAlias) {
|
||||
// Cycle the y-axis and draw the anti aliased pixels on the
|
||||
// outside of the curve
|
||||
for(var inty = (y3 + 1); inty < y4; inty++) {
|
||||
// For each of the pixels that need anti aliasing between
|
||||
//the foreground/border colour & background draw single pixel divs
|
||||
this.drawPixel(intx, inty, outsideColour, (this.pixelFraction(intx, inty , j) * 100), 1, newCorner, ((this.borderWidth > 0)? 0 : -1), this.settings[cc].radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// END OF CORNER CREATION
|
||||
// ---------------------------------------------------- END
|
||||
|
||||
// We now need to store the current corner in the masterConers array
|
||||
this.masterCorners[this.settings[cc].radius] = newCorner.cloneNode(true);
|
||||
}
|
||||
|
||||
//Now we have a new corner we need to reposition all the pixels unless
|
||||
//the current corner is the bottom right.
|
||||
if(cc != "br") {
|
||||
// Loop through all children (pixel bars)
|
||||
for(var t = 0, k = newCorner.childNodes.length; t < k; t++) {
|
||||
// Get current pixel bar
|
||||
var pixelBar = newCorner.childNodes[t];
|
||||
|
||||
// Get current top and left properties
|
||||
var pixelBarTop = parseInt(pixelBar.style.top.substring(0, pixelBar.style.top.indexOf("px")));
|
||||
var pixelBarLeft = parseInt(pixelBar.style.left.substring(0, pixelBar.style.left.indexOf("px")));
|
||||
var pixelBarHeight = parseInt(pixelBar.style.height.substring(0, pixelBar.style.height.indexOf("px")));
|
||||
|
||||
// Reposition pixels
|
||||
if(cc == "tl" || cc == "bl") {
|
||||
pixelBar.style.left = this.settings[cc].radius -pixelBarLeft -1 + "px"; // Left
|
||||
}
|
||||
if(cc == "tr" || cc == "tl") {
|
||||
pixelBar.style.top = this.settings[cc].radius -pixelBarHeight -pixelBarTop + "px"; // Top
|
||||
}
|
||||
var value;
|
||||
|
||||
switch(cc) {
|
||||
case "tr":
|
||||
value = (-1 *( Math.abs((this.boxWidth - this.settings[cc].radius + this.borderWidth) + pixelBarLeft) - (Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth))));
|
||||
pixelBar.style.backgroundPosition = value + "px";
|
||||
|
||||
break;
|
||||
|
||||
case "tl":
|
||||
value = (-1 *( Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) - (Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth))));
|
||||
pixelBar.style.backgroundPosition = value + "px";
|
||||
|
||||
break;
|
||||
|
||||
case "bl":
|
||||
value = (-1 *( Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) - (Math.abs((this.boxHeight + this.settings[cc].radius + pixelBarTop) -this.borderWidth))));
|
||||
pixelBar.style.backgroundPosition = value + "px";
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(newCorner) {
|
||||
// Position the container
|
||||
switch(cc) {
|
||||
case "tl":
|
||||
if(newCorner.style.position == "absolute") newCorner.style.top = "0px";
|
||||
if(newCorner.style.position == "absolute") newCorner.style.left = "0px";
|
||||
if(this.topContainer) this.topContainer.appendChild(newCorner);
|
||||
break;
|
||||
|
||||
case "tr":
|
||||
if(newCorner.style.position == "absolute") newCorner.style.top = "0px";
|
||||
if(newCorner.style.position == "absolute") newCorner.style.right = "0px";
|
||||
if(this.topContainer) this.topContainer.appendChild(newCorner);
|
||||
break;
|
||||
|
||||
case "bl":
|
||||
if(newCorner.style.position == "absolute") newCorner.style.bottom = "0px";
|
||||
if(newCorner.style.position == "absolute") newCorner.style.left = "0px";
|
||||
if(this.bottomContainer) this.bottomContainer.appendChild(newCorner);
|
||||
break;
|
||||
|
||||
case "br":
|
||||
if(newCorner.style.position == "absolute") newCorner.style.bottom = "0px";
|
||||
if(newCorner.style.position == "absolute") newCorner.style.right = "0px";
|
||||
if(this.bottomContainer) this.bottomContainer.appendChild(newCorner);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//The last thing to do is draw the rest of the filler DIVs.
|
||||
//We only need to create a filler DIVs when two corners have
|
||||
//diffrent radiuses in either the top or bottom container.
|
||||
|
||||
// Find out which corner has the biiger radius and get the difference amount
|
||||
var radiusDiff = [];
|
||||
radiusDiff["t"] = this.settings.tl.enabled && this.settings.tr.enabled ? Math.abs(this.settings.tl.radius - this.settings.tr.radius) : 0;
|
||||
radiusDiff["b"] = this.settings.bl.enabled && this.settings.br.enabled ? Math.abs(this.settings.bl.radius - this.settings.br.radius) : 0;
|
||||
|
||||
for(var z in radiusDiff) {
|
||||
if(radiusDiff[z]) {
|
||||
// Get the type of corner that is the smaller one
|
||||
var smallerCornerType = ((this.settings[z + "l"].radius < this.settings[z + "r"].radius)? z +"l" : z +"r");
|
||||
|
||||
// First we need to create a DIV for the space under the smaller corner
|
||||
var newFiller = document.createElement("DIV");
|
||||
with(newFiller.style) {
|
||||
height = radiusDiff[z] + "px";
|
||||
width = this.settings[smallerCornerType].radius+ "px"
|
||||
position = "absolute";
|
||||
fontSize = "1px";
|
||||
overflow = "hidden";
|
||||
backgroundColor = this.boxColour;
|
||||
}
|
||||
|
||||
// Position filler
|
||||
switch(smallerCornerType) {
|
||||
case "tl":
|
||||
with(newFiller.style) {
|
||||
bottom = "0px";
|
||||
left = "0px";
|
||||
borderLeft = this.borderString;
|
||||
}
|
||||
this.topContainer.appendChild(newFiller);
|
||||
break;
|
||||
|
||||
case "tr":
|
||||
with(newFiller.style) {
|
||||
bottom = "0px";
|
||||
right = "0px";
|
||||
borderRight = this.borderString;
|
||||
}
|
||||
this.topContainer.appendChild(newFiller);
|
||||
break;
|
||||
|
||||
case "bl":
|
||||
with(newFiller.style) {
|
||||
top = "0px";
|
||||
left = "0px";
|
||||
borderLeft = this.borderString;
|
||||
}
|
||||
this.bottomContainer.appendChild(newFiller);
|
||||
break;
|
||||
|
||||
case "br":
|
||||
with(newFiller.style) {
|
||||
top = "0px";
|
||||
right = "0px";
|
||||
borderRight = this.borderString;
|
||||
}
|
||||
this.bottomContainer.appendChild(newFiller);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the bar to fill the gap between each corner horizontally
|
||||
var newFillerBar = document.createElement("DIV");
|
||||
with(newFillerBar.style) {
|
||||
position = "relative";
|
||||
fontSize = "1px";
|
||||
overflow = "hidden";
|
||||
backgroundColor = this.boxColour;
|
||||
}
|
||||
|
||||
switch(z) {
|
||||
case "t":
|
||||
// Top Bar
|
||||
if(this.topContainer) {
|
||||
with(newFillerBar.style) {
|
||||
height = topMaxRadius - this.borderWidth + "px";
|
||||
marginLeft = this.settings.tl.radius - this.borderWidth + "px";
|
||||
marginRight = this.settings.tr.radius - this.borderWidth + "px";
|
||||
borderTop = this.borderString;
|
||||
}
|
||||
this.topContainer.appendChild(newFillerBar);
|
||||
}
|
||||
break;
|
||||
|
||||
case "b":
|
||||
if(this.bottomContainer) {
|
||||
// Bottom Bar
|
||||
with(newFillerBar.style) {
|
||||
height = botMaxRadius - this.borderWidth + "px";
|
||||
marginLeft = this.settings.bl.radius - this.borderWidth + "px";
|
||||
marginRight = this.settings.br.radius - this.borderWidth + "px";
|
||||
borderBottom = this.borderString;
|
||||
}
|
||||
this.bottomContainer.appendChild(newFillerBar);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This function draws the pixles
|
||||
this.drawPixel = function(intx, inty, colour, transAmount, height, newCorner, image, cornerRadius) {
|
||||
// Create pixel
|
||||
var pixel = document.createElement("DIV");
|
||||
|
||||
|
||||
// Section doesn't like with (pixel.style) { DEBUG?
|
||||
pixel.style.height = height + "px";
|
||||
pixel.style.width = "1px";
|
||||
pixel.style.position = "absolute";
|
||||
pixel.style.fontSize = "1px";
|
||||
pixel.style.overflow = "hidden";
|
||||
|
||||
// Dont apply background image to border pixels
|
||||
if(image == -1 && this.backgroundImage != "") {
|
||||
pixel.style.backgroundImage = this.backgroundImage;
|
||||
pixel.style.backgroundPosition = "-" + (this.boxWidth - (cornerRadius - intx) + this.borderWidth) + "px -" + ((this.boxHeight + cornerRadius + inty) -this.borderWidth) + "px";
|
||||
} else {
|
||||
pixel.style.backgroundColor = colour;
|
||||
}
|
||||
|
||||
// Set opacity if the transparency is anything other than 100
|
||||
if (transAmount != 100) {
|
||||
dojo.style.setOpacity(pixel, transAmount);
|
||||
}
|
||||
// Set the pixels position
|
||||
pixel.style.top = inty + "px";
|
||||
pixel.style.left = intx + "px";
|
||||
|
||||
newCorner.appendChild(pixel);
|
||||
}
|
||||
},
|
||||
|
||||
//For a pixel cut by the line determines the fraction of the pixel on the 'inside' of the
|
||||
//line. Returns a number between 0 and 1
|
||||
pixelFraction: function(x, y, r) {
|
||||
var pixelfraction = 0;
|
||||
|
||||
//determine the co-ordinates of the two points on the perimeter of the pixel that the
|
||||
//circle crosses
|
||||
|
||||
var xvalues = [];
|
||||
var yvalues = [];
|
||||
var point = 0;
|
||||
var whatsides = "";
|
||||
|
||||
// x + 0 = Left
|
||||
var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x,2)));
|
||||
|
||||
if ((intersect >= y) && (intersect < (y+1))) {
|
||||
whatsides = "Left";
|
||||
xvalues[point] = 0;
|
||||
yvalues[point] = intersect - y;
|
||||
point = point + 1;
|
||||
}
|
||||
|
||||
// y + 1 = Top
|
||||
var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y+1,2)));
|
||||
|
||||
if ((intersect >= x) && (intersect < (x+1))) {
|
||||
whatsides = whatsides + "Top";
|
||||
xvalues[point] = intersect - x;
|
||||
yvalues[point] = 1;
|
||||
point = point + 1;
|
||||
}
|
||||
// x + 1 = Right
|
||||
var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x+1,2)));
|
||||
|
||||
if ((intersect >= y) && (intersect < (y+1))) {
|
||||
whatsides = whatsides + "Right";
|
||||
xvalues[point] = 1;
|
||||
yvalues[point] = intersect - y;
|
||||
point = point + 1;
|
||||
}
|
||||
// y + 0 = Bottom
|
||||
var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y,2)));
|
||||
|
||||
if ((intersect >= x) && (intersect < (x+1))) {
|
||||
whatsides = whatsides + "Bottom";
|
||||
xvalues[point] = intersect - x;
|
||||
yvalues[point] = 0;
|
||||
}
|
||||
|
||||
//depending on which sides of the perimeter of the pixel the circle crosses calculate the
|
||||
//fraction of the pixel inside the circle
|
||||
|
||||
switch (whatsides) {
|
||||
case "LeftRight":
|
||||
pixelfraction = Math.min(yvalues[0],yvalues[1]) + ((Math.max(yvalues[0],yvalues[1]) - Math.min(yvalues[0],yvalues[1]))/2);
|
||||
break;
|
||||
|
||||
case "TopRight":
|
||||
pixelfraction = 1-(((1-xvalues[0])*(1-yvalues[1]))/2);
|
||||
break;
|
||||
|
||||
case "TopBottom":
|
||||
pixelfraction = Math.min(xvalues[0],xvalues[1]) + ((Math.max(xvalues[0],xvalues[1]) - Math.min(xvalues[0],xvalues[1]))/2);
|
||||
break;
|
||||
|
||||
case "LeftBottom":
|
||||
pixelfraction = (yvalues[0]*xvalues[1])/2;
|
||||
break;
|
||||
|
||||
default:
|
||||
pixelfraction = 1;
|
||||
}
|
||||
return pixelfraction;
|
||||
},
|
||||
|
||||
// This function converts CSS rgb(x, x, x) to hexadecimal
|
||||
rgb2Hex: function (rgbColour) {
|
||||
try{
|
||||
// Get array of RGB values
|
||||
var rgbArray = this.rgb2Array(rgbColour);
|
||||
|
||||
// Get RGB values
|
||||
var red = parseInt(rgbArray[0]);
|
||||
var green = parseInt(rgbArray[1]);
|
||||
var blue = parseInt(rgbArray[2]);
|
||||
|
||||
// Build hex colour code
|
||||
var hexColour = "#" + this.intToHex(red) + this.intToHex(green) + this.intToHex(blue);
|
||||
}
|
||||
catch(e){ alert("There was an error converting the RGB value to Hexadecimal in function rgb2Hex");
|
||||
}
|
||||
return hexColour;
|
||||
},
|
||||
|
||||
//Converts a number to hexadecimal format
|
||||
|
||||
intToHex: function (strNum) {
|
||||
var base = strNum / 16;
|
||||
var rem = strNum % 16;
|
||||
var base = base - (rem / 16);
|
||||
var baseS = this.makeHex(base);
|
||||
var remS = this.makeHex(rem);
|
||||
return baseS + '' + remS;
|
||||
},
|
||||
//gets the hex bits of a number
|
||||
|
||||
makeHex: function(x) {
|
||||
if((x >= 0) && (x <= 9)) {
|
||||
return x;
|
||||
} else {
|
||||
switch(x) {
|
||||
case 10: return "A";
|
||||
case 11: return "B";
|
||||
case 12: return "C";
|
||||
case 13: return "D";
|
||||
case 14: return "E";
|
||||
case 15: return "F";
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Returns an array of rbg values
|
||||
rgb2Array: function(rgbColour) {
|
||||
// Remove rgb()
|
||||
var rgbValues = rgbColour.substring(4, rgbColour.indexOf(")"));
|
||||
|
||||
// Split RGB into array
|
||||
var rgbArray = rgbValues.split(", ");
|
||||
return rgbArray;
|
||||
}
|
||||
}); // end function
|
76
webapp/web/src/widget/Select.js
Normal file
76
webapp/web/src/widget/Select.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Select");
|
||||
dojo.provide("dojo.widget.html.Select");
|
||||
|
||||
dojo.require("dojo.widget.html.ComboBox");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.html.stabile");
|
||||
|
||||
/*
|
||||
* The Select widget is an enhanced version of HTML's <select> tag.
|
||||
*
|
||||
* Similar features:
|
||||
* - There is a drop down list of possible values.
|
||||
* - You can only enter a value from the drop down list. (You can't enter an arbitrary value.)
|
||||
* - The value submitted with the form is the hidden value (ex: CA),
|
||||
not the displayed value a.k.a. label (ex: California)
|
||||
*
|
||||
* Enhancements over plain HTML version:
|
||||
* - If you type in some text then it will filter down the list of possible values in the drop down list.
|
||||
* - List can be specified either as a static list or via a javascript function (that can get the list from a server)
|
||||
*/
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.Select",
|
||||
dojo.widget.html.ComboBox,
|
||||
{
|
||||
widgetType: "Select",
|
||||
forceValidOption: true,
|
||||
|
||||
setValue: function(value) {
|
||||
this.comboBoxValue.value = value;
|
||||
dojo.widget.html.stabile.setState(this.widgetId, this.getState(), true);
|
||||
},
|
||||
|
||||
setLabel: function(value){
|
||||
// FIXME, not sure what to do here!
|
||||
this.comboBoxSelectionValue.value = value;
|
||||
if (this.textInputNode.value != value) { // prevent mucking up of selection
|
||||
this.textInputNode.value = value;
|
||||
}
|
||||
},
|
||||
|
||||
getLabel: function(){
|
||||
return this.comboBoxSelectionValue.value;
|
||||
},
|
||||
|
||||
getState: function() {
|
||||
return {
|
||||
value: this.getValue(),
|
||||
label: this.getLabel()
|
||||
};
|
||||
},
|
||||
|
||||
onKeyUp: function(evt){
|
||||
this.setLabel(this.textInputNode.value);
|
||||
},
|
||||
|
||||
setState: function(state) {
|
||||
this.setValue(state.value);
|
||||
this.setLabel(state.label);
|
||||
},
|
||||
|
||||
setAllValues: function(value1, value2){
|
||||
this.setValue(value2);
|
||||
this.setLabel(value1);
|
||||
}
|
||||
});
|
45
webapp/web/src/widget/Show.js
Normal file
45
webapp/web/src/widget/Show.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Show");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.lang.common");
|
||||
|
||||
dojo.widget.Show = function(){}
|
||||
dojo.lang.extend(dojo.widget.Show, {
|
||||
isContainer: true,
|
||||
_slide: -1,
|
||||
_slides: [],
|
||||
gotoSlide: function(/*int*/ slide){
|
||||
this._slide = slide;
|
||||
// summary: Placeholder
|
||||
},
|
||||
nextSlide: function(/*Event?*/ event){
|
||||
if(!this._slides[this._slide].nextAction(event)){
|
||||
if((this._slide + 1) != this._slides.length){
|
||||
this.gotoSlide(this._slide + 1);
|
||||
return true; // boolean
|
||||
}
|
||||
return false; // boolean
|
||||
}
|
||||
},
|
||||
previousSlide: function(/*Event?*/ event){
|
||||
if(!this._slides[this._slide].previousAction(event)){
|
||||
if((this._slide - 1) != -1){
|
||||
this.gotoSlide(this._slide - 1);
|
||||
return true; // boolean
|
||||
}
|
||||
return false; // boolean
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.Show");
|
26
webapp/web/src/widget/ShowAction.js
Normal file
26
webapp/web/src/widget/ShowAction.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.ShowAction");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.lang.common");
|
||||
|
||||
dojo.widget.ShowAction = function(){}
|
||||
dojo.lang.extend(dojo.widget.ShowAction, {
|
||||
on: "",
|
||||
action: "",
|
||||
duration: 0,
|
||||
from: "",
|
||||
to: "",
|
||||
auto: "false"
|
||||
});
|
||||
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.ShowAction");
|
43
webapp/web/src/widget/ShowSlide.js
Normal file
43
webapp/web/src/widget/ShowSlide.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.ShowSlide");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.lang.common");
|
||||
|
||||
dojo.widget.ShowSlide = function(){
|
||||
}
|
||||
dojo.lang.extend(dojo.widget.ShowSlide, {
|
||||
title: "",
|
||||
_action: -1,
|
||||
isContainer: true,
|
||||
_components: {},
|
||||
_actions: [],
|
||||
gotoAction: function(/*int*/ action){
|
||||
this._action = action;
|
||||
},
|
||||
nextAction: function(/*Event?*/ event){
|
||||
if((this._action + 1) != this._actions.length){
|
||||
++this._action;
|
||||
return true; // boolean
|
||||
}
|
||||
return false; // boolean
|
||||
},
|
||||
previousAction: function(/*Event?*/ event){
|
||||
if((this._action - 1) != -1){
|
||||
--this._action;
|
||||
return true; // boolean
|
||||
}
|
||||
return false; // boolean
|
||||
}
|
||||
});
|
||||
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.ShowSlide");
|
158
webapp/web/src/widget/SimpleDropdownButtons.js
Normal file
158
webapp/web/src/widget/SimpleDropdownButtons.js
Normal file
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
/* TODO:
|
||||
* - make the dropdowns "smart" so they can't get cutoff on bottom of page, sides of page, etc.
|
||||
* - unify menus with the MenuItem and Menu classes so we can add stuff to all menus at once
|
||||
* - allow buttons to be enabled/disabled at runtime
|
||||
* - this probably means creating all menus upfront and then triggering a disable action
|
||||
* for disabled buttons in the constructor loop. we'll need a disable and enable action anyway
|
||||
* - should each button with menu be a widget object of it's own?
|
||||
*/
|
||||
dojo.provide("dojo.widget.SimpleDropdownButtons");
|
||||
dojo.provide("dojo.widget.HtmlSimpleDropdownButtons");
|
||||
|
||||
dojo.deprecated("dojo.widget.SimpleDropdownButtons", "use dojo.widget.DropDownButton", "0.4");
|
||||
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.uri.Uri");
|
||||
dojo.require("dojo.dom");
|
||||
dojo.require("dojo.style");
|
||||
dojo.require("dojo.html");
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:simpledropdownbuttons");
|
||||
|
||||
dojo.widget.HtmlSimpleDropdownButtons = function() {
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
|
||||
this.widgetType = "SimpleDropdownButtons";
|
||||
this.templateCssPath = dojo.uri.dojoUri("src/widget/templates/HtmlSimpleDropdownButtons.css");
|
||||
|
||||
this.menuTriggerClass = "dojoSimpleDropdownButtons";
|
||||
this.menuClass = "dojoSimpleDropdownButtonsMenu";
|
||||
|
||||
// overwrite buildRendering so we don't clobber our list
|
||||
this.buildRendering = function(args, frag) {
|
||||
if(this.templateCssPath) {
|
||||
dojo.style.insertCssFile(this.templateCssPath, null, true);
|
||||
}
|
||||
this.domNode = frag["dojo:"+this.widgetType.toLowerCase()]["nodeRef"];
|
||||
|
||||
var menu = this.domNode;
|
||||
if( !dojo.html.hasClass(menu, this.menuTriggerClass) ) {
|
||||
dojo.html.addClass(menu, this.menuTriggerClass);
|
||||
}
|
||||
var li = dojo.dom.getFirstChildElement(menu);
|
||||
var menuIDs = [];
|
||||
var arrowIDs = [];
|
||||
|
||||
while(li) {
|
||||
if(li.getElementsByTagName("ul").length > 0) {
|
||||
var a = dojo.dom.getFirstChildElement(li);
|
||||
var arrow = document.createElement("a");
|
||||
arrow.href = "javascript:;";
|
||||
arrow.innerHTML = " ";
|
||||
dojo.html.setClass(arrow, "downArrow");
|
||||
if(!arrow.id) {
|
||||
arrow.id = dojo.dom.getUniqueId();
|
||||
}
|
||||
arrowIDs.push(arrow.id);
|
||||
var submenu = dojo.dom.getNextSiblingElement(a);
|
||||
if(!submenu.id) {
|
||||
submenu.id = dojo.dom.getUniqueId();
|
||||
}
|
||||
menuIDs.push(submenu.id);
|
||||
|
||||
if( dojo.html.hasClass(a, "disabled") ) {
|
||||
dojo.html.addClass(arrow, "disabled");
|
||||
dojo.html.disableSelection(li);
|
||||
arrow.onfocus = function(){ this.blur(); }
|
||||
} else {
|
||||
dojo.html.addClass(submenu, this.menuClass);
|
||||
document.body.appendChild(submenu);
|
||||
dojo.event.connect(arrow, "onmousedown", (function() {
|
||||
var ar = arrow;
|
||||
return function(e) {
|
||||
dojo.html.addClass(ar, "pressed");
|
||||
}
|
||||
})());
|
||||
dojo.event.connect(arrow, "onclick", (function() {
|
||||
var aa = a;
|
||||
var ar = arrow;
|
||||
var sm = submenu;
|
||||
var setWidth = false;
|
||||
|
||||
return function(e) {
|
||||
hideAll(sm, ar);
|
||||
sm.style.left = (dojo.html.getScrollLeft()
|
||||
+ e.clientX - e.layerX + aa.offsetLeft) + "px";
|
||||
sm.style.top = (dojo.html.getScrollTop() + e.clientY
|
||||
- e.layerY + aa.offsetTop + aa.offsetHeight) + "px";
|
||||
sm.style.display = sm.style.display == "block" ? "none" : "block";
|
||||
if(sm.style.display == "none") {
|
||||
dojo.html.removeClass(ar, "pressed");
|
||||
e.target.blur()
|
||||
}
|
||||
if(!setWidth && sm.style.display == "block"
|
||||
&& sm.offsetWidth < aa.offsetWidth + ar.offsetWidth) {
|
||||
sm.style.width = aa.offsetWidth + ar.offsetWidth + "px";
|
||||
setWidth = true;
|
||||
}
|
||||
e.preventDefault();
|
||||
}
|
||||
})());
|
||||
}
|
||||
|
||||
dojo.event.connect(a, "onclick", function(e) {
|
||||
if(e && e.target && e.target.blur) {
|
||||
e.target.blur();
|
||||
}
|
||||
});
|
||||
|
||||
if(a.nextSibling) {
|
||||
li.insertBefore(arrow, a.nextSibling);
|
||||
} else {
|
||||
li.appendChild(arrow);
|
||||
}
|
||||
|
||||
}
|
||||
li = dojo.dom.getNextSiblingElement(li);
|
||||
}
|
||||
|
||||
function hideAll(excludeMenu, excludeArrow) {
|
||||
// hide menus
|
||||
for(var i = 0; i < menuIDs.length; i++) {
|
||||
var m = document.getElementById(menuIDs[i]);
|
||||
if(!excludeMenu || m != excludeMenu) {
|
||||
document.getElementById(menuIDs[i]).style.display = "none";
|
||||
}
|
||||
}
|
||||
// restore arrows to non-pressed state
|
||||
for(var i = 0; i < arrowIDs.length; i++) {
|
||||
var m = document.getElementById(arrowIDs[i]);
|
||||
if(!excludeArrow || m != excludeArrow) {
|
||||
dojo.html.removeClass(m, "pressed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dojo.event.connect(document.documentElement, "onmousedown", function(e) {
|
||||
if( dojo.html.hasClass(e.target, "downArrow") ) { return };
|
||||
for(var i = 0; i < menuIDs.length; i++) {
|
||||
if( dojo.dom.isDescendantOf(e.target, document.getElementById(menuIDs[i])) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
hideAll();
|
||||
});
|
||||
}
|
||||
}
|
||||
dojo.inherits(dojo.widget.HtmlSimpleDropdownButtons, dojo.widget.HtmlWidget);
|
132
webapp/web/src/widget/SlideShow.js
Normal file
132
webapp/web/src/widget/SlideShow.js
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.SlideShow");
|
||||
dojo.provide("dojo.widget.html.SlideShow");
|
||||
|
||||
dojo.require("dojo.event");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.lfx.*");
|
||||
dojo.require("dojo.style");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.SlideShow",
|
||||
dojo.widget.HtmlWidget,
|
||||
{
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlSlideShow.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlSlideShow.css"),
|
||||
|
||||
// over-ride some defaults
|
||||
isContainer: false,
|
||||
widgetType: "SlideShow",
|
||||
|
||||
// useful properties
|
||||
imgUrls: [], // the images we'll go through
|
||||
imgUrlBase: "",
|
||||
urlsIdx: 0, // where in the images we are
|
||||
delay: 4000, // give it 4 seconds
|
||||
transitionInterval: 2000, // 2 seconds
|
||||
imgWidth: 800, // img width
|
||||
imgHeight: 600, // img height
|
||||
background: "img2", // what's in the bg
|
||||
foreground: "img1", // what's in the fg
|
||||
stopped: false, // should I stay or should I go?
|
||||
fadeAnim: null, // references our animation
|
||||
|
||||
// our DOM nodes:
|
||||
imagesContainer: null,
|
||||
startStopButton: null,
|
||||
controlsContainer: null,
|
||||
img1: null,
|
||||
img2: null,
|
||||
|
||||
fillInTemplate: function(){
|
||||
dojo.style.setOpacity(this.img1, 0.9999);
|
||||
dojo.style.setOpacity(this.img2, 0.9999);
|
||||
with(this.imagesContainer.style){
|
||||
width = this.imgWidth+"px";
|
||||
height = this.imgHeight+"px";
|
||||
}
|
||||
with(this.img1.style){
|
||||
width = this.imgWidth+"px";
|
||||
height = this.imgHeight+"px";
|
||||
}
|
||||
with(this.img2.style){
|
||||
width = this.imgWidth+"px";
|
||||
height = this.imgHeight+"px";
|
||||
}
|
||||
if(this.imgUrls.length>1){
|
||||
this.img2.src = this.imgUrlBase+this.imgUrls[this.urlsIdx++];
|
||||
this.endTransition();
|
||||
}else{
|
||||
this.img1.src = this.imgUrlBase+this.imgUrls[this.urlsIdx++];
|
||||
}
|
||||
},
|
||||
|
||||
togglePaused: function(){
|
||||
if(this.stopped){
|
||||
this.stopped = false;
|
||||
this.backgroundImageLoaded();
|
||||
this.startStopButton.value= "pause";
|
||||
}else{
|
||||
this.stopped = true;
|
||||
this.startStopButton.value= "play";
|
||||
}
|
||||
},
|
||||
|
||||
backgroundImageLoaded: function(){
|
||||
// start fading out the foreground image
|
||||
if(this.stopped){ return; }
|
||||
|
||||
// actually start the fadeOut effect
|
||||
// NOTE: if we wanted to use other transition types, we'd set them up
|
||||
// here as well
|
||||
if(this.fadeAnim) {
|
||||
this.fadeAnim.stop();
|
||||
}
|
||||
this.fadeAnim = dojo.lfx.fadeOut(this[this.foreground],
|
||||
this.transitionInterval, null);
|
||||
dojo.event.connect(this.fadeAnim,"onEnd",this,"endTransition");
|
||||
this.fadeAnim.play();
|
||||
},
|
||||
|
||||
endTransition: function(){
|
||||
// move the foreground image to the background
|
||||
with(this[this.background].style){ zIndex = parseInt(zIndex)+1; }
|
||||
with(this[this.foreground].style){ zIndex = parseInt(zIndex)-1; }
|
||||
|
||||
// fg/bg book-keeping
|
||||
var tmp = this.foreground;
|
||||
this.foreground = this.background;
|
||||
this.background = tmp;
|
||||
|
||||
// keep on truckin
|
||||
this.loadNextImage();
|
||||
},
|
||||
|
||||
loadNextImage: function(){
|
||||
// load a new image in that container, and make sure it informs
|
||||
// us when it finishes loading
|
||||
dojo.event.kwConnect({
|
||||
srcObj: this[this.background],
|
||||
srcFunc: "onload",
|
||||
adviceObj: this,
|
||||
adviceFunc: "backgroundImageLoaded",
|
||||
once: true, // make sure we only ever hear about it once
|
||||
delay: this.delay
|
||||
});
|
||||
dojo.style.setOpacity(this[this.background], 1.0);
|
||||
this[this.background].src = this.imgUrlBase+this.imgUrls[this.urlsIdx++];
|
||||
if(this.urlsIdx>(this.imgUrls.length-1)){
|
||||
this.urlsIdx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
38
webapp/web/src/widget/SortableTable.js
Normal file
38
webapp/web/src/widget/SortableTable.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.SortableTable");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.SortableTable");
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:sortableTable");
|
||||
|
||||
// set up the general widget
|
||||
dojo.widget.SortableTable=function(){
|
||||
// summary
|
||||
// base class for the SortableTable
|
||||
dojo.widget.Widget.call(this);
|
||||
this.widgetType="SortableTable";
|
||||
this.isContainer=false;
|
||||
|
||||
// custom properties
|
||||
this.enableMultipleSelect=false;
|
||||
this.maximumNumberOfSelections=0; // 0 for unlimited, is the default.
|
||||
this.enableAlternateRows=false;
|
||||
this.minRows=0; // 0 means ignore.
|
||||
this.defaultDateFormat="%D";
|
||||
this.data=[];
|
||||
this.selected=[]; // always an array to handle multiple selections.
|
||||
this.columns=[];
|
||||
this.sortIndex=0; // index of the column sorted on, first is the default.
|
||||
this.sortDirection=0; // 0==asc, 1==desc
|
||||
this.valueField="Id"; // if a JSON structure is parsed and there is a field of this name,
|
||||
// a value attribute will be added to the row (tr value="{Id}")
|
||||
};
|
||||
dojo.inherits(dojo.widget.SortableTable, dojo.widget.Widget);
|
194
webapp/web/src/widget/Spinner.js
Normal file
194
webapp/web/src/widget/Spinner.js
Normal file
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Spinner");
|
||||
dojo.provide("dojo.widget.AdjustableIntegerTextbox");
|
||||
|
||||
dojo.require("dojo.widget.validate.IntegerTextbox");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.event.*");
|
||||
|
||||
/*
|
||||
****** AdjustableIntegerTextbox ******
|
||||
|
||||
A subclass of IntegerTextbox.
|
||||
*/
|
||||
dojo.widget.AdjustableIntegerTextbox = function(node) {
|
||||
// this property isn't a primitive and needs to be created on a per-item basis.
|
||||
this.flags = {};
|
||||
}
|
||||
dojo.inherits(dojo.widget.AdjustableIntegerTextbox, dojo.widget.validate.IntegerTextbox);
|
||||
dojo.lang.extend(dojo.widget.AdjustableIntegerTextbox, {
|
||||
// new subclass properties
|
||||
widgetType: "AdjustableIntegerTextbox",
|
||||
delta: "1",
|
||||
|
||||
adjustValue: function(direction, x){
|
||||
var val = this.getValue().replace(/[^\-+\d]/g, "");
|
||||
if(val.length == 0){ return; }
|
||||
|
||||
num = Math.min(Math.max((parseInt(val)+(parseInt(this.delta) * direction)), this.flags.min), this.flags.max);
|
||||
val = (new Number(num)).toString();
|
||||
|
||||
if(num >= 0){
|
||||
val = ((this.flags.signed == true)?'+':' ')+val; // make sure first char is a nondigit
|
||||
}
|
||||
|
||||
if(this.flags.separator.length > 0){
|
||||
for (var i=val.length-3; i > 1; i-=3){
|
||||
val = val.substr(0,i)+this.flags.separator+val.substr(i);
|
||||
}
|
||||
}
|
||||
|
||||
if(val.substr(0,1) == ' '){ val = val.substr(1); } // remove space
|
||||
|
||||
this.setValue(val);
|
||||
|
||||
return val.length;
|
||||
}
|
||||
});
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:AdjustableIntegerTextbox");
|
||||
|
||||
/*
|
||||
****** AdjustableRealNumberTextbox ******
|
||||
|
||||
A subclass of RealNumberTextbox.
|
||||
@attr places The exact number of decimal places. If omitted, it's unlimited and optional.
|
||||
@attr exponent Can be true or false. If omitted the exponential part is optional.
|
||||
@attr eSigned Is the exponent signed? Can be true or false, if omitted the sign is optional.
|
||||
*/
|
||||
dojo.widget.AdjustableRealNumberTextbox = function(node) {
|
||||
// this property isn't a primitive and needs to be created on a per-item basis.
|
||||
this.flags = {};
|
||||
}
|
||||
dojo.inherits(dojo.widget.AdjustableRealNumberTextbox, dojo.widget.validate.RealNumberTextbox);
|
||||
dojo.lang.extend(dojo.widget.AdjustableRealNumberTextbox, {
|
||||
// new subclass properties
|
||||
widgetType: "AdjustableRealNumberTextbox",
|
||||
delta: "1e1",
|
||||
|
||||
adjustValue: function(direction, x){
|
||||
var val = this.getValue().replace(/[^\-+\.eE\d]/g, "");
|
||||
if(!val.length){ return; }
|
||||
|
||||
var num = parseFloat(val);
|
||||
if(isNaN(num)){ return; }
|
||||
var delta = this.delta.split(/[eE]/);
|
||||
if(!delta.length){
|
||||
delta = [1, 1];
|
||||
}else{
|
||||
delta[0] = parseFloat(delta[0].replace(/[^\-+\.\d]/g, ""));
|
||||
if(isNaN(delta[0])){ delta[0] = 1; }
|
||||
if(delta.length > 1){
|
||||
delta[1] = parseInt(delta[1]);
|
||||
}
|
||||
if(isNaN(delta[1])){ delta[1] = 1; }
|
||||
}
|
||||
val = this.getValue().split(/[eE]/);
|
||||
if(!val.length){ return; }
|
||||
var numBase = parseFloat(val[0].replace(/[^\-+\.\d]/g, ""));
|
||||
if(val.length == 1){
|
||||
var numExp = 0;
|
||||
}else{
|
||||
var numExp = parseInt(val[1].replace(/[^\-+\d]/g, ""));
|
||||
}
|
||||
if(x <= val[0].length){
|
||||
x = 0;
|
||||
numBase += delta[0] * direction;
|
||||
}else{
|
||||
x = Number.MAX_VALUE;
|
||||
numExp += delta[1] * direction;
|
||||
if(this.flags.eSigned == false && numExp < 0){
|
||||
numExp = 0;
|
||||
}
|
||||
}
|
||||
num = Math.min(Math.max((numBase * Math.pow(10,numExp)), this.flags.min), this.flags.max);
|
||||
if((this.flags.exponent == true || (this.flags.exponent != false && x != 0)) && num.toExponential){
|
||||
if (isNaN(this.flags.places) || this.flags.places == Infinity){
|
||||
val = num.toExponential();
|
||||
}else{
|
||||
val = num.toExponential(this.flags.places);
|
||||
}
|
||||
}else if(num.toFixed && num.toPrecision){
|
||||
if(isNaN(this.flags.places)){
|
||||
val = num.toPrecision((1/3).toString().length-1);
|
||||
}else{
|
||||
val = num.toFixed(this.flags.places);
|
||||
}
|
||||
}else{
|
||||
val = num.toString();
|
||||
}
|
||||
|
||||
if(num >= 0){
|
||||
if(this.flags.signed == true){
|
||||
val = '+' + val;
|
||||
}
|
||||
}
|
||||
val = val.split(/[eE]/);
|
||||
if(this.flags.separator.length > 0){
|
||||
if(num >= 0 && val[0].substr(0,1) != '+'){
|
||||
val[0] = ' ' + val[0]; // make sure first char is nondigit for easy algorithm
|
||||
}
|
||||
var i = val[0].lastIndexOf('.');
|
||||
if(i >= 0){
|
||||
i -= 3;
|
||||
}else{
|
||||
i = val[0].length-3;
|
||||
}
|
||||
for (; i > 1; i-=3){
|
||||
val[0] = val[0].substr(0,i)+this.flags.separator+val[0].substr(i);
|
||||
}
|
||||
if(val[0].substr(0,1) == ' '){ val[0] = val[0].substr(1); } // remove space
|
||||
}
|
||||
if(val.length > 1){
|
||||
if((this.flags.eSigned == true)&&(val[1].substr(0,1) != '+')){
|
||||
val[1] = '+' + val[1];
|
||||
}else if((!this.flags.eSigned)&&(val[1].substr(0,1) == '+')){
|
||||
val[1] = val[1].substr(1);
|
||||
}else if((!this.flags.eSigned)&&(val[1].substr(0,1) == '-')&&(num.toFixed && num.toPrecision)){
|
||||
if(isNaN(this.flags.places)){
|
||||
val[0] = num.toPrecision((1/3).toString().length-1);
|
||||
}else{
|
||||
val[0] = num.toFixed(this.flags.places).toString();
|
||||
}
|
||||
val[1] = "0";
|
||||
}
|
||||
val[0] += 'e' + val[1];
|
||||
}
|
||||
this.setValue(val[0]);
|
||||
if(x > val[0].length){ x = val[0].length; }
|
||||
return x;
|
||||
}
|
||||
});
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:AdjustableRealNumberTextbox");
|
||||
|
||||
dojo.widget.Spinner = function(){
|
||||
dojo.widget.Widget.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.Spinner, dojo.widget.Widget);
|
||||
|
||||
dojo.widget.Spinner.defaults = {
|
||||
widgetType: "Spinner",
|
||||
isContainer: false
|
||||
};
|
||||
|
||||
dojo.lang.extend(dojo.widget.Spinner, dojo.widget.Spinner.defaults);
|
||||
|
||||
dojo.widget.DomSpinner = function(){
|
||||
dojo.widget.Spinner.call(this);
|
||||
dojo.widget.DomWidget.call(this, true);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.DomSpinner, dojo.widget.DomWidget);
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:Spinner");
|
||||
|
||||
// render-specific includes
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.Spinner");
|
579
webapp/web/src/widget/SplitContainer.js
Normal file
579
webapp/web/src/widget/SplitContainer.js
Normal file
|
@ -0,0 +1,579 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.SplitContainer");
|
||||
dojo.provide("dojo.widget.SplitContainerPanel");
|
||||
dojo.provide("dojo.widget.html.SplitContainer");
|
||||
dojo.provide("dojo.widget.html.SplitContainerPanel");
|
||||
|
||||
//
|
||||
// TODO
|
||||
// make it prettier
|
||||
// active dragging upwards doesn't always shift other bars (direction calculation is wrong in this case)
|
||||
//
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.LayoutContainer");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.style");
|
||||
dojo.require("dojo.dom");
|
||||
dojo.require("dojo.io"); // workaround dojo bug. dojo.io.cookie requires dojo.io but it still doesn't get pulled in
|
||||
dojo.require("dojo.io.cookie");
|
||||
|
||||
dojo.widget.html.SplitContainer = function(){
|
||||
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
|
||||
this.sizers = [];
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.SplitContainer, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.SplitContainer, {
|
||||
widgetType: "SplitContainer",
|
||||
isContainer: true,
|
||||
|
||||
virtualSizer: null,
|
||||
isHorizontal: 0,
|
||||
paneBefore: null,
|
||||
paneAfter: null,
|
||||
isSizing: false,
|
||||
dragOffset: null,
|
||||
startPoint: null,
|
||||
lastPoint: null,
|
||||
sizingSplitter: null,
|
||||
isActiveResize: 0,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
isDraggingLeft: 0,
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlSplitContainer.css"),
|
||||
originPos: null,
|
||||
persist: true, // save splitter positions in a cookie
|
||||
|
||||
activeSizing: '',
|
||||
sizerWidth: 15,
|
||||
orientation: 'horizontal',
|
||||
|
||||
debugName: '',
|
||||
|
||||
fillInTemplate: function(){
|
||||
|
||||
dojo.style.insertCssFile(this.templateCssPath, null, true);
|
||||
dojo.html.addClass(this.domNode, "dojoSplitContainer");
|
||||
this.domNode.style.overflow='hidden'; // workaround firefox bug
|
||||
|
||||
this.paneWidth = dojo.style.getContentWidth(this.domNode);
|
||||
this.paneHeight = dojo.style.getContentHeight(this.domNode);
|
||||
|
||||
this.isHorizontal = (this.orientation == 'horizontal') ? 1 : 0;
|
||||
this.isActiveResize = (this.activeSizing == '1') ? 1 : 0;
|
||||
|
||||
//dojo.debug("fillInTemplate for "+this.debugName);
|
||||
},
|
||||
|
||||
onResized: function(e){
|
||||
this.paneWidth = dojo.style.getContentWidth(this.domNode);
|
||||
this.paneHeight = dojo.style.getContentHeight(this.domNode);
|
||||
this.layoutPanels();
|
||||
},
|
||||
|
||||
postCreate: function(args, fragment, parentComp){
|
||||
|
||||
// dojo.debug("post create for "+this.debugName);
|
||||
|
||||
// attach the children and create the draggers
|
||||
for(var i=0; i<this.children.length; i++){
|
||||
with(this.children[i].domNode.style){
|
||||
position = "absolute";
|
||||
}
|
||||
dojo.html.addClass(this.children[i].domNode,
|
||||
"dojoSplitPane");
|
||||
|
||||
if(i == this.children.length-1){
|
||||
break;
|
||||
}
|
||||
|
||||
this._addSizer();
|
||||
}
|
||||
|
||||
// create the fake dragger
|
||||
this.virtualSizer = document.createElement('div');
|
||||
this.virtualSizer.style.position = 'absolute';
|
||||
this.virtualSizer.style.display = 'none';
|
||||
//this.virtualSizer.style.backgroundColor = 'lime';
|
||||
this.virtualSizer.style.zIndex = 10;
|
||||
this.virtualSizer.className = this.isHorizontal ? 'dojoSplitContainerVirtualSizerH' : 'dojoSplitContainerVirtualSizerV';
|
||||
this.domNode.appendChild(this.virtualSizer);
|
||||
|
||||
dojo.html.disableSelection(this.virtualSizer);
|
||||
|
||||
if(this.persist){
|
||||
this.restoreState();
|
||||
}
|
||||
|
||||
// size the panels once the browser has caught up
|
||||
this.resizeSoon();
|
||||
},
|
||||
|
||||
_injectChild: function(child) {
|
||||
with(child.domNode.style){
|
||||
position = "absolute";
|
||||
}
|
||||
dojo.html.addClass(child.domNode,
|
||||
"dojoSplitPane");
|
||||
},
|
||||
|
||||
_addSizer: function() {
|
||||
var i = this.sizers.length;
|
||||
|
||||
this.sizers[i] = document.createElement('div');
|
||||
this.sizers[i].style.position = 'absolute';
|
||||
this.sizers[i].className = this.isHorizontal ? 'dojoSplitContainerSizerH' : 'dojoSplitContainerSizerV';
|
||||
|
||||
var self = this;
|
||||
var handler = (function(){ var sizer_i = i; return function(e){ self.beginSizing(e, sizer_i); } })();
|
||||
dojo.event.connect(this.sizers[i], "onmousedown", handler);
|
||||
|
||||
this.domNode.appendChild(this.sizers[i]);
|
||||
dojo.html.disableSelection(this.sizers[i]);
|
||||
},
|
||||
|
||||
removeChild: function(widget){
|
||||
// Remove sizer, but only if widget is really our child and
|
||||
// we have at least one sizer to throw away
|
||||
if (this.sizers.length > 0) {
|
||||
for(var x=0; x<this.children.length; x++){
|
||||
if(this.children[x] === widget){
|
||||
var i = this.sizers.length - 1;
|
||||
this.domNode.removeChild(this.sizers[i]);
|
||||
this.sizers.length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove widget and repaint
|
||||
dojo.widget.html.SplitContainer.superclass.removeChild.call(this, widget, arguments);
|
||||
this.onResized();
|
||||
},
|
||||
|
||||
addChild: function(widget, overrideContainerNode, pos, ref, insertIndex){
|
||||
dojo.widget.html.SplitContainer.superclass.addChild.call(this, widget, overrideContainerNode, pos, ref, insertIndex);
|
||||
this._injectChild(widget);
|
||||
|
||||
if (this.children.length > 1) {
|
||||
this._addSizer();
|
||||
}
|
||||
|
||||
this.layoutPanels();
|
||||
},
|
||||
|
||||
layoutPanels: function(){
|
||||
if (this.children.length == 0){ return; }
|
||||
|
||||
//
|
||||
// calculate space
|
||||
//
|
||||
|
||||
var space = this.isHorizontal ? this.paneWidth : this.paneHeight;
|
||||
|
||||
if (this.children.length > 1){
|
||||
|
||||
space -= this.sizerWidth * (this.children.length - 1);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// calculate total of SizeShare values
|
||||
//
|
||||
|
||||
var out_of = 0;
|
||||
|
||||
for(var i=0; i<this.children.length; i++){
|
||||
|
||||
out_of += this.children[i].sizeShare;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// work out actual pixels per sizeshare unit
|
||||
//
|
||||
|
||||
var pix_per_unit = space / out_of;
|
||||
|
||||
|
||||
//
|
||||
// set the SizeActual member of each pane
|
||||
//
|
||||
|
||||
var total_size = 0;
|
||||
|
||||
for(var i=0; i<this.children.length-1; i++){
|
||||
|
||||
var size = Math.round(pix_per_unit * this.children[i].sizeShare);
|
||||
this.children[i].sizeActual = size;
|
||||
total_size += size;
|
||||
}
|
||||
this.children[this.children.length-1].sizeActual = space - total_size;
|
||||
|
||||
//
|
||||
// make sure the sizes are ok
|
||||
//
|
||||
|
||||
this.checkSizes();
|
||||
|
||||
|
||||
//
|
||||
// now loop, positioning each pane and letting children resize themselves
|
||||
//
|
||||
|
||||
var pos = 0;
|
||||
var size = this.children[0].sizeActual;
|
||||
this.movePanel(this.children[0].domNode, pos, size);
|
||||
this.children[0].position = pos;
|
||||
this.children[0].checkSize();
|
||||
pos += size;
|
||||
|
||||
for(var i=1; i<this.children.length; i++){
|
||||
|
||||
// first we position the sizing handle before this pane
|
||||
this.movePanel(this.sizers[i-1], pos, this.sizerWidth);
|
||||
this.sizers[i-1].position = pos;
|
||||
pos += this.sizerWidth;
|
||||
|
||||
size = this.children[i].sizeActual;
|
||||
this.movePanel(this.children[i].domNode, pos, size);
|
||||
this.children[i].position = pos;
|
||||
this.children[i].checkSize();
|
||||
pos += size;
|
||||
}
|
||||
},
|
||||
|
||||
movePanel: function(panel, pos, size){
|
||||
if (this.isHorizontal){
|
||||
panel.style.left = pos + 'px';
|
||||
panel.style.top = 0;
|
||||
|
||||
dojo.style.setOuterWidth(panel, size);
|
||||
dojo.style.setOuterHeight(panel, this.paneHeight);
|
||||
}else{
|
||||
panel.style.left = 0;
|
||||
panel.style.top = pos + 'px';
|
||||
|
||||
dojo.style.setOuterWidth(panel, this.paneWidth);
|
||||
dojo.style.setOuterHeight(panel, size);
|
||||
}
|
||||
},
|
||||
|
||||
growPane: function(growth, pane){
|
||||
|
||||
if (growth > 0){
|
||||
if (pane.sizeActual > pane.sizeMin){
|
||||
if ((pane.sizeActual - pane.sizeMin) > growth){
|
||||
|
||||
// stick all the growth in this pane
|
||||
pane.sizeActual = pane.sizeActual - growth;
|
||||
growth = 0;
|
||||
}else{
|
||||
// put as much growth in here as we can
|
||||
growth -= pane.sizeActual - pane.sizeMin;
|
||||
pane.sizeActual = pane.sizeMin;
|
||||
}
|
||||
}
|
||||
}
|
||||
return growth;
|
||||
},
|
||||
|
||||
checkSizes: function(){
|
||||
|
||||
var total_min_size = 0;
|
||||
var total_size = 0;
|
||||
|
||||
for(var i=0; i<this.children.length; i++){
|
||||
|
||||
total_size += this.children[i].sizeActual;
|
||||
total_min_size += this.children[i].sizeMin;
|
||||
}
|
||||
|
||||
// only make adjustments if we have enough space for all the minimums
|
||||
|
||||
if (total_min_size <= total_size){
|
||||
|
||||
var growth = 0;
|
||||
|
||||
for(var i=0; i<this.children.length; i++){
|
||||
|
||||
if (this.children[i].sizeActual < this.children[i].sizeMin){
|
||||
|
||||
growth += this.children[i].sizeMin - this.children[i].sizeActual;
|
||||
this.children[i].sizeActual = this.children[i].sizeMin;
|
||||
}
|
||||
}
|
||||
|
||||
if (growth > 0){
|
||||
if (this.isDraggingLeft){
|
||||
for(var i=this.children.length-1; i>=0; i--){
|
||||
growth = this.growPane(growth, this.children[i]);
|
||||
}
|
||||
}else{
|
||||
for(var i=0; i<this.children.length; i++){
|
||||
growth = this.growPane(growth, this.children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
|
||||
for(var i=0; i<this.children.length; i++){
|
||||
this.children[i].sizeActual = Math.round(total_size * (this.children[i].sizeMin / total_min_size));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
beginSizing: function(e, i){
|
||||
var clientX = e.layerX;
|
||||
var clientY = e.layerY;
|
||||
var screenX = e.pageX;
|
||||
var screenY = e.pageY;
|
||||
|
||||
this.paneBefore = this.children[i];
|
||||
this.paneAfter = this.children[i+1];
|
||||
|
||||
this.isSizing = true;
|
||||
this.sizingSplitter = this.sizers[i];
|
||||
this.originPos = dojo.style.getAbsolutePosition(this.domNode, true);
|
||||
this.dragOffset = {'x':clientX, 'y':clientY};
|
||||
this.startPoint = {'x':screenX, 'y':screenY};
|
||||
this.lastPoint = {'x':screenX, 'y':screenY};
|
||||
|
||||
this.offsetX = screenX - clientX;
|
||||
this.offsetY = screenY - clientY;
|
||||
|
||||
if (!this.isActiveResize){
|
||||
this.showSizingLine();
|
||||
}
|
||||
|
||||
//
|
||||
// attach mouse events
|
||||
//
|
||||
|
||||
dojo.event.connect(document.documentElement, "onmousemove", this, "changeSizing");
|
||||
dojo.event.connect(document.documentElement, "onmouseup", this, "endSizing");
|
||||
},
|
||||
|
||||
changeSizing: function(e){
|
||||
var screenX = e.pageX;
|
||||
var screenY = e.pageY;
|
||||
|
||||
if (this.isActiveResize){
|
||||
this.lastPoint = {'x':screenX, 'y':screenY};
|
||||
this.movePoint();
|
||||
this.updateSize();
|
||||
}else{
|
||||
this.lastPoint = {'x':screenX, 'y':screenY};
|
||||
this.movePoint();
|
||||
this.moveSizingLine();
|
||||
}
|
||||
},
|
||||
|
||||
endSizing: function(e){
|
||||
|
||||
if (!this.isActiveResize){
|
||||
this.hideSizingLine();
|
||||
}
|
||||
|
||||
this.updateSize();
|
||||
|
||||
this.isSizing = false;
|
||||
|
||||
dojo.event.disconnect(document.documentElement, "onmousemove", this, "changeSizing");
|
||||
dojo.event.disconnect(document.documentElement, "onmouseup", this, "endSizing");
|
||||
|
||||
if(this.persist){
|
||||
this.saveState(this);
|
||||
}
|
||||
},
|
||||
|
||||
movePoint: function(){
|
||||
|
||||
// make sure FLastPoint is a legal point to drag to
|
||||
var p = this.screenToMainClient(this.lastPoint);
|
||||
|
||||
if (this.isHorizontal){
|
||||
|
||||
var a = p.x - this.dragOffset.x;
|
||||
a = this.legaliseSplitPoint(a);
|
||||
p.x = a + this.dragOffset.x;
|
||||
}else{
|
||||
var a = p.y - this.dragOffset.y;
|
||||
a = this.legaliseSplitPoint(a);
|
||||
p.y = a + this.dragOffset.y;
|
||||
}
|
||||
|
||||
this.lastPoint = this.mainClientToScreen(p);
|
||||
},
|
||||
|
||||
screenToClient: function(pt){
|
||||
|
||||
pt.x -= (this.offsetX + this.sizingSplitter.position);
|
||||
pt.y -= (this.offsetY + this.sizingSplitter.position);
|
||||
|
||||
return pt;
|
||||
},
|
||||
|
||||
clientToScreen: function(pt){
|
||||
|
||||
pt.x += (this.offsetX + this.sizingSplitter.position);
|
||||
pt.y += (this.offsetY + this.sizingSplitter.position);
|
||||
|
||||
return pt;
|
||||
},
|
||||
|
||||
screenToMainClient: function(pt){
|
||||
|
||||
pt.x -= this.offsetX;
|
||||
pt.y -= this.offsetY;
|
||||
|
||||
return pt;
|
||||
},
|
||||
|
||||
mainClientToScreen: function(pt){
|
||||
|
||||
pt.x += this.offsetX;
|
||||
pt.y += this.offsetY;
|
||||
|
||||
return pt;
|
||||
},
|
||||
|
||||
legaliseSplitPoint: function(a){
|
||||
|
||||
a += this.sizingSplitter.position;
|
||||
|
||||
this.isDraggingLeft = (a > 0) ? 1 : 0;
|
||||
|
||||
if (!this.isActiveResize){
|
||||
|
||||
if (a < this.paneBefore.position + this.paneBefore.sizeMin){
|
||||
|
||||
a = this.paneBefore.position + this.paneBefore.sizeMin;
|
||||
}
|
||||
|
||||
if (a > this.paneAfter.position + (this.paneAfter.sizeActual - (this.sizerWidth + this.paneAfter.sizeMin))){
|
||||
|
||||
a = this.paneAfter.position + (this.paneAfter.sizeActual - (this.sizerWidth + this.paneAfter.sizeMin));
|
||||
}
|
||||
}
|
||||
|
||||
a -= this.sizingSplitter.position;
|
||||
|
||||
this.checkSizes();
|
||||
|
||||
return a;
|
||||
},
|
||||
|
||||
updateSize: function(){
|
||||
|
||||
var p = this.clientToScreen(this.lastPoint);
|
||||
var p = this.screenToClient(this.lastPoint);
|
||||
|
||||
var pos = this.isHorizontal ? p.x - (this.dragOffset.x + this.originPos.x) : p.y - (this.dragOffset.y + this.originPos.y);
|
||||
|
||||
var start_region = this.paneBefore.position;
|
||||
var end_region = this.paneAfter.position + this.paneAfter.sizeActual;
|
||||
|
||||
this.paneBefore.sizeActual = pos - start_region;
|
||||
this.paneAfter.position = pos + this.sizerWidth;
|
||||
this.paneAfter.sizeActual = end_region - this.paneAfter.position;
|
||||
|
||||
for(var i=0; i<this.children.length; i++){
|
||||
|
||||
this.children[i].sizeShare = this.children[i].sizeActual;
|
||||
}
|
||||
|
||||
this.layoutPanels();
|
||||
},
|
||||
|
||||
showSizingLine: function(){
|
||||
|
||||
this.moveSizingLine();
|
||||
|
||||
if (this.isHorizontal){
|
||||
dojo.style.setOuterWidth(this.virtualSizer, this.sizerWidth);
|
||||
dojo.style.setOuterHeight(this.virtualSizer, this.paneHeight);
|
||||
}else{
|
||||
dojo.style.setOuterWidth(this.virtualSizer, this.paneWidth);
|
||||
dojo.style.setOuterHeight(this.virtualSizer, this.sizerWidth);
|
||||
}
|
||||
|
||||
this.virtualSizer.style.display = 'block';
|
||||
},
|
||||
|
||||
hideSizingLine: function(){
|
||||
|
||||
this.virtualSizer.style.display = 'none';
|
||||
},
|
||||
|
||||
moveSizingLine: function(){
|
||||
|
||||
var origin = {'x':0, 'y':0};
|
||||
|
||||
if (this.isHorizontal){
|
||||
origin.x += (this.lastPoint.x - this.startPoint.x) + this.sizingSplitter.position;
|
||||
}else{
|
||||
origin.y += (this.lastPoint.y - this.startPoint.y) + this.sizingSplitter.position;
|
||||
}
|
||||
|
||||
this.virtualSizer.style.left = origin.x + 'px';
|
||||
this.virtualSizer.style.top = origin.y + 'px';
|
||||
},
|
||||
|
||||
_getCookieName: function(i) {
|
||||
return this.widgetId + "_" + i;
|
||||
},
|
||||
|
||||
restoreState: function () {
|
||||
for(var i=0; i<this.children.length; i++) {
|
||||
var cookieName = this._getCookieName(i);
|
||||
var cookieValue = dojo.io.cookie.getCookie(cookieName);
|
||||
if (cookieValue != null) {
|
||||
var pos = parseInt(cookieValue);
|
||||
this.children[i].sizeShare=pos;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
saveState: function (){
|
||||
for(var i=0; i<this.children.length; i++) {
|
||||
var cookieName = this._getCookieName(i);
|
||||
dojo.io.cookie.setCookie(cookieName, this.children[i].sizeShare, null, null, null, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// These arguments can be specified for the children of a SplitContainer.
|
||||
// Since any widget can be specified as a SplitContainer child, mix them
|
||||
// into the base widget class. (This is a hack, but it's effective.)
|
||||
dojo.lang.extend(dojo.widget.Widget, {
|
||||
sizeMin: 10,
|
||||
sizeShare: 10
|
||||
});
|
||||
|
||||
// Deprecated class for split pane children.
|
||||
// Actually any widget can be the child of a split pane
|
||||
dojo.widget.html.SplitContainerPanel = function(){
|
||||
dojo.widget.html.LayoutContainer.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.SplitContainerPanel, dojo.widget.html.LayoutContainer);
|
||||
dojo.lang.extend(dojo.widget.html.SplitContainerPanel, {
|
||||
widgetType: "SplitContainerPanel"
|
||||
});
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:SplitContainer");
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:SplitContainerPanel");
|
141
webapp/web/src/widget/SvgButton.js
Normal file
141
webapp/web/src/widget/SvgButton.js
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
// FIXME: not yet functional
|
||||
|
||||
dojo.provide("dojo.widget.SvgButton");
|
||||
|
||||
dojo.require("dojo.widget.Button");
|
||||
|
||||
dojo.widget.SvgButton = function(){
|
||||
// FIXME: this is incomplete and doesn't work yet
|
||||
// if DOMButton turns into a mixin, we should subclass Button instead and
|
||||
// just mix in the DOMButton properties.
|
||||
|
||||
dojo.widget.DomButton.call(this);
|
||||
dojo.widget.SvgWidget.call(this);
|
||||
|
||||
// FIXME: freaking implement this already!
|
||||
this.onFoo = function(){ alert("bar"); }
|
||||
|
||||
this.label = "huzzah!";
|
||||
|
||||
this.setLabel = function(x, y, textSize, label, shape){
|
||||
//var labelNode = this.domNode.ownerDocument.createTextNode(this.label);
|
||||
//var textNode = this.domNode.ownerDocument.createElement("text");
|
||||
var coords = dojo.widget.SvgButton.prototype.coordinates(x, y, textSize, label, shape);
|
||||
var textString = "";
|
||||
switch(shape) {
|
||||
case "ellipse":
|
||||
textString = "<text x='"+ coords[6] + "' y='"+ coords[7] + "'>"+ label + "</text>";
|
||||
//textNode.setAttribute("x", coords[6]);
|
||||
//textNode.setAttribute("y", coords[7]);
|
||||
break;
|
||||
case "rectangle":
|
||||
//FIXME: implement
|
||||
textString = "";
|
||||
//textNode.setAttribute("x", coords[6]);
|
||||
//textNode.setAttribute("y", coords[7]);
|
||||
break;
|
||||
case "circle":
|
||||
//FIXME: implement
|
||||
textString = "";
|
||||
//textNode.setAttribute("x", coords[6]);
|
||||
//textNode.setAttribute("y", coords[7]);
|
||||
break;
|
||||
}
|
||||
//textNode.appendChild(labelNode);
|
||||
//this.domNode.appendChild(textNode);
|
||||
return textString;
|
||||
//alert(textNode.getComputedTextLength());
|
||||
}
|
||||
|
||||
this.fillInTemplate = function(x, y, textSize, label, shape){
|
||||
// the idea is to set the text to the appropriate place given its length
|
||||
// and the template shape
|
||||
|
||||
// FIXME: For now, assuming text sizes are integers in SVG units
|
||||
this.textSize = textSize || 12;
|
||||
this.label = label;
|
||||
// FIXEME: for now, I'm going to fake this... need to come up with a real way to
|
||||
// determine the actual width of the text, such as computedStyle
|
||||
var textWidth = this.label.length*this.textSize ;
|
||||
//this.setLabel();
|
||||
}
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.SvgButton, dojo.widget.DomButton);
|
||||
|
||||
// FIXME
|
||||
dojo.widget.SvgButton.prototype.shapeString = function(x, y, textSize, label, shape) {
|
||||
switch(shape) {
|
||||
case "ellipse":
|
||||
var coords = dojo.widget.SvgButton.prototype.coordinates(x, y, textSize, label, shape)
|
||||
return "<ellipse cx='"+ coords[4]+"' cy='"+ coords[5]+"' rx='"+ coords[2]+"' ry='"+ coords[3]+"'/>";
|
||||
break;
|
||||
case "rect":
|
||||
//FIXME: implement
|
||||
return "";
|
||||
//return "<rect x='110' y='45' width='70' height='30'/>";
|
||||
break;
|
||||
case "circle":
|
||||
//FIXME: implement
|
||||
return "";
|
||||
//return "<circle cx='210' cy='60' r='23'/>";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dojo.widget.SvgButton.prototype.coordinates = function(x, y, textSize, label, shape) {
|
||||
switch(shape) {
|
||||
case "ellipse":
|
||||
var buttonWidth = label.length*textSize;
|
||||
var buttonHeight = textSize*2.5
|
||||
var rx = buttonWidth/2;
|
||||
var ry = buttonHeight/2;
|
||||
var cx = rx + x;
|
||||
var cy = ry + y;
|
||||
var textX = cx - rx*textSize/25;
|
||||
var textY = cy*1.1;
|
||||
return [buttonWidth, buttonHeight, rx, ry, cx, cy, textX, textY];
|
||||
break;
|
||||
case "rectangle":
|
||||
//FIXME: implement
|
||||
return "";
|
||||
break;
|
||||
case "circle":
|
||||
//FIXME: implement
|
||||
return "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dojo.widget.SvgButton.prototype.labelString = function(x, y, textSize, label, shape){
|
||||
var textString = "";
|
||||
var coords = dojo.widget.SvgButton.prototype.coordinates(x, y, textSize, label, shape);
|
||||
switch(shape) {
|
||||
case "ellipse":
|
||||
textString = "<text x='"+ coords[6] + "' y='"+ coords[7] + "'>"+ label + "</text>";
|
||||
break;
|
||||
case "rectangle":
|
||||
//FIXME: implement
|
||||
textString = "";
|
||||
break;
|
||||
case "circle":
|
||||
//FIXME: implement
|
||||
textString = "";
|
||||
break;
|
||||
}
|
||||
return textString;
|
||||
}
|
||||
|
||||
dojo.widget.SvgButton.prototype.templateString = function(x, y, textSize, label, shape) {
|
||||
return "<g class='dojoButton' dojoAttachEvent='onClick; onMouseMove: onFoo;' dojoAttachPoint='labelNode'>"+ dojo.widgets.SVGButton.prototype.shapeString(x, y, textSize, label, shape) + dojo.widget.SVGButton.prototype.labelString(x, y, textSize, label, shape) + "</g>";
|
||||
}
|
92
webapp/web/src/widget/SvgWidget.js
Normal file
92
webapp/web/src/widget/SvgWidget.js
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.require("dojo.widget.DomWidget");
|
||||
dojo.provide("dojo.widget.SvgWidget");
|
||||
dojo.provide("dojo.widget.SVGWidget"); // back compat
|
||||
|
||||
dojo.require("dojo.dom");
|
||||
|
||||
// SVGWidget is a mixin ONLY
|
||||
dojo.widget.SvgWidget = function(args){
|
||||
// mix in the parent type
|
||||
// dojo.widget.DomWidget.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.SvgWidget, dojo.widget.DomWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.SvgWidget, {
|
||||
getContainerHeight: function(){
|
||||
// NOTE: container height must be returned as the INNER height
|
||||
dojo.unimplemented("dojo.widget.SvgWidget.getContainerHeight");
|
||||
},
|
||||
|
||||
getContainerWidth: function(){
|
||||
// return this.parent.domNode.offsetWidth;
|
||||
dojo.unimplemented("dojo.widget.SvgWidget.getContainerWidth");
|
||||
},
|
||||
|
||||
setNativeHeight: function(height){
|
||||
// var ch = this.getContainerHeight();
|
||||
dojo.unimplemented("dojo.widget.SVGWidget.setNativeHeight");
|
||||
},
|
||||
|
||||
createNodesFromText: function(txt, wrap){
|
||||
return dojo.dom.createNodesFromText(txt, wrap);
|
||||
}
|
||||
});
|
||||
|
||||
dojo.widget.SVGWidget = dojo.widget.SvgWidget;
|
||||
|
||||
try{
|
||||
(function(){
|
||||
var tf = function(){
|
||||
// FIXME: fill this in!!!
|
||||
var rw = new function(){
|
||||
dojo.widget.SvgWidget.call(this);
|
||||
this.buildRendering = function(){ return; }
|
||||
this.destroyRendering = function(){ return; }
|
||||
this.postInitialize = function(){ return; }
|
||||
this.cleanUp = function(){ return; }
|
||||
this.widgetType = "SVGRootWidget";
|
||||
this.domNode = document.documentElement;
|
||||
}
|
||||
var wm = dojo.widget.manager;
|
||||
wm.root = rw;
|
||||
wm.add(rw);
|
||||
|
||||
// extend the widgetManager with a getWidgetFromNode method
|
||||
wm.getWidgetFromNode = function(node){
|
||||
var filter = function(x){
|
||||
if(x.domNode == node){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
var widgets = [];
|
||||
while((node)&&(widgets.length < 1)){
|
||||
widgets = this.getWidgetsByFilter(filter);
|
||||
node = node.parentNode;
|
||||
}
|
||||
if(widgets.length > 0){
|
||||
return widgets[0];
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
wm.getWidgetFromEvent = function(domEvt){
|
||||
return this.getWidgetFromNode(domEvt.target);
|
||||
}
|
||||
|
||||
wm.getWidgetFromPrimitive = wm.getWidgetFromNode;
|
||||
}
|
||||
// make sure we get called when the time is right
|
||||
dojo.event.connect(dojo.hostenv, "loaded", tf);
|
||||
})();
|
||||
}catch(e){ alert(e); }
|
64
webapp/web/src/widget/SwtWidget.js
Normal file
64
webapp/web/src/widget/SwtWidget.js
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.SwtWidget");
|
||||
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.widget.Widget");
|
||||
dojo.require("dojo.uri.*");
|
||||
dojo.require("dojo.lang.func");
|
||||
dojo.require("dojo.lang.extras");
|
||||
|
||||
try{
|
||||
importPackage(Packages.org.eclipse.swt.widgets);
|
||||
|
||||
dojo.declare("dojo.widget.SwtWidget", dojo.widget.Widget, {
|
||||
initializer: function() {
|
||||
if((arguments.length>0)&&(typeof arguments[0] == "object")){
|
||||
this.create(arguments[0]);
|
||||
}
|
||||
},
|
||||
|
||||
display: null,
|
||||
shell: null,
|
||||
|
||||
show: function(){ },
|
||||
hide: function(){ },
|
||||
|
||||
addChild: function(){ },
|
||||
registerChild: function(){ },
|
||||
addWidgetAsDirectChild: function(){ },
|
||||
removeChild: function(){ },
|
||||
cleanUp: function(){ },
|
||||
destroyRendering: function(){ },
|
||||
postInitialize: function(){ },
|
||||
});
|
||||
|
||||
// initialize SWT runtime
|
||||
|
||||
dojo.widget.SwtWidget.prototype.display = new Display();
|
||||
dojo.widget.SwtWidget.prototype.shell = new Shell(dojo.widget.SwtWidget.prototype.display);
|
||||
|
||||
dojo.widget.manager.startShell = function(){
|
||||
var sh = dojo.widget.SwtWidget.prototype.shell;
|
||||
var d = dojo.widget.SwtWidget.prototype.display;
|
||||
sh.open();
|
||||
while(!sh.isDisposed()){
|
||||
dojo.widget.manager.doNext();
|
||||
if(!d.readAndDispatch()){
|
||||
d.sleep();
|
||||
}
|
||||
}
|
||||
d.dispose();
|
||||
};
|
||||
}catch(e){
|
||||
// seems we didn't have the SWT classes in the environment. Log it.
|
||||
dojo.debug("dojo.widget.SwtWidget not loaded. SWT classes not available");
|
||||
}
|
261
webapp/web/src/widget/TabContainer.js
Normal file
261
webapp/web/src/widget/TabContainer.js
Normal file
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.TabContainer");
|
||||
dojo.provide("dojo.widget.html.TabContainer");
|
||||
dojo.provide("dojo.widget.Tab");
|
||||
|
||||
dojo.require("dojo.lang.func");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.style");
|
||||
dojo.require("dojo.html.layout");
|
||||
|
||||
//////////////////////////////////////////
|
||||
// TabContainer -- a set of Tabs
|
||||
//////////////////////////////////////////
|
||||
dojo.widget.html.TabContainer = function() {
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.TabContainer, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.TabContainer, {
|
||||
widgetType: "TabContainer",
|
||||
isContainer: true,
|
||||
|
||||
// Constructor arguments
|
||||
labelPosition: "top",
|
||||
closeButton: "none",
|
||||
|
||||
useVisibility: false, // true-->use visibility:hidden instead of display:none
|
||||
|
||||
// if false, TabContainers size changes according to size of currently selected tab
|
||||
doLayout: true,
|
||||
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlTabContainer.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlTabContainer.css"),
|
||||
|
||||
selectedTab: "", // initially selected tab (widgetId)
|
||||
|
||||
fillInTemplate: function(args, frag) {
|
||||
// Copy style info from input node to output node
|
||||
var source = this.getFragNodeRef(frag);
|
||||
dojo.html.copyStyle(this.domNode, source);
|
||||
|
||||
dojo.widget.html.TabContainer.superclass.fillInTemplate.call(this, args, frag);
|
||||
},
|
||||
|
||||
postCreate: function(args, frag) {
|
||||
// Load all the tabs, creating a label for each one
|
||||
for(var i=0; i<this.children.length; i++){
|
||||
this._setupTab(this.children[i]);
|
||||
}
|
||||
|
||||
if (this.closeButton=="pane") {
|
||||
var div = document.createElement("div");
|
||||
dojo.html.addClass(div, "dojoTabPanePaneClose");
|
||||
var self = this;
|
||||
dojo.event.connect(div, "onclick", function(){ self._runOnCloseTab(self.selectedTabWidget); });
|
||||
dojo.event.connect(div, "onmouseover", function(){ dojo.html.addClass(div, "dojoTabPanePaneCloseHover"); });
|
||||
dojo.event.connect(div, "onmouseout", function(){ dojo.html.removeClass(div, "dojoTabPanePaneCloseHover"); });
|
||||
this.dojoTabLabels.appendChild(div);
|
||||
}
|
||||
|
||||
if(this.doLayout){
|
||||
dojo.html.addClass(this.dojoTabLabels, "dojoTabLabels-"+this.labelPosition);
|
||||
} else {
|
||||
dojo.html.addClass(this.dojoTabLabels, "dojoTabLabels-"+this.labelPosition+"-noLayout");
|
||||
}
|
||||
|
||||
this._doSizing();
|
||||
|
||||
// Display the selected tab
|
||||
if(this.selectedTabWidget){
|
||||
this.selectTab(this.selectedTabWidget, true);
|
||||
}
|
||||
},
|
||||
|
||||
addChild: function(child, overrideContainerNode, pos, ref, insertIndex){
|
||||
this._setupTab(child);
|
||||
dojo.widget.html.TabContainer.superclass.addChild.call(this,child, overrideContainerNode, pos, ref, insertIndex);
|
||||
|
||||
// in case the tab labels have overflowed from one line to two lines
|
||||
this._doSizing();
|
||||
},
|
||||
|
||||
_setupTab: function(tab){
|
||||
tab.domNode.style.display="none";
|
||||
|
||||
// Create label
|
||||
tab.div = document.createElement("div");
|
||||
dojo.widget.wai.setAttr(tab.div, "waiRole", "tab");
|
||||
dojo.html.addClass(tab.div, "dojoTabPaneTab");
|
||||
var span = document.createElement("span");
|
||||
span.innerHTML = tab.label;
|
||||
dojo.html.disableSelection(span);
|
||||
if (this.closeButton=="tab") {
|
||||
var img = document.createElement("div");
|
||||
dojo.html.addClass(img, "dojoTabPaneTabClose");
|
||||
var self = this;
|
||||
dojo.event.connect(img, "onclick", function(evt){ self._runOnCloseTab(tab); dojo.event.browser.stopEvent(evt); });
|
||||
dojo.event.connect(img, "onmouseover", function(){ dojo.html.addClass(img,"dojoTabPaneTabCloseHover"); });
|
||||
dojo.event.connect(img, "onmouseout", function(){ dojo.html.removeClass(img,"dojoTabPaneTabCloseHover"); });
|
||||
span.appendChild(img);
|
||||
}
|
||||
tab.div.appendChild(span);
|
||||
this.dojoTabLabels.appendChild(tab.div);
|
||||
|
||||
var self = this;
|
||||
dojo.event.connect(tab.div, "onclick", function(){ self.selectTab(tab); });
|
||||
|
||||
if(!this.selectedTabWidget || this.selectedTab==tab.widgetId || tab.selected){
|
||||
this.selectedTabWidget = tab;
|
||||
} else {
|
||||
this._hideTab(tab);
|
||||
}
|
||||
|
||||
dojo.html.addClass(tab.domNode, "dojoTabPane");
|
||||
with(tab.domNode.style){
|
||||
top = dojo.style.getPixelValue(this.containerNode, "padding-top", true);
|
||||
left = dojo.style.getPixelValue(this.containerNode, "padding-left", true);
|
||||
}
|
||||
},
|
||||
|
||||
// Configure the content pane to take up all the space except for where the tab labels are
|
||||
_doSizing: function(){
|
||||
// position the labels and the container node
|
||||
var labelAlign=this.labelPosition.replace(/-h/,"");
|
||||
var children = [
|
||||
{domNode: this.dojoTabLabels, layoutAlign: labelAlign},
|
||||
{domNode: this.containerNode, layoutAlign: "client"}
|
||||
];
|
||||
|
||||
|
||||
if (this.doLayout) {
|
||||
dojo.html.layout(this.domNode, children);
|
||||
}
|
||||
|
||||
// size the current tab
|
||||
// TODO: should have ptr to current tab rather than searching
|
||||
var cw=dojo.style.getContentWidth(this.containerNode);
|
||||
var ch=dojo.style.getContentHeight(this.containerNode);
|
||||
dojo.lang.forEach(this.children, function(child){
|
||||
//if (this.doLayout) {
|
||||
if(child.selected){
|
||||
child.resizeTo(cw, ch);
|
||||
}
|
||||
//} else {
|
||||
// child.onResized();
|
||||
//}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
removeChild: function(tab) {
|
||||
|
||||
// remove tab event handlers
|
||||
dojo.event.disconnect(tab.div, "onclick", function () { });
|
||||
if (this.closeButton=="tab") {
|
||||
var img = tab.div.lastChild.lastChild;
|
||||
if (img) {
|
||||
dojo.html.removeClass(img, "dojoTabPaneTabClose", function () { });
|
||||
dojo.event.disconnect(img, "onclick", function () { });
|
||||
dojo.event.disconnect(img, "onmouseover", function () { });
|
||||
dojo.event.disconnect(img, "onmouseout", function () { });
|
||||
}
|
||||
}
|
||||
|
||||
dojo.widget.html.TabContainer.superclass.removeChild.call(this, tab);
|
||||
|
||||
dojo.html.removeClass(tab.domNode, "dojoTabPane");
|
||||
this.dojoTabLabels.removeChild(tab.div);
|
||||
delete(tab.div);
|
||||
|
||||
if (this.selectedTabWidget === tab) {
|
||||
this.selectedTabWidget = undefined;
|
||||
if (this.children.length > 0) {
|
||||
this.selectTab(this.children[0], true);
|
||||
}
|
||||
}
|
||||
|
||||
// in case the tab labels have overflowed from one line to two lines
|
||||
this._doSizing();
|
||||
},
|
||||
|
||||
selectTab: function(tab, _noRefresh) {
|
||||
// Deselect old tab and select new one
|
||||
if (this.selectedTabWidget) {
|
||||
this._hideTab(this.selectedTabWidget);
|
||||
}
|
||||
this.selectedTabWidget = tab;
|
||||
this._showTab(tab, _noRefresh);
|
||||
},
|
||||
|
||||
_showTab: function(tab, _noRefresh) {
|
||||
dojo.html.addClass(tab.div, "current");
|
||||
tab.selected=true;
|
||||
if ( this.useVisibility && !dojo.render.html.ie ) {
|
||||
tab.domNode.style.visibility="visible";
|
||||
} else {
|
||||
// make sure we dont refresh onClose and on postCreate
|
||||
// speeds up things a bit when using refreshOnShow and fixes #646
|
||||
if(_noRefresh && tab.refreshOnShow){
|
||||
var tmp = tab.refreshOnShow;
|
||||
tab.refreshOnShow = false;
|
||||
tab.show();
|
||||
tab.refreshOnShow = tmp;
|
||||
}else{
|
||||
tab.show();
|
||||
}
|
||||
|
||||
tab.resizeTo(
|
||||
dojo.style.getContentWidth(this.containerNode),
|
||||
dojo.style.getContentHeight(this.containerNode)
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
_hideTab: function(tab) {
|
||||
dojo.html.removeClass(tab.div, "current");
|
||||
tab.selected=false;
|
||||
if( this.useVisibility ){
|
||||
tab.domNode.style.visibility="hidden";
|
||||
}else{
|
||||
tab.hide();
|
||||
}
|
||||
},
|
||||
|
||||
_runOnCloseTab: function(tab) {
|
||||
var onc = tab.extraArgs.onClose || tab.extraArgs.onclose;
|
||||
var fcn = dojo.lang.isFunction(onc) ? onc : window[onc];
|
||||
var remove = dojo.lang.isFunction(fcn) ? fcn(this,tab) : true;
|
||||
if(remove) {
|
||||
this.removeChild(tab);
|
||||
// makes sure we can clean up executeScripts in ContentPane onUnLoad
|
||||
tab.destroy();
|
||||
}
|
||||
},
|
||||
|
||||
onResized: function() {
|
||||
this._doSizing();
|
||||
}
|
||||
});
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:TabContainer");
|
||||
|
||||
// These arguments can be specified for the children of a TabContainer.
|
||||
// Since any widget can be specified as a TabContainer child, mix them
|
||||
// into the base widget class. (This is a hack, but it's effective.)
|
||||
dojo.lang.extend(dojo.widget.Widget, {
|
||||
label: "",
|
||||
selected: false // is this tab currently selected?
|
||||
});
|
32
webapp/web/src/widget/TaskBar.js
Normal file
32
webapp/web/src/widget/TaskBar.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.TaskBar");
|
||||
dojo.provide("dojo.widget.TaskBarItem");
|
||||
dojo.require("dojo.widget.Widget");
|
||||
|
||||
dojo.widget.TaskBar = function(){
|
||||
dojo.widget.Widget.call(this);
|
||||
|
||||
this.widgetType = "TaskBar";
|
||||
this.isContainer = true;
|
||||
}
|
||||
dojo.inherits(dojo.widget.TaskBar, dojo.widget.Widget);
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:taskbar");
|
||||
|
||||
dojo.widget.TaskBarItem = function(){
|
||||
dojo.widget.Widget.call(this);
|
||||
|
||||
this.widgetType = "TaskBarItem";
|
||||
}
|
||||
dojo.inherits(dojo.widget.TaskBarItem, dojo.widget.Widget);
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:taskbaritem");
|
||||
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.TaskBar");
|
82
webapp/web/src/widget/TimePicker.js
Normal file
82
webapp/web/src/widget/TimePicker.js
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.TimePicker");
|
||||
dojo.provide("dojo.widget.TimePicker.util");
|
||||
dojo.require("dojo.widget.DomWidget");
|
||||
dojo.require("dojo.date");
|
||||
|
||||
dojo.widget.TimePicker = function(){
|
||||
dojo.widget.Widget.call(this);
|
||||
this.widgetType = "TimePicker";
|
||||
this.isContainer = false;
|
||||
// the following aliases prevent breaking people using 0.2.x
|
||||
this.toRfcDateTime = dojo.widget.TimePicker.util.toRfcDateTime;
|
||||
this.fromRfcDateTime = dojo.widget.TimePicker.util.fromRfcDateTime;
|
||||
this.toAmPmHour = dojo.widget.TimePicker.util.toAmPmHour;
|
||||
this.fromAmPmHour = dojo.widget.TimePicker.util.fromAmPmHour;
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.TimePicker, dojo.widget.Widget);
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:timepicker");
|
||||
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.TimePicker");
|
||||
|
||||
dojo.widget.TimePicker.util = new function() {
|
||||
// utility functions
|
||||
this.toRfcDateTime = function(jsDate) {
|
||||
if(!jsDate) {
|
||||
jsDate = new Date();
|
||||
}
|
||||
return dojo.date.format(jsDate, "%Y-%m-%dT%H:%M:00%z");
|
||||
}
|
||||
|
||||
this.fromRfcDateTime = function(rfcDate, useDefaultMinutes, isAnyTime) {
|
||||
var tempDate = new Date();
|
||||
if(!rfcDate || rfcDate.indexOf("T")==-1) {
|
||||
if(useDefaultMinutes) {
|
||||
tempDate.setMinutes(Math.floor(tempDate.getMinutes()/5)*5);
|
||||
} else {
|
||||
tempDate.setMinutes(0);
|
||||
}
|
||||
} else {
|
||||
var tempTime = rfcDate.split("T")[1].split(":");
|
||||
// fullYear, month, date
|
||||
var tempDate = new Date();
|
||||
tempDate.setHours(tempTime[0]);
|
||||
tempDate.setMinutes(tempTime[1]);
|
||||
}
|
||||
return tempDate;
|
||||
}
|
||||
|
||||
this.toAmPmHour = function(hour) {
|
||||
var amPmHour = hour;
|
||||
var isAm = true;
|
||||
if (amPmHour == 0) {
|
||||
amPmHour = 12;
|
||||
} else if (amPmHour>12) {
|
||||
amPmHour = amPmHour - 12;
|
||||
isAm = false;
|
||||
} else if (amPmHour == 12) {
|
||||
isAm = false;
|
||||
}
|
||||
return [amPmHour, isAm];
|
||||
}
|
||||
|
||||
this.fromAmPmHour = function(amPmHour, isAm) {
|
||||
var hour = parseInt(amPmHour, 10);
|
||||
if(isAm && hour == 12) {
|
||||
hour = 0;
|
||||
} else if (!isAm && hour<12) {
|
||||
hour = hour + 12;
|
||||
}
|
||||
return hour;
|
||||
}
|
||||
}
|
12
webapp/web/src/widget/TitlePane.js
Normal file
12
webapp/web/src/widget/TitlePane.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.TitlePane");
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.TitlePane");
|
40
webapp/web/src/widget/Toggler.js
Normal file
40
webapp/web/src/widget/Toggler.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Toggler");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.event.*");
|
||||
|
||||
// clicking on this node shows/hides another widget
|
||||
|
||||
dojo.widget.Toggler = function(){
|
||||
dojo.widget.DomWidget.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.Toggler, dojo.widget.DomWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.Toggler, {
|
||||
widgetType: "Toggler",
|
||||
|
||||
// Associated widget
|
||||
targetId: '',
|
||||
|
||||
fillInTemplate: function() {
|
||||
dojo.event.connect(this.domNode, "onclick", this, "onClick");
|
||||
},
|
||||
|
||||
onClick: function() {
|
||||
var pane = dojo.widget.byId(this.targetId);
|
||||
if(!pane){ return; }
|
||||
pane.explodeSrc = this.domNode;
|
||||
pane.toggleShowing();
|
||||
}
|
||||
});
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:toggler");
|
935
webapp/web/src/widget/Toolbar.js
Normal file
935
webapp/web/src/widget/Toolbar.js
Normal file
|
@ -0,0 +1,935 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.ToolbarContainer");
|
||||
dojo.provide("dojo.widget.html.ToolbarContainer");
|
||||
dojo.provide("dojo.widget.Toolbar");
|
||||
dojo.provide("dojo.widget.html.Toolbar");
|
||||
dojo.provide("dojo.widget.ToolbarItem");
|
||||
dojo.provide("dojo.widget.html.ToolbarButtonGroup");
|
||||
dojo.provide("dojo.widget.html.ToolbarButton");
|
||||
dojo.provide("dojo.widget.html.ToolbarDialog");
|
||||
dojo.provide("dojo.widget.html.ToolbarMenu");
|
||||
dojo.provide("dojo.widget.html.ToolbarSeparator");
|
||||
dojo.provide("dojo.widget.html.ToolbarSpace");
|
||||
dojo.provide("dojo.widget.Icon");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.html");
|
||||
|
||||
/* ToolbarContainer
|
||||
*******************/
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:toolbarContainer");
|
||||
dojo.widget.html.ToolbarContainer = function() {
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.ToolbarContainer, dojo.widget.HtmlWidget);
|
||||
dojo.lang.extend(dojo.widget.html.ToolbarContainer, {
|
||||
widgetType: "ToolbarContainer",
|
||||
isContainer: true,
|
||||
|
||||
templateString: '<div class="toolbarContainer" dojoAttachPoint="containerNode"></div>',
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlToolbar.css"),
|
||||
|
||||
getItem: function(name) {
|
||||
if(name instanceof dojo.widget.ToolbarItem) { return name; }
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.html.Toolbar) {
|
||||
var item = child.getItem(name);
|
||||
if(item) { return item; }
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
getItems: function() {
|
||||
var items = [];
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.html.Toolbar) {
|
||||
items = items.concat(child.getItems());
|
||||
}
|
||||
}
|
||||
return items;
|
||||
},
|
||||
|
||||
enable: function() {
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.html.Toolbar) {
|
||||
child.enable.apply(child, arguments);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
disable: function() {
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.html.Toolbar) {
|
||||
child.disable.apply(child, arguments);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
select: function(name) {
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.html.Toolbar) {
|
||||
child.select(arguments);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
deselect: function(name) {
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.html.Toolbar) {
|
||||
child.deselect(arguments);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getItemsState: function() {
|
||||
var values = {};
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.html.Toolbar) {
|
||||
dojo.lang.mixin(values, child.getItemsState());
|
||||
}
|
||||
}
|
||||
return values;
|
||||
},
|
||||
|
||||
getItemsActiveState: function() {
|
||||
var values = {};
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.html.Toolbar) {
|
||||
dojo.lang.mixin(values, child.getItemsActiveState());
|
||||
}
|
||||
}
|
||||
return values;
|
||||
},
|
||||
|
||||
getItemsSelectedState: function() {
|
||||
var values = {};
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.html.Toolbar) {
|
||||
dojo.lang.mixin(values, child.getItemsSelectedState());
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
});
|
||||
|
||||
/* Toolbar
|
||||
**********/
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:toolbar");
|
||||
dojo.widget.html.Toolbar = function() {
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.Toolbar, dojo.widget.HtmlWidget);
|
||||
dojo.lang.extend(dojo.widget.html.Toolbar, {
|
||||
widgetType: "Toolbar",
|
||||
isContainer: true,
|
||||
|
||||
templateString: '<div class="toolbar" dojoAttachPoint="containerNode" unselectable="on" dojoOnMouseover="_onmouseover" dojoOnMouseout="_onmouseout" dojoOnClick="_onclick" dojoOnMousedown="_onmousedown" dojoOnMouseup="_onmouseup"></div>',
|
||||
//templateString: '<div class="toolbar" dojoAttachPoint="containerNode" unselectable="on"></div>',
|
||||
|
||||
// given a node, tries to find it's toolbar item
|
||||
_getItem: function(node) {
|
||||
var start = new Date();
|
||||
var widget = null;
|
||||
while(node && node != this.domNode) {
|
||||
if(dojo.html.hasClass(node, "toolbarItem")) {
|
||||
var widgets = dojo.widget.manager.getWidgetsByFilter(function(w) { return w.domNode == node; });
|
||||
if(widgets.length == 1) {
|
||||
widget = widgets[0];
|
||||
break;
|
||||
} else if(widgets.length > 1) {
|
||||
dojo.raise("Toolbar._getItem: More than one widget matches the node");
|
||||
}
|
||||
}
|
||||
node = node.parentNode;
|
||||
}
|
||||
return widget;
|
||||
},
|
||||
|
||||
_onmouseover: function(e) {
|
||||
var widget = this._getItem(e.target);
|
||||
if(widget && widget._onmouseover) { widget._onmouseover(e); }
|
||||
},
|
||||
|
||||
_onmouseout: function(e) {
|
||||
var widget = this._getItem(e.target);
|
||||
if(widget && widget._onmouseout) { widget._onmouseout(e); }
|
||||
},
|
||||
|
||||
_onclick: function(e) {
|
||||
var widget = this._getItem(e.target);
|
||||
if(widget && widget._onclick){
|
||||
widget._onclick(e);
|
||||
}
|
||||
},
|
||||
|
||||
_onmousedown: function(e) {
|
||||
var widget = this._getItem(e.target);
|
||||
if(widget && widget._onmousedown) { widget._onmousedown(e); }
|
||||
},
|
||||
|
||||
_onmouseup: function(e) {
|
||||
var widget = this._getItem(e.target);
|
||||
if(widget && widget._onmouseup) { widget._onmouseup(e); }
|
||||
},
|
||||
|
||||
addChild: function(item, pos, props) {
|
||||
var widget = dojo.widget.ToolbarItem.make(item, null, props);
|
||||
var ret = dojo.widget.html.Toolbar.superclass.addChild.call(this, widget, null, pos, null);
|
||||
return ret;
|
||||
},
|
||||
|
||||
push: function() {
|
||||
for(var i = 0; i < arguments.length; i++) {
|
||||
this.addChild(arguments[i]);
|
||||
}
|
||||
},
|
||||
|
||||
getItem: function(name) {
|
||||
if(name instanceof dojo.widget.ToolbarItem) { return name; }
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.ToolbarItem
|
||||
&& child._name == name) { return child; }
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
getItems: function() {
|
||||
var items = [];
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.ToolbarItem) {
|
||||
items.push(child);
|
||||
}
|
||||
}
|
||||
return items;
|
||||
},
|
||||
|
||||
getItemsState: function() {
|
||||
var values = {};
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.ToolbarItem) {
|
||||
values[child._name] = {
|
||||
selected: child._selected,
|
||||
enabled: child._enabled
|
||||
};
|
||||
}
|
||||
}
|
||||
return values;
|
||||
},
|
||||
|
||||
getItemsActiveState: function() {
|
||||
var values = this.getItemsState();
|
||||
for(var item in values) {
|
||||
values[item] = values[item].enabled;
|
||||
}
|
||||
return values;
|
||||
},
|
||||
|
||||
getItemsSelectedState: function() {
|
||||
var values = this.getItemsState();
|
||||
for(var item in values) {
|
||||
values[item] = values[item].selected;
|
||||
}
|
||||
return values;
|
||||
},
|
||||
|
||||
enable: function() {
|
||||
var items = arguments.length ? arguments : this.children;
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
var child = this.getItem(items[i]);
|
||||
if(child instanceof dojo.widget.ToolbarItem) {
|
||||
child.enable(false, true);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
disable: function() {
|
||||
var items = arguments.length ? arguments : this.children;
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
var child = this.getItem(items[i]);
|
||||
if(child instanceof dojo.widget.ToolbarItem) {
|
||||
child.disable();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
select: function() {
|
||||
for(var i = 0; i < arguments.length; i++) {
|
||||
var name = arguments[i];
|
||||
var item = this.getItem(name);
|
||||
if(item) { item.select(); }
|
||||
}
|
||||
},
|
||||
|
||||
deselect: function() {
|
||||
for(var i = 0; i < arguments.length; i++) {
|
||||
var name = arguments[i];
|
||||
var item = this.getItem(name);
|
||||
if(item) { item.disable(); }
|
||||
}
|
||||
},
|
||||
|
||||
setValue: function() {
|
||||
for(var i = 0; i < arguments.length; i += 2) {
|
||||
var name = arguments[i], value = arguments[i+1];
|
||||
var item = this.getItem(name);
|
||||
if(item) {
|
||||
if(item instanceof dojo.widget.ToolbarItem) {
|
||||
item.setValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/* ToolbarItem hierarchy:
|
||||
- ToolbarItem
|
||||
- ToolbarButton
|
||||
- ToolbarDialog
|
||||
- ToolbarMenu
|
||||
- ToolbarSeparator
|
||||
- ToolbarSpace
|
||||
- ToolbarFlexibleSpace
|
||||
*/
|
||||
|
||||
|
||||
/* ToolbarItem
|
||||
**************/
|
||||
dojo.widget.ToolbarItem = function() {
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.ToolbarItem, dojo.widget.HtmlWidget);
|
||||
dojo.lang.extend(dojo.widget.ToolbarItem, {
|
||||
templateString: '<span unselectable="on" class="toolbarItem"></span>',
|
||||
|
||||
_name: null,
|
||||
getName: function() { return this._name; },
|
||||
setName: function(value) { return this._name = value; },
|
||||
getValue: function() { return this.getName(); },
|
||||
setValue: function(value) { return this.setName(value); },
|
||||
|
||||
_selected: false,
|
||||
isSelected: function() { return this._selected; },
|
||||
setSelected: function(is, force, preventEvent) {
|
||||
if(!this._toggleItem && !force) { return; }
|
||||
is = Boolean(is);
|
||||
if(force || this._enabled && this._selected != is) {
|
||||
this._selected = is;
|
||||
this.update();
|
||||
if(!preventEvent) {
|
||||
this._fireEvent(is ? "onSelect" : "onDeselect");
|
||||
this._fireEvent("onChangeSelect");
|
||||
}
|
||||
}
|
||||
},
|
||||
select: function(force, preventEvent) {
|
||||
return this.setSelected(true, force, preventEvent);
|
||||
},
|
||||
deselect: function(force, preventEvent) {
|
||||
return this.setSelected(false, force, preventEvent);
|
||||
},
|
||||
|
||||
_toggleItem: false,
|
||||
isToggleItem: function() { return this._toggleItem; },
|
||||
setToggleItem: function(value) { this._toggleItem = Boolean(value); },
|
||||
|
||||
toggleSelected: function(force) {
|
||||
return this.setSelected(!this._selected, force);
|
||||
},
|
||||
|
||||
_enabled: true,
|
||||
isEnabled: function() { return this._enabled; },
|
||||
setEnabled: function(is, force, preventEvent) {
|
||||
is = Boolean(is);
|
||||
if(force || this._enabled != is) {
|
||||
this._enabled = is;
|
||||
this.update();
|
||||
if(!preventEvent) {
|
||||
this._fireEvent(this._enabled ? "onEnable" : "onDisable");
|
||||
this._fireEvent("onChangeEnabled");
|
||||
}
|
||||
}
|
||||
return this._enabled;
|
||||
},
|
||||
enable: function(force, preventEvent) {
|
||||
return this.setEnabled(true, force, preventEvent);
|
||||
},
|
||||
disable: function(force, preventEvent) {
|
||||
return this.setEnabled(false, force, preventEvent);
|
||||
},
|
||||
toggleEnabled: function(force, preventEvent) {
|
||||
return this.setEnabled(!this._enabled, force, preventEvent);
|
||||
},
|
||||
|
||||
_icon: null,
|
||||
getIcon: function() { return this._icon; },
|
||||
setIcon: function(value) {
|
||||
var icon = dojo.widget.Icon.make(value);
|
||||
if(this._icon) {
|
||||
this._icon.setIcon(icon);
|
||||
} else {
|
||||
this._icon = icon;
|
||||
}
|
||||
var iconNode = this._icon.getNode();
|
||||
if(iconNode.parentNode != this.domNode) {
|
||||
if(this.domNode.hasChildNodes()) {
|
||||
this.domNode.insertBefore(iconNode, this.domNode.firstChild);
|
||||
} else {
|
||||
this.domNode.appendChild(iconNode);
|
||||
}
|
||||
}
|
||||
return this._icon;
|
||||
},
|
||||
|
||||
// TODO: update the label node (this.labelNode?)
|
||||
_label: "",
|
||||
getLabel: function() { return this._label; },
|
||||
setLabel: function(value) {
|
||||
var ret = this._label = value;
|
||||
if(!this.labelNode) {
|
||||
this.labelNode = document.createElement("span");
|
||||
this.domNode.appendChild(this.labelNode);
|
||||
}
|
||||
this.labelNode.innerHTML = "";
|
||||
this.labelNode.appendChild(document.createTextNode(this._label));
|
||||
this.update();
|
||||
return ret;
|
||||
},
|
||||
|
||||
// fired from: setSelected, setEnabled, setLabel
|
||||
update: function() {
|
||||
if(this._enabled) {
|
||||
dojo.html.removeClass(this.domNode, "disabled");
|
||||
if(this._selected) {
|
||||
dojo.html.addClass(this.domNode, "selected");
|
||||
} else {
|
||||
dojo.html.removeClass(this.domNode, "selected");
|
||||
}
|
||||
} else {
|
||||
this._selected = false;
|
||||
dojo.html.addClass(this.domNode, "disabled");
|
||||
dojo.html.removeClass(this.domNode, "down");
|
||||
dojo.html.removeClass(this.domNode, "hover");
|
||||
}
|
||||
this._updateIcon();
|
||||
},
|
||||
|
||||
_updateIcon: function() {
|
||||
if(this._icon) {
|
||||
if(this._enabled) {
|
||||
if(this._cssHover) {
|
||||
this._icon.hover();
|
||||
} else if(this._selected) {
|
||||
this._icon.select();
|
||||
} else {
|
||||
this._icon.enable();
|
||||
}
|
||||
} else {
|
||||
this._icon.disable();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_fireEvent: function(evt) {
|
||||
if(typeof this[evt] == "function") {
|
||||
var args = [this];
|
||||
for(var i = 1; i < arguments.length; i++) {
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
this[evt].apply(this, args);
|
||||
}
|
||||
},
|
||||
|
||||
_onmouseover: function(e) {
|
||||
if(!this._enabled) { return };
|
||||
dojo.html.addClass(this.domNode, "hover");
|
||||
},
|
||||
|
||||
_onmouseout: function(e) {
|
||||
dojo.html.removeClass(this.domNode, "hover");
|
||||
dojo.html.removeClass(this.domNode, "down");
|
||||
if(!this._selected) {
|
||||
dojo.html.removeClass(this.domNode, "selected");
|
||||
}
|
||||
},
|
||||
|
||||
_onclick: function(e) {
|
||||
// FIXME: buttons never seem to have this._enabled set to true on Opera 9
|
||||
// dojo.debug("widget:", this.widgetType, ":", this.getName(), ", enabled:", this._enabled);
|
||||
if(this._enabled && !this._toggleItem) {
|
||||
this._fireEvent("onClick");
|
||||
}
|
||||
},
|
||||
|
||||
_onmousedown: function(e) {
|
||||
if(e.preventDefault) { e.preventDefault(); }
|
||||
if(!this._enabled) { return };
|
||||
dojo.html.addClass(this.domNode, "down");
|
||||
if(this._toggleItem) {
|
||||
if(this.parent.preventDeselect && this._selected) {
|
||||
return;
|
||||
}
|
||||
this.toggleSelected();
|
||||
}
|
||||
},
|
||||
|
||||
_onmouseup: function(e) {
|
||||
dojo.html.removeClass(this.domNode, "down");
|
||||
},
|
||||
|
||||
fillInTemplate: function(args, frag) {
|
||||
if(args.name) { this._name = args.name; }
|
||||
if(args.selected) { this.select(); }
|
||||
if(args.disabled) { this.disable(); }
|
||||
if(args.label) { this.setLabel(args.label); }
|
||||
if(args.icon) { this.setIcon(args.icon); }
|
||||
if(args.toggleitem||args.toggleItem) { this.setToggleItem(true); }
|
||||
}
|
||||
});
|
||||
|
||||
dojo.widget.ToolbarItem.make = function(wh, whIsType, props) {
|
||||
var item = null;
|
||||
|
||||
if(wh instanceof Array) {
|
||||
item = dojo.widget.createWidget("ToolbarButtonGroup", props);
|
||||
item.setName(wh[0]);
|
||||
for(var i = 1; i < wh.length; i++) {
|
||||
item.addChild(wh[i]);
|
||||
}
|
||||
} else if(wh instanceof dojo.widget.ToolbarItem) {
|
||||
item = wh;
|
||||
} else if(wh instanceof dojo.uri.Uri) {
|
||||
item = dojo.widget.createWidget("ToolbarButton",
|
||||
dojo.lang.mixin(props||{}, {icon: new dojo.widget.Icon(wh.toString())}));
|
||||
} else if(whIsType) {
|
||||
item = dojo.widget.createWidget(wh, props)
|
||||
} else if(typeof wh == "string" || wh instanceof String) {
|
||||
switch(wh.charAt(0)) {
|
||||
case "|":
|
||||
case "-":
|
||||
case "/":
|
||||
item = dojo.widget.createWidget("ToolbarSeparator", props);
|
||||
break;
|
||||
case " ":
|
||||
if(wh.length == 1) {
|
||||
item = dojo.widget.createWidget("ToolbarSpace", props);
|
||||
} else {
|
||||
item = dojo.widget.createWidget("ToolbarFlexibleSpace", props);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(/\.(gif|jpg|jpeg|png)$/i.test(wh)) {
|
||||
item = dojo.widget.createWidget("ToolbarButton",
|
||||
dojo.lang.mixin(props||{}, {icon: new dojo.widget.Icon(wh.toString())}));
|
||||
} else {
|
||||
item = dojo.widget.createWidget("ToolbarButton",
|
||||
dojo.lang.mixin(props||{}, {label: wh.toString()}));
|
||||
}
|
||||
}
|
||||
} else if(wh && wh.tagName && /^img$/i.test(wh.tagName)) {
|
||||
item = dojo.widget.createWidget("ToolbarButton",
|
||||
dojo.lang.mixin(props||{}, {icon: wh}));
|
||||
} else {
|
||||
item = dojo.widget.createWidget("ToolbarButton",
|
||||
dojo.lang.mixin(props||{}, {label: wh.toString()}));
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/* ToolbarButtonGroup
|
||||
*********************/
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:toolbarButtonGroup");
|
||||
dojo.widget.html.ToolbarButtonGroup = function() {
|
||||
dojo.widget.ToolbarItem.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.ToolbarButtonGroup, dojo.widget.ToolbarItem);
|
||||
dojo.lang.extend(dojo.widget.html.ToolbarButtonGroup, {
|
||||
widgetType: "ToolbarButtonGroup",
|
||||
isContainer: true,
|
||||
|
||||
templateString: '<span unselectable="on" class="toolbarButtonGroup" dojoAttachPoint="containerNode"></span>',
|
||||
|
||||
// if a button has the same name, it will be selected
|
||||
// if this is set to a number, the button at that index will be selected
|
||||
defaultButton: "",
|
||||
|
||||
postCreate: function() {
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
this._injectChild(this.children[i]);
|
||||
}
|
||||
},
|
||||
|
||||
addChild: function(item, pos, props) {
|
||||
var widget = dojo.widget.ToolbarItem.make(item, null, dojo.lang.mixin(props||{}, {toggleItem:true}));
|
||||
var ret = dojo.widget.html.ToolbarButtonGroup.superclass.addChild.call(this, widget, null, pos, null);
|
||||
this._injectChild(widget);
|
||||
return ret;
|
||||
},
|
||||
|
||||
_injectChild: function(widget) {
|
||||
dojo.event.connect(widget, "onSelect", this, "onChildSelected");
|
||||
dojo.event.connect(widget, "onDeselect", this, "onChildDeSelected");
|
||||
if(widget._name == this.defaultButton
|
||||
|| (typeof this.defaultButton == "number"
|
||||
&& this.children.length-1 == this.defaultButton)) {
|
||||
widget.select(false, true);
|
||||
}
|
||||
},
|
||||
|
||||
getItem: function(name) {
|
||||
if(name instanceof dojo.widget.ToolbarItem) { return name; }
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.ToolbarItem
|
||||
&& child._name == name) { return child; }
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
getItems: function() {
|
||||
var items = [];
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.ToolbarItem) {
|
||||
items.push(child);
|
||||
}
|
||||
}
|
||||
return items;
|
||||
},
|
||||
|
||||
onChildSelected: function(e) {
|
||||
this.select(e._name);
|
||||
},
|
||||
|
||||
onChildDeSelected: function(e) {
|
||||
this._fireEvent("onChangeSelect", this._value);
|
||||
},
|
||||
|
||||
enable: function(force, preventEvent) {
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.ToolbarItem) {
|
||||
child.enable(force, preventEvent);
|
||||
if(child._name == this._value) {
|
||||
child.select(force, preventEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
disable: function(force, preventEvent) {
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.ToolbarItem) {
|
||||
child.disable(force, preventEvent);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_value: "",
|
||||
getValue: function() { return this._value; },
|
||||
|
||||
select: function(name, force, preventEvent) {
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if(child instanceof dojo.widget.ToolbarItem) {
|
||||
if(child._name == name) {
|
||||
child.select(force, preventEvent);
|
||||
this._value = name;
|
||||
} else {
|
||||
child.deselect(true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!preventEvent) {
|
||||
this._fireEvent("onSelect", this._value);
|
||||
this._fireEvent("onChangeSelect", this._value);
|
||||
}
|
||||
},
|
||||
setValue: this.select,
|
||||
|
||||
preventDeselect: false // if true, once you select one, you can't have none selected
|
||||
});
|
||||
|
||||
/* ToolbarButton
|
||||
***********************/
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:toolbarButton");
|
||||
dojo.widget.html.ToolbarButton = function() {
|
||||
dojo.widget.ToolbarItem.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.ToolbarButton, dojo.widget.ToolbarItem);
|
||||
dojo.lang.extend(dojo.widget.html.ToolbarButton, {
|
||||
widgetType: "ToolbarButton",
|
||||
|
||||
fillInTemplate: function(args, frag) {
|
||||
dojo.widget.html.ToolbarButton.superclass.fillInTemplate.call(this, args, frag);
|
||||
dojo.html.addClass(this.domNode, "toolbarButton");
|
||||
if(this._icon) {
|
||||
this.setIcon(this._icon);
|
||||
}
|
||||
if(this._label) {
|
||||
this.setLabel(this._label);
|
||||
}
|
||||
|
||||
if(!this._name) {
|
||||
if(this._label) {
|
||||
this.setName(this._label);
|
||||
} else if(this._icon) {
|
||||
var src = this._icon.getSrc("enabled").match(/[\/^]([^\.\/]+)\.(gif|jpg|jpeg|png)$/i);
|
||||
if(src) { this.setName(src[1]); }
|
||||
} else {
|
||||
this._name = this._widgetId;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/* ToolbarDialog
|
||||
**********************/
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:toolbarDialog");
|
||||
dojo.widget.html.ToolbarDialog = function() {
|
||||
dojo.widget.html.ToolbarButton.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.ToolbarDialog, dojo.widget.html.ToolbarButton);
|
||||
dojo.lang.extend(dojo.widget.html.ToolbarDialog, {
|
||||
widgetType: "ToolbarDialog",
|
||||
|
||||
fillInTemplate: function (args, frag) {
|
||||
dojo.widget.html.ToolbarDialog.superclass.fillInTemplate.call(this, args, frag);
|
||||
dojo.event.connect(this, "onSelect", this, "showDialog");
|
||||
dojo.event.connect(this, "onDeselect", this, "hideDialog");
|
||||
},
|
||||
|
||||
showDialog: function (e) {
|
||||
dojo.lang.setTimeout(dojo.event.connect, 1, document, "onmousedown", this, "deselect");
|
||||
},
|
||||
|
||||
hideDialog: function (e) {
|
||||
dojo.event.disconnect(document, "onmousedown", this, "deselect");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/* ToolbarMenu
|
||||
**********************/
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:toolbarMenu");
|
||||
dojo.widget.html.ToolbarMenu = function() {
|
||||
dojo.widget.html.ToolbarDialog.call(this);
|
||||
|
||||
this.widgetType = "ToolbarMenu";
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.ToolbarMenu, dojo.widget.html.ToolbarDialog);
|
||||
|
||||
/* ToolbarMenuItem
|
||||
******************/
|
||||
dojo.widget.ToolbarMenuItem = function() {
|
||||
}
|
||||
|
||||
/* ToolbarSeparator
|
||||
**********************/
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:toolbarSeparator");
|
||||
dojo.widget.html.ToolbarSeparator = function() {
|
||||
dojo.widget.ToolbarItem.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.ToolbarSeparator, dojo.widget.ToolbarItem);
|
||||
dojo.lang.extend(dojo.widget.html.ToolbarSeparator, {
|
||||
widgetType: "ToolbarSeparator",
|
||||
templateString: '<span unselectable="on" class="toolbarItem toolbarSeparator"></span>',
|
||||
|
||||
defaultIconPath: new dojo.uri.dojoUri("src/widget/templates/buttons/-.gif"),
|
||||
|
||||
fillInTemplate: function(args, frag, skip) {
|
||||
dojo.widget.html.ToolbarSeparator.superclass.fillInTemplate.call(this, args, frag);
|
||||
this._name = this.widgetId;
|
||||
if(!skip) {
|
||||
if(!this._icon) {
|
||||
this.setIcon(this.defaultIconPath);
|
||||
}
|
||||
this.domNode.appendChild(this._icon.getNode());
|
||||
}
|
||||
},
|
||||
|
||||
// don't want events!
|
||||
_onmouseover: null,
|
||||
_onmouseout: null,
|
||||
_onclick: null,
|
||||
_onmousedown: null,
|
||||
_onmouseup: null
|
||||
});
|
||||
|
||||
/* ToolbarSpace
|
||||
**********************/
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:toolbarSpace");
|
||||
dojo.widget.html.ToolbarSpace = function() {
|
||||
dojo.widget.html.ToolbarSeparator.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.ToolbarSpace, dojo.widget.html.ToolbarSeparator);
|
||||
dojo.lang.extend(dojo.widget.html.ToolbarSpace, {
|
||||
widgetType: "ToolbarSpace",
|
||||
|
||||
fillInTemplate: function(args, frag, skip) {
|
||||
dojo.widget.html.ToolbarSpace.superclass.fillInTemplate.call(this, args, frag, true);
|
||||
if(!skip) {
|
||||
dojo.html.addClass(this.domNode, "toolbarSpace");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/* ToolbarSelect
|
||||
******************/
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:toolbarSelect");
|
||||
dojo.widget.html.ToolbarSelect = function() {
|
||||
dojo.widget.ToolbarItem.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.ToolbarSelect, dojo.widget.ToolbarItem);
|
||||
dojo.lang.extend(dojo.widget.html.ToolbarSelect, {
|
||||
widgetType: "ToolbarSelect",
|
||||
templateString: '<span class="toolbarItem toolbarSelect" unselectable="on"><select dojoAttachPoint="selectBox" dojoOnChange="changed"></select></span>',
|
||||
|
||||
fillInTemplate: function(args, frag) {
|
||||
dojo.widget.html.ToolbarSelect.superclass.fillInTemplate.call(this, args, frag, true);
|
||||
var keys = args.values;
|
||||
var i = 0;
|
||||
for(var val in keys) {
|
||||
var opt = document.createElement("option");
|
||||
opt.setAttribute("value", keys[val]);
|
||||
opt.innerHTML = val;
|
||||
this.selectBox.appendChild(opt);
|
||||
}
|
||||
},
|
||||
|
||||
changed: function(e) {
|
||||
this._fireEvent("onSetValue", this.selectBox.value);
|
||||
},
|
||||
|
||||
setEnabled: function(is, force, preventEvent) {
|
||||
var ret = dojo.widget.html.ToolbarSelect.superclass.setEnabled.call(this, is, force, preventEvent);
|
||||
this.selectBox.disabled = !this._enabled;
|
||||
return ret;
|
||||
},
|
||||
|
||||
// don't want events!
|
||||
_onmouseover: null,
|
||||
_onmouseout: null,
|
||||
_onclick: null,
|
||||
_onmousedown: null,
|
||||
_onmouseup: null
|
||||
});
|
||||
|
||||
/* Icon
|
||||
*********/
|
||||
// arguments can be IMG nodes, Image() instances or URLs -- enabled is the only one required
|
||||
dojo.widget.Icon = function(enabled, disabled, hover, selected){
|
||||
if(!arguments.length){
|
||||
// FIXME: should this be dojo.raise?
|
||||
throw new Error("Icon must have at least an enabled state");
|
||||
}
|
||||
var states = ["enabled", "disabled", "hover", "selected"];
|
||||
var currentState = "enabled";
|
||||
var domNode = document.createElement("img");
|
||||
|
||||
this.getState = function(){ return currentState; }
|
||||
this.setState = function(value){
|
||||
if(dojo.lang.inArray(value, states)){
|
||||
if(this[value]){
|
||||
currentState = value;
|
||||
domNode.setAttribute("src", this[currentState].src);
|
||||
}
|
||||
}else{
|
||||
throw new Error("Invalid state set on Icon (state: " + value + ")");
|
||||
}
|
||||
}
|
||||
|
||||
this.setSrc = function(state, value){
|
||||
if(/^img$/i.test(value.tagName)){
|
||||
this[state] = value;
|
||||
}else if(typeof value == "string" || value instanceof String
|
||||
|| value instanceof dojo.uri.Uri){
|
||||
this[state] = new Image();
|
||||
this[state].src = value.toString();
|
||||
}
|
||||
return this[state];
|
||||
}
|
||||
|
||||
this.setIcon = function(icon){
|
||||
for(var i = 0; i < states.length; i++){
|
||||
if(icon[states[i]]){
|
||||
this.setSrc(states[i], icon[states[i]]);
|
||||
}
|
||||
}
|
||||
this.update();
|
||||
}
|
||||
|
||||
this.enable = function(){ this.setState("enabled"); }
|
||||
this.disable = function(){ this.setState("disabled"); }
|
||||
this.hover = function(){ this.setState("hover"); }
|
||||
this.select = function(){ this.setState("selected"); }
|
||||
|
||||
this.getSize = function(){
|
||||
return {
|
||||
width: domNode.width||domNode.offsetWidth,
|
||||
height: domNode.height||domNode.offsetHeight
|
||||
};
|
||||
}
|
||||
|
||||
this.setSize = function(w, h){
|
||||
domNode.width = w;
|
||||
domNode.height = h;
|
||||
return { width: w, height: h };
|
||||
}
|
||||
|
||||
this.getNode = function(){
|
||||
return domNode;
|
||||
}
|
||||
|
||||
this.getSrc = function(state){
|
||||
if(state){ return this[state].src; }
|
||||
return domNode.src||"";
|
||||
}
|
||||
|
||||
this.update = function(){
|
||||
this.setState(currentState);
|
||||
}
|
||||
|
||||
for(var i = 0; i < states.length; i++){
|
||||
var arg = arguments[i];
|
||||
var state = states[i];
|
||||
this[state] = null;
|
||||
if(!arg){ continue; }
|
||||
this.setSrc(state, arg);
|
||||
}
|
||||
|
||||
this.enable();
|
||||
}
|
||||
|
||||
dojo.widget.Icon.make = function(a,b,c,d){
|
||||
for(var i = 0; i < arguments.length; i++){
|
||||
if(arguments[i] instanceof dojo.widget.Icon){
|
||||
return arguments[i];
|
||||
}
|
||||
}
|
||||
|
||||
return new dojo.widget.Icon(a,b,c,d);
|
||||
}
|
14
webapp/web/src/widget/Tooltip.js
Normal file
14
webapp/web/src/widget/Tooltip.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Tooltip");
|
||||
dojo.require("dojo.widget.Widget");
|
||||
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.Tooltip");
|
569
webapp/web/src/widget/Tree.js
Normal file
569
webapp/web/src/widget/Tree.js
Normal file
|
@ -0,0 +1,569 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tree model does all the drawing, visual node management etc.
|
||||
* Throws events about clicks on it, so someone may catch them and process
|
||||
* Tree knows nothing about DnD stuff, covered in TreeDragAndDrop and (if enabled) attached by controller
|
||||
*/
|
||||
|
||||
/**
|
||||
* TODO: use domNode.cloneNode instead of createElement for grid
|
||||
* Should be faster (lyxsus)
|
||||
*/
|
||||
dojo.provide("dojo.widget.Tree");
|
||||
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.io.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.widget.TreeNode");
|
||||
|
||||
|
||||
|
||||
// make it a tag
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:Tree");
|
||||
|
||||
|
||||
dojo.widget.Tree = function() {
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
|
||||
this.eventNames = {};
|
||||
|
||||
this.tree = this;
|
||||
this.DNDAcceptTypes = [];
|
||||
this.actionsDisabled = [];
|
||||
|
||||
}
|
||||
dojo.inherits(dojo.widget.Tree, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.Tree, {
|
||||
widgetType: "Tree",
|
||||
|
||||
eventNamesDefault: {
|
||||
// new child does not get domNode filled in (only template draft)
|
||||
// until addChild->createDOMNode is called(program way) OR createDOMNode (html-way)
|
||||
// hook events to operate on new DOMNode, create dropTargets etc
|
||||
createDOMNode: "createDOMNode",
|
||||
// tree created.. Perform tree-wide actions if needed
|
||||
treeCreate: "treeCreate",
|
||||
treeDestroy: "treeDestroy",
|
||||
// expand icon clicked
|
||||
treeClick: "treeClick",
|
||||
// node icon clicked
|
||||
iconClick: "iconClick",
|
||||
// node title clicked
|
||||
titleClick: "titleClick",
|
||||
|
||||
moveFrom: "moveFrom",
|
||||
moveTo: "moveTo",
|
||||
addChild: "addChild",
|
||||
removeNode: "removeNode",
|
||||
expand: "expand",
|
||||
collapse: "collapse"
|
||||
},
|
||||
|
||||
isContainer: true,
|
||||
|
||||
DNDMode: "off",
|
||||
|
||||
lockLevel: 0, // lock ++ unlock --, so nested locking works fine
|
||||
|
||||
strictFolders: true,
|
||||
|
||||
DNDModes: {
|
||||
BETWEEN: 1,
|
||||
ONTO: 2
|
||||
},
|
||||
|
||||
DNDAcceptTypes: "",
|
||||
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/images/Tree/Tree.css"),
|
||||
|
||||
templateString: '<div class="dojoTree"></div>',
|
||||
|
||||
isExpanded: true, // consider this "root node" to be always expanded
|
||||
|
||||
isTree: true,
|
||||
|
||||
objectId: "",
|
||||
|
||||
// autoCreate if not "off"
|
||||
// used to get the autocreated controller ONLY.
|
||||
// generally, tree DOES NOT KNOW about its CONTROLLER, it just doesn't care
|
||||
// controller gets messages via dojo.event
|
||||
controller: "",
|
||||
|
||||
// autoCreate if not "off"
|
||||
// used to get the autocreated selector ONLY.
|
||||
// generally, tree DOES NOT KNOW its SELECTOR
|
||||
// binding is made with dojo.event
|
||||
selector: "",
|
||||
|
||||
// used ONLY at initialization time
|
||||
menu: "", // autobind menu if menu's widgetId is set here
|
||||
|
||||
expandLevel: "", // expand to level automatically
|
||||
|
||||
//
|
||||
// these icons control the grid and expando buttons for the whole tree
|
||||
//
|
||||
|
||||
blankIconSrc: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_blank.gif"),
|
||||
|
||||
gridIconSrcT: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_t.gif"), // for non-last child grid
|
||||
gridIconSrcL: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_l.gif"), // for last child grid
|
||||
gridIconSrcV: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_v.gif"), // vertical line
|
||||
gridIconSrcP: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_p.gif"), // for under parent item child icons
|
||||
gridIconSrcC: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_c.gif"), // for under child item child icons
|
||||
gridIconSrcX: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_x.gif"), // grid for sole root item
|
||||
gridIconSrcY: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_y.gif"), // grid for last rrot item
|
||||
gridIconSrcZ: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_z.gif"), // for under root parent item child icon
|
||||
|
||||
expandIconSrcPlus: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_expand_plus.gif"),
|
||||
expandIconSrcMinus: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_expand_minus.gif"),
|
||||
expandIconSrcLoading: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_loading.gif"),
|
||||
|
||||
|
||||
iconWidth: 18,
|
||||
iconHeight: 18,
|
||||
|
||||
|
||||
//
|
||||
// tree options
|
||||
//
|
||||
|
||||
showGrid: true,
|
||||
showRootGrid: true,
|
||||
|
||||
actionIsDisabled: function(action) {
|
||||
var _this = this;
|
||||
return dojo.lang.inArray(_this.actionsDisabled, action)
|
||||
},
|
||||
|
||||
|
||||
actions: {
|
||||
ADDCHILD: "ADDCHILD"
|
||||
},
|
||||
|
||||
|
||||
getInfo: function() {
|
||||
var info = {
|
||||
widgetId: this.widgetId,
|
||||
objectId: this.objectId
|
||||
}
|
||||
|
||||
return info;
|
||||
},
|
||||
|
||||
initializeController: function() {
|
||||
if (this.controller != "off") {
|
||||
if (this.controller) {
|
||||
this.controller = dojo.widget.byId(this.controller);
|
||||
}
|
||||
else {
|
||||
// create default controller here
|
||||
dojo.require("dojo.widget.TreeBasicController");
|
||||
this.controller = dojo.widget.createWidget("TreeBasicController",
|
||||
{ DNDController: (this.DNDMode ? "create" : ""), dieWithTree: true }
|
||||
);
|
||||
|
||||
}
|
||||
this.controller.listenTree(this); // controller listens to my events
|
||||
|
||||
} else {
|
||||
this.controller = null;
|
||||
}
|
||||
},
|
||||
|
||||
initializeSelector: function() {
|
||||
|
||||
if (this.selector != "off") {
|
||||
if (this.selector) {
|
||||
this.selector = dojo.widget.byId(this.selector);
|
||||
}
|
||||
else {
|
||||
// create default controller here
|
||||
dojo.require("dojo.widget.TreeSelector");
|
||||
this.selector = dojo.widget.createWidget("TreeSelector", {dieWithTree: true});
|
||||
}
|
||||
|
||||
this.selector.listenTree(this);
|
||||
|
||||
} else {
|
||||
this.selector = null;
|
||||
}
|
||||
},
|
||||
|
||||
initialize: function(args, frag){
|
||||
|
||||
var _this = this;
|
||||
|
||||
for(name in this.eventNamesDefault) {
|
||||
if (dojo.lang.isUndefined(this.eventNames[name])) {
|
||||
this.eventNames[name] = this.widgetId+"/"+this.eventNamesDefault[name];
|
||||
}
|
||||
}
|
||||
|
||||
for(var i=0; i<this.actionsDisabled.length; i++) {
|
||||
this.actionsDisabled[i] = this.actionsDisabled[i].toUpperCase();
|
||||
}
|
||||
|
||||
if (this.DNDMode == "off") {
|
||||
this.DNDMode = 0;
|
||||
} else if (this.DNDMode == "between") {
|
||||
this.DNDMode = this.DNDModes.ONTO | this.DNDModes.BETWEEN;
|
||||
} else if (this.DNDMode == "onto") {
|
||||
this.DNDMode = this.DNDModes.ONTO;
|
||||
}
|
||||
|
||||
this.expandLevel = parseInt(this.expandLevel);
|
||||
|
||||
this.initializeSelector();
|
||||
this.initializeController();
|
||||
|
||||
if (this.menu) {
|
||||
this.menu = dojo.widget.byId(this.menu);
|
||||
this.menu.listenTree(this);
|
||||
}
|
||||
|
||||
|
||||
this.containerNode = this.domNode;
|
||||
|
||||
},
|
||||
|
||||
|
||||
postCreate: function() {
|
||||
this.createDOMNode();
|
||||
},
|
||||
|
||||
|
||||
createDOMNode: function() {
|
||||
|
||||
dojo.html.disableSelection(this.domNode);
|
||||
|
||||
for(var i=0; i<this.children.length; i++){
|
||||
this.children[i].parent = this; // root nodes have tree as parent
|
||||
|
||||
var node = this.children[i].createDOMNode(this, 0);
|
||||
|
||||
|
||||
this.domNode.appendChild(node);
|
||||
}
|
||||
|
||||
|
||||
if (!this.showRootGrid){
|
||||
for(var i=0; i<this.children.length; i++){
|
||||
this.children[i].expand();
|
||||
}
|
||||
}
|
||||
|
||||
dojo.event.topic.publish(this.eventNames.treeCreate, { source: this } );
|
||||
|
||||
},
|
||||
|
||||
|
||||
destroy: function() {
|
||||
dojo.event.topic.publish(this.tree.eventNames.treeDestroy, { source: this } );
|
||||
|
||||
return dojo.widget.HtmlWidget.prototype.destroy.apply(this, arguments);
|
||||
},
|
||||
|
||||
|
||||
addChild: function(child, index) {
|
||||
|
||||
// dojo.debug("doAddChild "+index+" called for "+child);
|
||||
|
||||
var message = {
|
||||
child: child,
|
||||
index: index,
|
||||
parent: this,
|
||||
// remember if dom was already initialized
|
||||
// initialized => no createDOMNode => no createDOMNode event
|
||||
domNodeInitialized: child.domNodeInitialized
|
||||
}
|
||||
|
||||
this.doAddChild.apply(this, arguments);
|
||||
|
||||
dojo.event.topic.publish(this.tree.eventNames.addChild, message);
|
||||
},
|
||||
|
||||
|
||||
// not called for initial tree building. See createDOMNode instead.
|
||||
// builds child html node if needed
|
||||
// index is "last node" by default
|
||||
/**
|
||||
* FIXME: Is it possible that removeNode from the tree will cause leaks cause of attached events ?
|
||||
* if yes, then only attach events in addChild and detach in remove.. Seems all ok yet.
|
||||
*/
|
||||
doAddChild: function(child, index){
|
||||
|
||||
if (dojo.lang.isUndefined(index)) {
|
||||
index = this.children.length;
|
||||
}
|
||||
|
||||
if (!child.isTreeNode){
|
||||
dojo.raise("You can only add TreeNode widgets to a "+this.widgetType+" widget!");
|
||||
return;
|
||||
}
|
||||
|
||||
// usually it is impossible to change "isFolder" state, but if anyone wants to add a child to leaf,
|
||||
// it is possible program-way.
|
||||
if (this.isTreeNode){
|
||||
if (!this.isFolder) { // just became a folder.
|
||||
//dojo.debug("becoming folder "+this);
|
||||
this.setFolder();
|
||||
}
|
||||
}
|
||||
|
||||
// adjust tree
|
||||
var _this = this;
|
||||
dojo.lang.forEach(child.getDescendants(), function(elem) { elem.tree = _this.tree; });
|
||||
|
||||
// fix parent
|
||||
child.parent = this;
|
||||
|
||||
|
||||
// no dynamic loading for those who become parents
|
||||
if (this.isTreeNode) {
|
||||
this.state = this.loadStates.LOADED;
|
||||
}
|
||||
|
||||
// add new child into DOM after it was added into children
|
||||
if (index < this.children.length) { // children[] already has child
|
||||
//dojo.debug("Inserting before "+this.children[index].title);
|
||||
dojo.dom.insertBefore(child.domNode, this.children[index].domNode);
|
||||
} else {
|
||||
this.containerNode.appendChild(child.domNode);
|
||||
if (this.isExpanded && this.isTreeNode) {
|
||||
/* When I add children to hidden containerNode => show container w/ them */
|
||||
this.showChildren();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.children.splice(index, 0, child);
|
||||
|
||||
//dojo.debugShallow(this.children);
|
||||
|
||||
|
||||
// if node exists - adjust its depth, otherwise build it
|
||||
if (child.domNodeInitialized) {
|
||||
var d = this.isTreeNode ? this.depth : -1;
|
||||
child.adjustDepth( d - child.depth + 1 );
|
||||
|
||||
|
||||
// update icons to link generated dom with Tree => updateParentGrid
|
||||
// if I moved child from LastNode inside the tree => need to link it up'n'down =>
|
||||
// updateExpandGridColumn
|
||||
// if I change depth => need to update all grid..
|
||||
child.updateIconTree();
|
||||
} else {
|
||||
//dojo.debug("Create domnode ");
|
||||
child.depth = this.isTreeNode ? this.depth+1 : 0;
|
||||
child.createDOMNode(child.tree, child.depth);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Use-case:
|
||||
// When previous sibling was created => it was last, no children after it
|
||||
// so it did not create link down => let's add it for all descendants
|
||||
// Use-case:
|
||||
// a child was moved down under the last node so last node should be updated
|
||||
var prevSibling = child.getPreviousSibling();
|
||||
if (child.isLastNode() && prevSibling) {
|
||||
prevSibling.updateExpandGridColumn();
|
||||
}
|
||||
|
||||
|
||||
//dojo.debug("Added child "+child);
|
||||
|
||||
|
||||
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
makeBlankImg: function() {
|
||||
var img = document.createElement('img');
|
||||
|
||||
img.style.width = this.iconWidth + 'px';
|
||||
img.style.height = this.iconHeight + 'px';
|
||||
img.src = this.blankIconSrc;
|
||||
img.style.verticalAlign = 'middle';
|
||||
|
||||
return img;
|
||||
},
|
||||
|
||||
|
||||
updateIconTree: function(){
|
||||
|
||||
//dojo.debug("Update icons for "+this)
|
||||
if (!this.isTree) {
|
||||
this.updateIcons();
|
||||
}
|
||||
|
||||
for(var i=0; i<this.children.length; i++){
|
||||
this.children[i].updateIconTree();
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
toString: function() {
|
||||
return "["+this.widgetType+" ID:"+this.widgetId+"]"
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Move child to newParent as last child
|
||||
* redraw tree and update icons.
|
||||
*
|
||||
* Called by target, saves source in event.
|
||||
* events are published for BOTH trees AFTER update.
|
||||
*/
|
||||
move: function(child, newParent, index) {
|
||||
|
||||
//dojo.debug(child+" "+newParent+" at "+index);
|
||||
|
||||
var oldParent = child.parent;
|
||||
var oldTree = child.tree;
|
||||
|
||||
this.doMove.apply(this, arguments);
|
||||
|
||||
var newParent = child.parent;
|
||||
var newTree = child.tree;
|
||||
|
||||
var message = {
|
||||
oldParent: oldParent, oldTree: oldTree,
|
||||
newParent: newParent, newTree: newTree,
|
||||
child: child
|
||||
};
|
||||
|
||||
/* publish events here about structural changes for both source and target trees */
|
||||
dojo.event.topic.publish(oldTree.eventNames.moveFrom, message);
|
||||
dojo.event.topic.publish(newTree.eventNames.moveTo, message);
|
||||
|
||||
},
|
||||
|
||||
|
||||
/* do actual parent change here. Write remove child first */
|
||||
doMove: function(child, newParent, index) {
|
||||
//var parent = child.parent;
|
||||
child.parent.doRemoveNode(child);
|
||||
|
||||
newParent.doAddChild(child, index);
|
||||
},
|
||||
|
||||
|
||||
|
||||
// ================================ removeNode ===================================
|
||||
|
||||
removeNode: function(child) {
|
||||
if (!child.parent) return;
|
||||
|
||||
var oldTree = child.tree;
|
||||
var oldParent = child.parent;
|
||||
|
||||
var removedChild = this.doRemoveNode.apply(this, arguments);
|
||||
|
||||
|
||||
dojo.event.topic.publish(this.tree.eventNames.removeNode,
|
||||
{ child: removedChild, tree: oldTree, parent: oldParent }
|
||||
);
|
||||
|
||||
return removedChild;
|
||||
},
|
||||
|
||||
|
||||
doRemoveNode: function(child) {
|
||||
if (!child.parent) return;
|
||||
|
||||
var parent = child.parent;
|
||||
|
||||
var children = parent.children;
|
||||
|
||||
|
||||
var index = child.getParentIndex();
|
||||
if (index < 0) {
|
||||
dojo.raise("Couldn't find node "+child+" for removal");
|
||||
}
|
||||
|
||||
|
||||
children.splice(index,1);
|
||||
dojo.dom.removeNode(child.domNode);
|
||||
|
||||
if (parent.children.length == 0) {
|
||||
parent.containerNode.style.display = "none";
|
||||
}
|
||||
|
||||
// if WAS last node (children.length decreased already) and has prevSibling
|
||||
if (index == children.length && index>0) {
|
||||
children[index-1].updateExpandGridColumn();
|
||||
}
|
||||
// if it WAS first node in WHOLE TREE -
|
||||
// update link up of its former lower neighbour(if exists still)
|
||||
if (parent instanceof dojo.widget.Tree && index == 0 && children.length>0) {
|
||||
children[0].updateExpandGrid();
|
||||
}
|
||||
|
||||
//parent.updateIconTree();
|
||||
|
||||
|
||||
child.parent = child.tree = null;
|
||||
|
||||
return child;
|
||||
},
|
||||
|
||||
markLoading: function() {
|
||||
// no way to mark tree loading
|
||||
},
|
||||
|
||||
unMarkLoading: function() {
|
||||
// no way to show that tree finished loading
|
||||
},
|
||||
|
||||
|
||||
lock: function() {
|
||||
!this.lockLevel && this.markLoading();
|
||||
this.lockLevel++;
|
||||
},
|
||||
unlock: function() {
|
||||
if (!this.lockLevel) {
|
||||
dojo.raise("unlock: not locked");
|
||||
}
|
||||
this.lockLevel--;
|
||||
!this.lockLevel && this.unMarkLoading();
|
||||
},
|
||||
|
||||
isLocked: function() {
|
||||
var node = this;
|
||||
while (true) {
|
||||
if (node.lockLevel) {
|
||||
return true;
|
||||
}
|
||||
if (node instanceof dojo.widget.Tree) {
|
||||
break;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
flushLock: function() {
|
||||
this.lockLevel = 0;
|
||||
this.unMarkLoading();
|
||||
}
|
||||
});
|
||||
|
||||
|
294
webapp/web/src/widget/TreeBasicController.js
Normal file
294
webapp/web/src/widget/TreeBasicController.js
Normal file
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
|
||||
dojo.provide("dojo.widget.TreeBasicController");
|
||||
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.json")
|
||||
dojo.require("dojo.io.*");
|
||||
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:TreeBasicController");
|
||||
|
||||
|
||||
dojo.widget.TreeBasicController = function() {
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.TreeBasicController, dojo.widget.HtmlWidget);
|
||||
|
||||
|
||||
dojo.lang.extend(dojo.widget.TreeBasicController, {
|
||||
widgetType: "TreeBasicController",
|
||||
|
||||
DNDController: "",
|
||||
|
||||
dieWithTree: false,
|
||||
|
||||
initialize: function(args, frag){
|
||||
|
||||
/* no DND by default for compatibility */
|
||||
if (this.DNDController == "create") {
|
||||
dojo.require("dojo.dnd.TreeDragAndDrop");
|
||||
this.DNDController = new dojo.dnd.TreeDNDController(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Binds controller to all tree events
|
||||
*/
|
||||
listenTree: function(tree) {
|
||||
//dojo.debug("Event "+tree.eventNames.treeClick);
|
||||
dojo.event.topic.subscribe(tree.eventNames.createDOMNode, this, "onCreateDOMNode");
|
||||
dojo.event.topic.subscribe(tree.eventNames.treeClick, this, "onTreeClick");
|
||||
dojo.event.topic.subscribe(tree.eventNames.treeCreate, this, "onTreeCreate");
|
||||
dojo.event.topic.subscribe(tree.eventNames.treeDestroy, this, "onTreeDestroy");
|
||||
|
||||
if (this.DNDController) {
|
||||
this.DNDController.listenTree(tree);
|
||||
}
|
||||
},
|
||||
|
||||
unlistenTree: function(tree) {
|
||||
dojo.event.topic.unsubscribe(tree.eventNames.createDOMNode, this, "onCreateDOMNode");
|
||||
dojo.event.topic.unsubscribe(tree.eventNames.treeClick, this, "onTreeClick");
|
||||
dojo.event.topic.unsubscribe(tree.eventNames.treeCreate, this, "onTreeCreate");
|
||||
dojo.event.topic.unsubscribe(tree.eventNames.treeDestroy, this, "onTreeDestroy");
|
||||
},
|
||||
|
||||
onTreeDestroy: function(message) {
|
||||
var tree = message.source;
|
||||
|
||||
this.unlistenTree(tree);
|
||||
|
||||
if (this.dieWithTree) {
|
||||
//alert("Killing myself "+this.widgetId);
|
||||
this.destroy();
|
||||
//dojo.debug("done");
|
||||
}
|
||||
},
|
||||
|
||||
onCreateDOMNode: function(message) {
|
||||
|
||||
var node = message.source;
|
||||
|
||||
|
||||
if (node.expandLevel > 0) {
|
||||
this.expandToLevel(node, node.expandLevel);
|
||||
}
|
||||
},
|
||||
|
||||
// perform actions-initializers for tree
|
||||
onTreeCreate: function(message) {
|
||||
var tree = message.source;
|
||||
var _this = this;
|
||||
if (tree.expandLevel) {
|
||||
dojo.lang.forEach(tree.children,
|
||||
function(child) {
|
||||
_this.expandToLevel(child, tree.expandLevel-1)
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
expandToLevel: function(node, level) {
|
||||
if (level == 0) return;
|
||||
|
||||
var children = node.children;
|
||||
var _this = this;
|
||||
|
||||
var handler = function(node, expandLevel) {
|
||||
this.node = node;
|
||||
this.expandLevel = expandLevel;
|
||||
// recursively expand opened node
|
||||
this.process = function() {
|
||||
//dojo.debug("Process "+node+" level "+level);
|
||||
for(var i=0; i<this.node.children.length; i++) {
|
||||
var child = node.children[i];
|
||||
|
||||
_this.expandToLevel(child, this.expandLevel);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var h = new handler(node, level-1);
|
||||
|
||||
|
||||
this.expand(node, false, h, h.process);
|
||||
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
onTreeClick: function(message){
|
||||
var node = message.source;
|
||||
|
||||
if(node.isLocked()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (node.isExpanded){
|
||||
this.collapse(node);
|
||||
} else {
|
||||
this.expand(node);
|
||||
}
|
||||
},
|
||||
|
||||
expand: function(node, sync, callObj, callFunc) {
|
||||
node.expand();
|
||||
if (callFunc) callFunc.apply(callObj, [node]);
|
||||
},
|
||||
|
||||
collapse: function(node) {
|
||||
|
||||
node.collapse();
|
||||
},
|
||||
|
||||
// =============================== move ============================
|
||||
|
||||
/**
|
||||
* Checks whether it is ok to change parent of child to newParent
|
||||
* May incur type checks etc
|
||||
*
|
||||
* It should check only hierarchical possibility w/o index, etc
|
||||
* because in onDragOver event for Between DND mode we can't calculate index at once on onDragOVer.
|
||||
* index changes as client moves mouse up-down over the node
|
||||
*/
|
||||
canMove: function(child, newParent){
|
||||
|
||||
if (child.actionIsDisabled(child.actions.MOVE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if we move under same parent then no matter if ADDCHILD disabled for him
|
||||
// but if we move to NEW parent then check if action is disabled for him
|
||||
// also covers case for newParent being a non-folder in strict mode etc
|
||||
if (child.parent !== newParent && newParent.actionIsDisabled(newParent.actions.ADDCHILD)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Can't move parent under child. check whether new parent is child of "child".
|
||||
var node = newParent;
|
||||
while(node.isTreeNode) {
|
||||
//dojo.debugShallow(node.title)
|
||||
if (node === child) {
|
||||
// parent of newParent is child
|
||||
return false;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
move: function(child, newParent, index) {
|
||||
|
||||
/* move sourceTreeNode to new parent */
|
||||
if (!this.canMove(child, newParent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var result = this.doMove(child, newParent, index);
|
||||
|
||||
if (!result) return result;
|
||||
|
||||
if (newParent.isTreeNode) {
|
||||
this.expand(newParent);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
doMove: function(child, newParent, index) {
|
||||
child.tree.move(child, newParent, index);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
// =============================== removeNode ============================
|
||||
|
||||
|
||||
canRemoveNode: function(child) {
|
||||
if (child.actionIsDisabled(child.actions.REMOVE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
removeNode: function(node, callObj, callFunc) {
|
||||
if (!this.canRemoveNode(node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.doRemoveNode(node, callObj, callFunc);
|
||||
},
|
||||
|
||||
|
||||
doRemoveNode: function(node, callObj, callFunc) {
|
||||
node.tree.removeNode(node);
|
||||
|
||||
if (callFunc) {
|
||||
callFunc.apply(dojo.lang.isUndefined(callObj) ? this : callObj, [node]);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Create node stuff
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
canCreateChild: function(parent, index, data) {
|
||||
if (parent.actionIsDisabled(parent.actions.ADDCHILD)) return false;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
/* send data to server and add child from server */
|
||||
/* data may contain an almost ready child, or anything else, suggested to server */
|
||||
/*in RPC controllers server responds with child data to be inserted */
|
||||
createChild: function(parent, index, data, callObj, callFunc) {
|
||||
if (!this.canCreateChild(parent, index, data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.doCreateChild.apply(this, arguments);
|
||||
},
|
||||
|
||||
doCreateChild: function(parent, index, data, callObj, callFunc) {
|
||||
|
||||
var widgetType = data.widgetType ? data.widgetType : "TreeNode";
|
||||
|
||||
var newChild = dojo.widget.createWidget(widgetType, data);
|
||||
|
||||
parent.addChild(newChild, index);
|
||||
|
||||
this.expand(parent);
|
||||
|
||||
if (callFunc) {
|
||||
callFunc.apply(callObj, [newChild]);
|
||||
}
|
||||
|
||||
return newChild;
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
214
webapp/web/src/widget/TreeContextMenu.js
Normal file
214
webapp/web/src/widget/TreeContextMenu.js
Normal file
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
|
||||
|
||||
dojo.provide("dojo.widget.TreeContextMenu");
|
||||
dojo.provide("dojo.widget.TreeMenuItem");
|
||||
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.io.*");
|
||||
dojo.require("dojo.widget.Menu2");
|
||||
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:TreeContextMenu");
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:TreeMenuItem");
|
||||
|
||||
|
||||
|
||||
dojo.widget.TreeContextMenu = function() {
|
||||
dojo.widget.PopupMenu2.call(this);
|
||||
|
||||
this.listenedTrees = [];
|
||||
|
||||
}
|
||||
|
||||
|
||||
dojo.inherits(dojo.widget.TreeContextMenu, dojo.widget.PopupMenu2);
|
||||
|
||||
dojo.lang.extend(dojo.widget.TreeContextMenu, {
|
||||
|
||||
widgetType: "TreeContextMenu",
|
||||
|
||||
open: function(x, y, parentMenu, explodeSrc){
|
||||
|
||||
var result = dojo.widget.PopupMenu2.prototype.open.apply(this, arguments);
|
||||
|
||||
/* publish many events here about structural changes */
|
||||
dojo.event.topic.publish(this.eventNames.open, { menu:this });
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
listenTree: function(tree) {
|
||||
/* add context menu to all nodes that exist already */
|
||||
var nodes = tree.getDescendants();
|
||||
|
||||
for(var i=0; i<nodes.length; i++) {
|
||||
if (!nodes[i].isTreeNode) continue;
|
||||
this.bindDomNode(nodes[i].labelNode);
|
||||
}
|
||||
|
||||
|
||||
/* bind context menu to all nodes that will be created in the future (e.g loaded from server)*/
|
||||
var _this = this;
|
||||
dojo.event.topic.subscribe(tree.eventNames.createDOMNode, this, "onCreateDOMNode");
|
||||
dojo.event.topic.subscribe(tree.eventNames.moveFrom, this, "onMoveFrom");
|
||||
dojo.event.topic.subscribe(tree.eventNames.moveTo, this, "onMoveTo");
|
||||
dojo.event.topic.subscribe(tree.eventNames.removeNode, this, "onRemoveNode");
|
||||
dojo.event.topic.subscribe(tree.eventNames.addChild, this, "onAddChild");
|
||||
dojo.event.topic.subscribe(tree.eventNames.treeDestroy, this, "onTreeDestroy");
|
||||
|
||||
this.listenedTrees.push(tree);
|
||||
|
||||
},
|
||||
|
||||
unlistenTree: function(tree) {
|
||||
/* clear event listeners */
|
||||
|
||||
dojo.event.topic.unsubscribe(tree.eventNames.createDOMNode, this, "onCreateDOMNode");
|
||||
dojo.event.topic.unsubscribe(tree.eventNames.moveFrom, this, "onMoveFrom");
|
||||
dojo.event.topic.unsubscribe(tree.eventNames.moveTo, this, "onMoveTo");
|
||||
dojo.event.topic.unsubscribe(tree.eventNames.removeNode, this, "onRemoveNode");
|
||||
dojo.event.topic.unsubscribe(tree.eventNames.addChild, this, "onAddChild");
|
||||
dojo.event.topic.unsubscribe(tree.eventNames.treeDestroy, this, "onTreeDestroy");
|
||||
|
||||
for(var i=0; i<this.listenedTrees.length; i++){
|
||||
if(this.listenedTrees[i] === tree){
|
||||
this.listenedTrees.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onTreeDestroy: function(message) {
|
||||
this.unlistenTree(message.source);
|
||||
},
|
||||
|
||||
bindTreeNode: function(node) {
|
||||
var _this = this;
|
||||
//dojo.debug("bind to "+node);
|
||||
dojo.lang.forEach(node.getDescendants(),
|
||||
function(e) {_this.bindDomNode(e.labelNode); }
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
unBindTreeNode: function(node) {
|
||||
var _this = this;
|
||||
//dojo.debug("Unbind from "+node);
|
||||
dojo.lang.forEach(node.getDescendants(),
|
||||
function(e) {_this.unBindDomNode(e.labelNode); }
|
||||
);
|
||||
},
|
||||
|
||||
onCreateDOMNode: function(message) {
|
||||
this.bindTreeNode(message.source);
|
||||
},
|
||||
|
||||
|
||||
onMoveFrom: function(message) {
|
||||
if (!dojo.lang.inArray(this.listenedTrees, message.newTree)) {
|
||||
this.unBindTreeNode(message.child);
|
||||
}
|
||||
},
|
||||
|
||||
onMoveTo: function(message) {
|
||||
if (dojo.lang.inArray(this.listenedTrees, message.newTree)) {
|
||||
this.bindTreeNode(message.child);
|
||||
}
|
||||
},
|
||||
|
||||
onRemoveNode: function(message) {
|
||||
this.unBindTreeNode(message.child);
|
||||
},
|
||||
|
||||
onAddChild: function(message) {
|
||||
if (message.domNodeInitialized) {
|
||||
// dom node was there already => I did not process onNodeDomCreate
|
||||
this.bindTreeNode(message.child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
dojo.widget.TreeMenuItem = function() {
|
||||
dojo.widget.MenuItem2.call(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
dojo.inherits(dojo.widget.TreeMenuItem, dojo.widget.MenuItem2);
|
||||
|
||||
|
||||
dojo.lang.extend(dojo.widget.TreeMenuItem, {
|
||||
|
||||
widgetType: "TreeMenuItem",
|
||||
|
||||
// treeActions menu item performs following actions (to be checked for permissions)
|
||||
treeActions: "",
|
||||
|
||||
initialize: function(args, frag) {
|
||||
|
||||
this.treeActions = this.treeActions.split(",");
|
||||
for(var i=0; i<this.treeActions.length; i++) {
|
||||
this.treeActions[i] = this.treeActions[i].toUpperCase();
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
getTreeNode: function() {
|
||||
var menu = this;
|
||||
|
||||
while (! (menu instanceof dojo.widget.TreeContextMenu) ) {
|
||||
menu = menu.parent;
|
||||
}
|
||||
|
||||
var source = menu.getTopOpenEvent().target;
|
||||
|
||||
while (!source.getAttribute('treeNode') && source.tagName != 'body') {
|
||||
source = source.parentNode;
|
||||
}
|
||||
if (source.tagName == 'body') {
|
||||
dojo.raise("treeNode not detected");
|
||||
}
|
||||
var treeNode = dojo.widget.manager.getWidgetById(source.getAttribute('treeNode'));
|
||||
|
||||
return treeNode;
|
||||
},
|
||||
|
||||
|
||||
menuOpen: function(message) {
|
||||
var treeNode = this.getTreeNode();
|
||||
|
||||
this.setDisabled(false); // enable by default
|
||||
|
||||
var _this = this;
|
||||
dojo.lang.forEach(_this.treeActions,
|
||||
function(action) {
|
||||
_this.setDisabled( treeNode.actionIsDisabled(action) );
|
||||
}
|
||||
);
|
||||
|
||||
},
|
||||
|
||||
toString: function() {
|
||||
return "["+this.widgetType+" node "+this.getTreeNode()+"]";
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
95
webapp/web/src/widget/TreeControllerExtension.js
Normal file
95
webapp/web/src/widget/TreeControllerExtension.js
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
/**
|
||||
* Additional tree utils
|
||||
*
|
||||
*/
|
||||
dojo.provide("dojo.widget.TreeControllerExtension");
|
||||
|
||||
|
||||
dojo.widget.TreeControllerExtension = function() { }
|
||||
|
||||
dojo.lang.extend(dojo.widget.TreeControllerExtension, {
|
||||
|
||||
saveExpandedIndices: function(node, field) {
|
||||
var obj = {};
|
||||
|
||||
for(var i=0; i<node.children.length; i++) {
|
||||
if (node.children[i].isExpanded) {
|
||||
var key = dojo.lang.isUndefined(field) ? i : node.children[i][field];
|
||||
obj[key] = this.saveExpandedIndices(node.children[i], field);
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
|
||||
restoreExpandedIndices: function(node, savedIndices, field) {
|
||||
var _this = this;
|
||||
|
||||
var handler = function(node, savedIndices) {
|
||||
this.node = node; //.children[i];
|
||||
this.savedIndices = savedIndices; //[i];
|
||||
// recursively read next savedIndices level and apply to opened node
|
||||
this.process = function() {
|
||||
//dojo.debug("Callback applied for "+this.node);
|
||||
_this.restoreExpandedIndices(this.node, this.savedIndices, field);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
for(var i=0; i<node.children.length; i++) {
|
||||
var child = node.children[i];
|
||||
|
||||
var found = false;
|
||||
var key = -1;
|
||||
|
||||
//dojo.debug("Check "+child)
|
||||
// process field set case
|
||||
if (dojo.lang.isUndefined(field) && savedIndices[i]) {
|
||||
found = true;
|
||||
key = i;
|
||||
}
|
||||
|
||||
// process case when field is not set
|
||||
if (field) {
|
||||
for(var key in savedIndices) {
|
||||
//dojo.debug("Compare "+key+" "+child[field])
|
||||
if (key == child[field]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we found anything - expand it
|
||||
if (found) {
|
||||
//dojo.debug("Found at "+key)
|
||||
var h = new handler(child, savedIndices[key]);
|
||||
_this.expand(child, false, h, h.process);
|
||||
} else if (child.isExpanded) { // not found, so collapse
|
||||
//dojo.debug("Collapsing all descendants "+node.children[i])
|
||||
dojo.lang.forEach(child.getDescendants(), function(elem) { _this.collapse(elem); });
|
||||
//this.collapse(node.children[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
217
webapp/web/src/widget/TreeLoadingController.js
Normal file
217
webapp/web/src/widget/TreeLoadingController.js
Normal file
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
|
||||
dojo.provide("dojo.widget.TreeLoadingController");
|
||||
|
||||
dojo.require("dojo.widget.TreeBasicController");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.json")
|
||||
dojo.require("dojo.io.*");
|
||||
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:TreeLoadingController");
|
||||
|
||||
|
||||
dojo.widget.TreeLoadingController = function() {
|
||||
dojo.widget.TreeBasicController.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.TreeLoadingController, dojo.widget.TreeBasicController);
|
||||
|
||||
|
||||
dojo.lang.extend(dojo.widget.TreeLoadingController, {
|
||||
widgetType: "TreeLoadingController",
|
||||
|
||||
RPCUrl: "",
|
||||
|
||||
RPCActionParam: "action", // used for GET for RPCUrl
|
||||
|
||||
|
||||
/**
|
||||
* Common RPC error handler (dies)
|
||||
*/
|
||||
RPCErrorHandler: function(type, obj, evt) {
|
||||
alert( "RPC Error: " + (obj.message||"no message"));
|
||||
},
|
||||
|
||||
|
||||
|
||||
getRPCUrl: function(action) {
|
||||
|
||||
// RPCUrl=local meant SOLELY for DEMO and LOCAL TESTS.
|
||||
// May lead to widgetId collisions
|
||||
if (this.RPCUrl == "local") {
|
||||
var dir = document.location.href.substr(0, document.location.href.lastIndexOf('/'));
|
||||
var localUrl = dir+"/"+action;
|
||||
//dojo.debug(localUrl);
|
||||
return localUrl;
|
||||
}
|
||||
|
||||
if (!this.RPCUrl) {
|
||||
dojo.raise("Empty RPCUrl: can't load");
|
||||
}
|
||||
|
||||
return this.RPCUrl + ( this.RPCUrl.indexOf("?") > -1 ? "&" : "?") + this.RPCActionParam+"="+action;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Add all loaded nodes from array obj as node children and expand it
|
||||
*/
|
||||
loadProcessResponse: function(node, result, callObj, callFunc) {
|
||||
|
||||
if (!dojo.lang.isUndefined(result.error)) {
|
||||
this.RPCErrorHandler("server", result.error);
|
||||
return false;
|
||||
}
|
||||
|
||||
//dojo.debugShallow(result);
|
||||
|
||||
var newChildren = result;
|
||||
|
||||
if (!dojo.lang.isArray(newChildren)) {
|
||||
dojo.raise('loadProcessResponse: Not array loaded: '+newChildren);
|
||||
}
|
||||
|
||||
for(var i=0; i<newChildren.length; i++) {
|
||||
// looks like dojo.widget.manager needs no special "add" command
|
||||
newChildren[i] = dojo.widget.createWidget(node.widgetType, newChildren[i]);
|
||||
node.addChild(newChildren[i]);
|
||||
}
|
||||
|
||||
|
||||
//node.addAllChildren(newChildren);
|
||||
|
||||
node.state = node.loadStates.LOADED;
|
||||
|
||||
//dojo.debug(callFunc);
|
||||
|
||||
if (dojo.lang.isFunction(callFunc)) {
|
||||
callFunc.apply(dojo.lang.isUndefined(callObj) ? this : callObj, [node, newChildren]);
|
||||
}
|
||||
//this.expand(node);
|
||||
},
|
||||
|
||||
getInfo: function(obj) {
|
||||
return obj.getInfo();
|
||||
},
|
||||
|
||||
runRPC: function(kw) {
|
||||
var _this = this;
|
||||
|
||||
var handle = function(type, data, evt) {
|
||||
// unlock BEFORE any processing is done
|
||||
// so errorHandler may apply locking
|
||||
if (kw.lock) {
|
||||
dojo.lang.forEach(kw.lock,
|
||||
function(t) { t.unlock() }
|
||||
);
|
||||
}
|
||||
|
||||
if(type == "load"){
|
||||
kw.load.call(this, data);
|
||||
}else{
|
||||
this.RPCErrorHandler(type, data, evt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (kw.lock) {
|
||||
dojo.lang.forEach(kw.lock,
|
||||
function(t) { t.lock() }
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
dojo.io.bind({
|
||||
url: kw.url,
|
||||
/* I hitch to get this.loadOkHandler */
|
||||
handle: dojo.lang.hitch(this, handle),
|
||||
mimetype: "text/json",
|
||||
preventCache: true,
|
||||
sync: kw.sync,
|
||||
content: { data: dojo.json.serialize(kw.params) }
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Load children of the node from server
|
||||
* Synchroneous loading doesn't break control flow
|
||||
* I need sync mode for DnD
|
||||
*/
|
||||
loadRemote: function(node, sync, callObj, callFunc){
|
||||
var _this = this;
|
||||
|
||||
var params = {
|
||||
node: this.getInfo(node),
|
||||
tree: this.getInfo(node.tree)
|
||||
};
|
||||
|
||||
//dojo.debug(callFunc)
|
||||
|
||||
this.runRPC({
|
||||
url: this.getRPCUrl('getChildren'),
|
||||
load: function(result) {
|
||||
_this.loadProcessResponse(node, result, callObj, callFunc) ;
|
||||
},
|
||||
sync: sync,
|
||||
lock: [node],
|
||||
params: params
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
expand: function(node, sync, callObj, callFunc) {
|
||||
|
||||
if (node.state == node.loadStates.UNCHECKED && node.isFolder) {
|
||||
|
||||
this.loadRemote(node, sync,
|
||||
this,
|
||||
function(node, newChildren) {
|
||||
this.expand(node, sync, callObj, callFunc);
|
||||
}
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
dojo.widget.TreeBasicController.prototype.expand.apply(this, arguments);
|
||||
|
||||
},
|
||||
|
||||
|
||||
|
||||
doMove: function(child, newParent, index) {
|
||||
/* load nodes into newParent in sync mode, if needed, first */
|
||||
if (newParent.isTreeNode && newParent.state == newParent.loadStates.UNCHECKED) {
|
||||
this.loadRemote(newParent, true);
|
||||
}
|
||||
|
||||
return dojo.widget.TreeBasicController.prototype.doMove.apply(this, arguments);
|
||||
},
|
||||
|
||||
|
||||
doCreateChild: function(parent, index, data, callObj, callFunc) {
|
||||
|
||||
/* load nodes into newParent in sync mode, if needed, first */
|
||||
if (parent.state == parent.loadStates.UNCHECKED) {
|
||||
this.loadRemote(parent, true);
|
||||
}
|
||||
|
||||
return dojo.widget.TreeBasicController.prototype.doCreateChild.apply(this, arguments);
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
534
webapp/web/src/widget/TreeNode.js
Normal file
534
webapp/web/src/widget/TreeNode.js
Normal file
|
@ -0,0 +1,534 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
|
||||
dojo.provide("dojo.widget.TreeNode");
|
||||
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.io.*");
|
||||
|
||||
// make it a tag
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:TreeNode");
|
||||
|
||||
|
||||
// # //////////
|
||||
|
||||
dojo.widget.TreeNode = function() {
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
|
||||
this.actionsDisabled = [];
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.TreeNode, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.TreeNode, {
|
||||
widgetType: "TreeNode",
|
||||
|
||||
loadStates: {
|
||||
UNCHECKED: "UNCHECKED",
|
||||
LOADING: "LOADING",
|
||||
LOADED: "LOADED"
|
||||
},
|
||||
|
||||
|
||||
actions: {
|
||||
MOVE: "MOVE",
|
||||
REMOVE: "REMOVE",
|
||||
EDIT: "EDIT",
|
||||
ADDCHILD: "ADDCHILD"
|
||||
},
|
||||
|
||||
isContainer: true,
|
||||
|
||||
lockLevel: 0, // lock ++ unlock --, so nested locking works fine
|
||||
|
||||
|
||||
templateString: ('<div class="dojoTreeNode"> '
|
||||
+ '<span treeNode="${this.widgetId}" class="dojoTreeNodeLabel" dojoAttachPoint="labelNode"> '
|
||||
+ ' <span dojoAttachPoint="titleNode" dojoAttachEvent="onClick: onTitleClick" class="dojoTreeNodeLabelTitle">${this.title}</span> '
|
||||
+ '</span> '
|
||||
+ '<span class="dojoTreeNodeAfterLabel" dojoAttachPoint="afterLabelNode">${this.afterLabel}</span> '
|
||||
+ '<div dojoAttachPoint="containerNode" style="display:none"></div> '
|
||||
+ '</div>').replace(/(>|<)\s+/g, '$1'), // strip whitespaces between nodes
|
||||
|
||||
|
||||
childIconSrc: "",
|
||||
childIconFolderSrc: dojo.uri.dojoUri("src/widget/templates/images/Tree/closed.gif"), // for under root parent item child icon,
|
||||
childIconDocumentSrc: dojo.uri.dojoUri("src/widget/templates/images/Tree/document.gif"), // for under root parent item child icon,
|
||||
|
||||
childIcon: null,
|
||||
isTreeNode: true,
|
||||
|
||||
objectId: "", // the widget represents an object
|
||||
|
||||
afterLabel: "",
|
||||
afterLabelNode: null, // node to the left of labelNode
|
||||
|
||||
// an icon left from childIcon: imgs[-2].
|
||||
// if +/- for folders, blank for leaves
|
||||
expandIcon: null,
|
||||
|
||||
title: "",
|
||||
object: "", // node may have object attached, settable from HTML
|
||||
isFolder: false,
|
||||
|
||||
labelNode: null, // the item label
|
||||
titleNode: null, // the item title
|
||||
imgs: null, // an array of icons imgs
|
||||
|
||||
expandLevel: "", // expand to level
|
||||
|
||||
tree: null,
|
||||
|
||||
depth: 0,
|
||||
|
||||
isExpanded: false,
|
||||
|
||||
state: null, // after creation will change to loadStates: "loaded/loading/unchecked"
|
||||
domNodeInitialized: false, // domnode is initialized with icons etc
|
||||
|
||||
|
||||
isFirstNode: function() {
|
||||
return this.getParentIndex() == 0 ? true: false;
|
||||
},
|
||||
|
||||
isLastNode: function() {
|
||||
return this.getParentIndex() == this.parent.children.length-1 ? true : false;
|
||||
},
|
||||
|
||||
lock: function(){ return this.tree.lock.apply(this, arguments) },
|
||||
unlock: function(){ return this.tree.unlock.apply(this, arguments) },
|
||||
isLocked: function(){ return this.tree.isLocked.apply(this, arguments) },
|
||||
cleanLock: function(){ return this.tree.cleanLock.apply(this, arguments) },
|
||||
|
||||
actionIsDisabled: function(action) {
|
||||
var _this = this;
|
||||
|
||||
var disabled = false;
|
||||
|
||||
if (this.tree.strictFolders && action == this.actions.ADDCHILD && !this.isFolder) {
|
||||
disabled = true;
|
||||
}
|
||||
|
||||
if (dojo.lang.inArray(_this.actionsDisabled, action)) {
|
||||
disabled = true;
|
||||
}
|
||||
|
||||
if (this.isLocked()) {
|
||||
disabled = true;
|
||||
}
|
||||
|
||||
return disabled;
|
||||
},
|
||||
|
||||
getInfo: function() {
|
||||
// No title here (title may be widget)
|
||||
var info = {
|
||||
widgetId: this.widgetId,
|
||||
objectId: this.objectId,
|
||||
index: this.getParentIndex(),
|
||||
isFolder: this.isFolder
|
||||
}
|
||||
|
||||
return info;
|
||||
},
|
||||
|
||||
initialize: function(args, frag){
|
||||
|
||||
//dojo.debug(this.title)
|
||||
|
||||
this.state = this.loadStates.UNCHECKED;
|
||||
|
||||
for(var i=0; i<this.actionsDisabled.length; i++) {
|
||||
this.actionsDisabled[i] = this.actionsDisabled[i].toUpperCase();
|
||||
}
|
||||
|
||||
this.expandLevel = parseInt(this.expandLevel);
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Change visible node depth by appending/prepending with blankImgs
|
||||
* @param depthDiff Integer positive => move right, negative => move left
|
||||
*/
|
||||
adjustDepth: function(depthDiff) {
|
||||
|
||||
for(var i=0; i<this.children.length; i++) {
|
||||
this.children[i].adjustDepth(depthDiff);
|
||||
}
|
||||
|
||||
this.depth += depthDiff;
|
||||
|
||||
if (depthDiff>0) {
|
||||
for(var i=0; i<depthDiff; i++) {
|
||||
var img = this.tree.makeBlankImg();
|
||||
this.imgs.unshift(img);
|
||||
//dojo.debugShallow(this.domNode);
|
||||
dojo.dom.insertBefore(this.imgs[0], this.domNode.firstChild);
|
||||
|
||||
}
|
||||
}
|
||||
if (depthDiff<0) {
|
||||
for(var i=0; i<-depthDiff;i++) {
|
||||
this.imgs.shift();
|
||||
dojo.dom.removeNode(this.domNode.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
markLoading: function() {
|
||||
this._markLoadingSavedIcon = this.expandIcon.src;
|
||||
this.expandIcon.src = this.tree.expandIconSrcLoading;
|
||||
},
|
||||
|
||||
// if icon is "Loading" then
|
||||
unMarkLoading: function() {
|
||||
if (!this._markLoadingSavedIcon) return;
|
||||
|
||||
var im = new Image();
|
||||
im.src = this.tree.expandIconSrcLoading;
|
||||
|
||||
//dojo.debug("Unmark "+this.expandIcon.src+" : "+im.src);
|
||||
if (this.expandIcon.src == im.src) {
|
||||
this.expandIcon.src = this._markLoadingSavedIcon;
|
||||
}
|
||||
this._markLoadingSavedIcon = null;
|
||||
},
|
||||
|
||||
|
||||
setFolder: function() {
|
||||
dojo.event.connect(this.expandIcon, 'onclick', this, 'onTreeClick');
|
||||
this.expandIcon.src = this.isExpanded ? this.tree.expandIconSrcMinus : this.tree.expandIconSrcPlus;
|
||||
this.isFolder = true;
|
||||
},
|
||||
|
||||
|
||||
createDOMNode: function(tree, depth){
|
||||
|
||||
this.tree = tree;
|
||||
this.depth = depth;
|
||||
|
||||
|
||||
//
|
||||
// add the tree icons
|
||||
//
|
||||
|
||||
this.imgs = [];
|
||||
|
||||
for(var i=0; i<this.depth+1; i++){
|
||||
|
||||
var img = this.tree.makeBlankImg();
|
||||
|
||||
this.domNode.insertBefore(img, this.labelNode);
|
||||
|
||||
this.imgs.push(img);
|
||||
}
|
||||
|
||||
|
||||
this.expandIcon = this.imgs[this.imgs.length-1];
|
||||
|
||||
|
||||
this.childIcon = this.tree.makeBlankImg();
|
||||
|
||||
// add to images before the title
|
||||
this.imgs.push(this.childIcon);
|
||||
|
||||
dojo.dom.insertBefore(this.childIcon, this.titleNode);
|
||||
|
||||
// node with children(from source html) becomes folder on build stage.
|
||||
if (this.children.length || this.isFolder) {
|
||||
this.setFolder();
|
||||
}
|
||||
else {
|
||||
// leaves are always loaded
|
||||
//dojo.debug("Set "+this+" state to loaded");
|
||||
this.state = this.loadStates.LOADED;
|
||||
}
|
||||
|
||||
dojo.event.connect(this.childIcon, 'onclick', this, 'onIconClick');
|
||||
|
||||
|
||||
//
|
||||
// create the child rows
|
||||
//
|
||||
|
||||
|
||||
for(var i=0; i<this.children.length; i++){
|
||||
this.children[i].parent = this;
|
||||
|
||||
var node = this.children[i].createDOMNode(this.tree, this.depth+1);
|
||||
|
||||
this.containerNode.appendChild(node);
|
||||
}
|
||||
|
||||
|
||||
if (this.children.length) {
|
||||
this.state = this.loadStates.LOADED;
|
||||
}
|
||||
|
||||
this.updateIcons();
|
||||
|
||||
this.domNodeInitialized = true;
|
||||
|
||||
dojo.event.topic.publish(this.tree.eventNames.createDOMNode, { source: this } );
|
||||
|
||||
return this.domNode;
|
||||
},
|
||||
|
||||
onTreeClick: function(e){
|
||||
dojo.event.topic.publish(this.tree.eventNames.treeClick, { source: this, event: e });
|
||||
},
|
||||
|
||||
onIconClick: function(e){
|
||||
dojo.event.topic.publish(this.tree.eventNames.iconClick, { source: this, event: e });
|
||||
},
|
||||
|
||||
onTitleClick: function(e){
|
||||
dojo.event.topic.publish(this.tree.eventNames.titleClick, { source: this, event: e });
|
||||
},
|
||||
|
||||
markSelected: function() {
|
||||
dojo.html.addClass(this.titleNode, 'dojoTreeNodeLabelSelected');
|
||||
},
|
||||
|
||||
|
||||
unMarkSelected: function() {
|
||||
//dojo.debug('unmark')
|
||||
dojo.html.removeClass(this.titleNode, 'dojoTreeNodeLabelSelected');
|
||||
},
|
||||
|
||||
updateExpandIcon: function() {
|
||||
if (this.isFolder){
|
||||
this.expandIcon.src = this.isExpanded ? this.tree.expandIconSrcMinus : this.tree.expandIconSrcPlus;
|
||||
} else {
|
||||
this.expandIcon.src = this.tree.blankIconSrc;
|
||||
}
|
||||
},
|
||||
|
||||
/* set the grid under the expand icon */
|
||||
updateExpandGrid: function() {
|
||||
|
||||
if (this.tree.showGrid){
|
||||
if (this.depth){
|
||||
this.setGridImage(-2, this.isLastNode() ? this.tree.gridIconSrcL : this.tree.gridIconSrcT);
|
||||
}else{
|
||||
if (this.isFirstNode()){
|
||||
this.setGridImage(-2, this.isLastNode() ? this.tree.gridIconSrcX : this.tree.gridIconSrcY);
|
||||
}else{
|
||||
this.setGridImage(-2, this.isLastNode() ? this.tree.gridIconSrcL : this.tree.gridIconSrcT);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
this.setGridImage(-2, this.tree.blankIconSrc);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/* set the grid under the child icon */
|
||||
updateChildGrid: function() {
|
||||
|
||||
if ((this.depth || this.tree.showRootGrid) && this.tree.showGrid){
|
||||
this.setGridImage(-1, (this.children.length && this.isExpanded) ? this.tree.gridIconSrcP : this.tree.gridIconSrcC);
|
||||
}else{
|
||||
if (this.tree.showGrid && !this.tree.showRootGrid){
|
||||
this.setGridImage(-1, (this.children.length && this.isExpanded) ? this.tree.gridIconSrcZ : this.tree.blankIconSrc);
|
||||
}else{
|
||||
this.setGridImage(-1, this.tree.blankIconSrc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
|
||||
updateParentGrid: function() {
|
||||
var parent = this.parent;
|
||||
|
||||
//dojo.debug("updateParentGrid "+this);
|
||||
|
||||
for(var i=0; i<this.depth; i++){
|
||||
|
||||
//dojo.debug("Parent "+parent);
|
||||
|
||||
var idx = this.imgs.length-(3+i);
|
||||
var img = (this.tree.showGrid && !parent.isLastNode()) ? this.tree.gridIconSrcV : this.tree.blankIconSrc;
|
||||
|
||||
//dojo.debug("Image "+img+" for "+idx);
|
||||
|
||||
this.setGridImage(idx, img);
|
||||
|
||||
parent = parent.parent;
|
||||
}
|
||||
},
|
||||
|
||||
updateExpandGridColumn: function() {
|
||||
if (!this.tree.showGrid) return;
|
||||
|
||||
var _this = this;
|
||||
|
||||
var icon = this.isLastNode() ? this.tree.blankIconSrc : this.tree.gridIconSrcV;
|
||||
|
||||
dojo.lang.forEach(_this.getDescendants(),
|
||||
function(node) { node.setGridImage(_this.depth, icon); }
|
||||
);
|
||||
|
||||
this.updateExpandGrid();
|
||||
},
|
||||
|
||||
updateIcons: function(){
|
||||
|
||||
|
||||
//dojo.profile.start("updateIcons")
|
||||
|
||||
//dojo.debug("Update icons for "+this)
|
||||
//dojo.debug(this.isFolder)
|
||||
|
||||
this.imgs[0].style.display = this.tree.showRootGrid ? 'inline' : 'none';
|
||||
|
||||
|
||||
//
|
||||
// set the expand icon
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// set the child icon
|
||||
//
|
||||
this.buildChildIcon();
|
||||
|
||||
this.updateExpandGrid();
|
||||
this.updateChildGrid();
|
||||
this.updateParentGrid();
|
||||
|
||||
|
||||
|
||||
dojo.profile.stop("updateIcons")
|
||||
|
||||
},
|
||||
|
||||
buildChildIcon: function() {
|
||||
// IE (others?) tries to download whatever is on src attribute so setting "url()" like before isnt a good idea
|
||||
// Only results in a 404
|
||||
if(this.childIconSrc){
|
||||
this.childIcon.src = this.childIconSrc;
|
||||
}
|
||||
this.childIcon.style.display = this.childIconSrc ? 'inline' : 'none';
|
||||
},
|
||||
|
||||
setGridImage: function(idx, src){
|
||||
|
||||
if (idx < 0){
|
||||
idx = this.imgs.length + idx;
|
||||
}
|
||||
|
||||
//if (idx >= this.imgs.length-2) return;
|
||||
this.imgs[idx].style.backgroundImage = 'url(' + src + ')';
|
||||
},
|
||||
|
||||
|
||||
updateIconTree: function(){
|
||||
this.tree.updateIconTree.call(this);
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
expand: function(){
|
||||
if (this.isExpanded) return;
|
||||
|
||||
if (this.children.length) {
|
||||
this.showChildren();
|
||||
}
|
||||
|
||||
this.isExpanded = true;
|
||||
|
||||
this.updateExpandIcon();
|
||||
|
||||
dojo.event.topic.publish(this.tree.eventNames.expand, {source: this} );
|
||||
},
|
||||
|
||||
collapse: function(){
|
||||
if (!this.isExpanded) return;
|
||||
|
||||
this.hideChildren();
|
||||
this.isExpanded = false;
|
||||
|
||||
this.updateExpandIcon();
|
||||
|
||||
dojo.event.topic.publish(this.tree.eventNames.collapse, {source: this} );
|
||||
},
|
||||
|
||||
hideChildren: function(){
|
||||
this.tree.toggleObj.hide(
|
||||
this.containerNode, this.toggleDuration, this.explodeSrc, dojo.lang.hitch(this, "onHide")
|
||||
);
|
||||
|
||||
/* if dnd is in action, recalculate changed coordinates */
|
||||
if(dojo.exists(dojo, 'dnd.dragManager.dragObjects') && dojo.dnd.dragManager.dragObjects.length) {
|
||||
dojo.dnd.dragManager.cacheTargetLocations();
|
||||
}
|
||||
},
|
||||
|
||||
showChildren: function(){
|
||||
this.tree.toggleObj.show(
|
||||
this.containerNode, this.toggleDuration, this.explodeSrc, dojo.lang.hitch(this, "onShow")
|
||||
);
|
||||
|
||||
/* if dnd is in action, recalculate changed coordinates */
|
||||
if(dojo.exists(dojo, 'dnd.dragManager.dragObjects') && dojo.dnd.dragManager.dragObjects.length) {
|
||||
dojo.dnd.dragManager.cacheTargetLocations();
|
||||
}
|
||||
},
|
||||
|
||||
addChild: function(){
|
||||
return this.tree.addChild.apply(this, arguments);
|
||||
},
|
||||
|
||||
doAddChild: function(){
|
||||
return this.tree.doAddChild.apply(this, arguments);
|
||||
},
|
||||
|
||||
|
||||
|
||||
/* Edit current node : change properties and update contents */
|
||||
edit: function(props) {
|
||||
dojo.lang.mixin(this, props);
|
||||
if (props.title) {
|
||||
this.titleNode.innerHTML = this.title;
|
||||
}
|
||||
|
||||
if (props.afterLabel) {
|
||||
this.afterLabelNode.innerHTML = this.afterLabel;
|
||||
}
|
||||
|
||||
if (props.childIconSrc) {
|
||||
this.buildChildIcon();
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
|
||||
|
||||
removeNode: function(){ return this.tree.removeNode.apply(this, arguments) },
|
||||
doRemoveNode: function(){ return this.tree.doRemoveNode.apply(this, arguments) },
|
||||
|
||||
|
||||
toString: function() {
|
||||
return "["+this.widgetType+" Tree:"+this.tree+" ID:"+this.widgetId+" Title:"+this.title+"]";
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
171
webapp/web/src/widget/TreeRPCController.js
Normal file
171
webapp/web/src/widget/TreeRPCController.js
Normal file
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
|
||||
dojo.provide("dojo.widget.TreeRPCController");
|
||||
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.json")
|
||||
dojo.require("dojo.io.*");
|
||||
dojo.require("dojo.widget.TreeLoadingController");
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:TreeRPCController");
|
||||
|
||||
dojo.widget.TreeRPCController = function(){
|
||||
dojo.widget.TreeLoadingController.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.TreeRPCController, dojo.widget.TreeLoadingController);
|
||||
|
||||
dojo.lang.extend(dojo.widget.TreeRPCController, {
|
||||
widgetType: "TreeRPCController",
|
||||
|
||||
/**
|
||||
* Make request to server about moving children.
|
||||
*
|
||||
* Request returns "true" if move succeeded,
|
||||
* object with error field if failed
|
||||
*
|
||||
* I can't leave DragObject floating until async request returns, need to return false/true
|
||||
* so making it sync way...
|
||||
*
|
||||
* Also, "loading" icon is not shown until function finishes execution, so no indication for remote request.
|
||||
*/
|
||||
doMove: function(child, newParent, index){
|
||||
|
||||
//if (newParent.isTreeNode) newParent.markLoading();
|
||||
|
||||
var params = {
|
||||
// where from
|
||||
child: this.getInfo(child),
|
||||
childTree: this.getInfo(child.tree),
|
||||
// where to
|
||||
newParent: this.getInfo(newParent),
|
||||
newParentTree: this.getInfo(newParent.tree),
|
||||
newIndex: index
|
||||
};
|
||||
|
||||
var success;
|
||||
|
||||
this.runRPC({
|
||||
url: this.getRPCUrl('move'),
|
||||
/* I hitch to get this.loadOkHandler */
|
||||
load: function(response){
|
||||
success = this.doMoveProcessResponse(response, child, newParent, index) ;
|
||||
},
|
||||
sync: true,
|
||||
lock: [child, newParent],
|
||||
params: params
|
||||
});
|
||||
|
||||
|
||||
return success;
|
||||
},
|
||||
|
||||
doMoveProcessResponse: function(response, child, newParent, index){
|
||||
|
||||
if(!dojo.lang.isUndefined(response.error)){
|
||||
this.RPCErrorHandler("server", response.error);
|
||||
return false;
|
||||
}
|
||||
|
||||
var args = [child, newParent, index];
|
||||
return dojo.widget.TreeLoadingController.prototype.doMove.apply(this, args);
|
||||
|
||||
},
|
||||
|
||||
|
||||
doRemoveNode: function(node, callObj, callFunc){
|
||||
|
||||
var params = {
|
||||
node: this.getInfo(node),
|
||||
tree: this.getInfo(node.tree)
|
||||
}
|
||||
|
||||
this.runRPC({
|
||||
url: this.getRPCUrl('removeNode'),
|
||||
/* I hitch to get this.loadOkHandler */
|
||||
load: function(response){
|
||||
this.doRemoveNodeProcessResponse(response, node, callObj, callFunc)
|
||||
},
|
||||
params: params,
|
||||
lock: [node]
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
doRemoveNodeProcessResponse: function(response, node, callObj, callFunc){
|
||||
if(!dojo.lang.isUndefined(response.error)){
|
||||
this.RPCErrorHandler("server", response.error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!response){ return false; }
|
||||
|
||||
if(response == true){
|
||||
/* change parent succeeded */
|
||||
var args = [ node, callObj, callFunc ];
|
||||
dojo.widget.TreeLoadingController.prototype.doRemoveNode.apply(this, args);
|
||||
|
||||
return;
|
||||
}else if(dojo.lang.isObject(response)){
|
||||
dojo.raise(response.error);
|
||||
}else{
|
||||
dojo.raise("Invalid response "+response)
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Create node stuff
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
doCreateChild: function(parent, index, output, callObj, callFunc){
|
||||
|
||||
var params = {
|
||||
tree: this.getInfo(parent.tree),
|
||||
parent: this.getInfo(parent),
|
||||
index: index,
|
||||
data: output
|
||||
}
|
||||
|
||||
this.runRPC({
|
||||
url: this.getRPCUrl('createChild'),
|
||||
load: function(response) {
|
||||
// suggested data is dead, fresh data from server is used
|
||||
this.doCreateChildProcessResponse( response, parent, index, callObj, callFunc)
|
||||
},
|
||||
params: params,
|
||||
lock: [parent]
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
doCreateChildProcessResponse: function(response, parent, index, callObj, callFunc){
|
||||
|
||||
if(!dojo.lang.isUndefined(response.error)){
|
||||
this.RPCErrorHandler("server",response.error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!dojo.lang.isObject(response)){
|
||||
dojo.raise("Invalid result "+response)
|
||||
}
|
||||
|
||||
var args = [parent, index, response, callObj, callFunc];
|
||||
|
||||
dojo.widget.TreeLoadingController.prototype.doCreateChild.apply(this, args);
|
||||
}
|
||||
});
|
183
webapp/web/src/widget/TreeSelector.js
Normal file
183
webapp/web/src/widget/TreeSelector.js
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
|
||||
dojo.provide("dojo.widget.TreeSelector");
|
||||
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:TreeSelector");
|
||||
|
||||
|
||||
dojo.widget.TreeSelector = function() {
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
|
||||
|
||||
this.eventNames = {};
|
||||
|
||||
this.listenedTrees = [];
|
||||
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.TreeSelector, dojo.widget.HtmlWidget);
|
||||
|
||||
|
||||
dojo.lang.extend(dojo.widget.TreeSelector, {
|
||||
widgetType: "TreeSelector",
|
||||
selectedNode: null,
|
||||
|
||||
dieWithTree: false,
|
||||
|
||||
eventNamesDefault: {
|
||||
select : "select",
|
||||
destroy : "destroy",
|
||||
deselect : "deselect",
|
||||
dblselect: "dblselect" // select already selected node.. Edit or whatever
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
|
||||
for(name in this.eventNamesDefault) {
|
||||
if (dojo.lang.isUndefined(this.eventNames[name])) {
|
||||
this.eventNames[name] = this.widgetId+"/"+this.eventNamesDefault[name];
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
destroy: function() {
|
||||
dojo.event.topic.publish(this.eventNames.destroy, { source: this } );
|
||||
|
||||
return dojo.widget.HtmlWidget.prototype.destroy.apply(this, arguments);
|
||||
},
|
||||
|
||||
|
||||
listenTree: function(tree) {
|
||||
dojo.event.topic.subscribe(tree.eventNames.titleClick, this, "select");
|
||||
dojo.event.topic.subscribe(tree.eventNames.iconClick, this, "select");
|
||||
dojo.event.topic.subscribe(tree.eventNames.collapse, this, "onCollapse");
|
||||
dojo.event.topic.subscribe(tree.eventNames.moveFrom, this, "onMoveFrom");
|
||||
dojo.event.topic.subscribe(tree.eventNames.removeNode, this, "onRemoveNode");
|
||||
dojo.event.topic.subscribe(tree.eventNames.treeDestroy, this, "onTreeDestroy");
|
||||
|
||||
/* remember all my trees to deselect when element is movedFrom them */
|
||||
this.listenedTrees.push(tree);
|
||||
},
|
||||
|
||||
|
||||
unlistenTree: function(tree) {
|
||||
|
||||
dojo.event.topic.unsubscribe(tree.eventNames.titleClick, this, "select");
|
||||
dojo.event.topic.unsubscribe(tree.eventNames.iconClick, this, "select");
|
||||
dojo.event.topic.unsubscribe(tree.eventNames.collapse, this, "onCollapse");
|
||||
dojo.event.topic.unsubscribe(tree.eventNames.moveFrom, this, "onMoveFrom");
|
||||
dojo.event.topic.unsubscribe(tree.eventNames.removeNode, this, "onRemoveNode");
|
||||
dojo.event.topic.unsubscribe(tree.eventNames.treeDestroy, this, "onTreeDestroy");
|
||||
|
||||
|
||||
for(var i=0; i<this.listenedTrees.length; i++){
|
||||
if(this.listenedTrees[i] === tree){
|
||||
this.listenedTrees.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
onTreeDestroy: function(message) {
|
||||
|
||||
this.unlistenTree(message.source);
|
||||
|
||||
if (this.dieWithTree) {
|
||||
//dojo.debug("Killing myself "+this.widgetId);
|
||||
this.destroy();
|
||||
//dojo.debug("done");
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// deselect node if parent is collapsed
|
||||
onCollapse: function(message) {
|
||||
if (!this.selectedNode) return;
|
||||
|
||||
var node = message.source;
|
||||
var parent = this.selectedNode.parent;
|
||||
while (parent !== node && parent.isTreeNode) {
|
||||
parent = parent.parent;
|
||||
}
|
||||
if (parent.isTreeNode) {
|
||||
this.deselect();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
select: function(message) {
|
||||
var node = message.source;
|
||||
var e = message.event;
|
||||
|
||||
if (this.selectedNode === node) {
|
||||
dojo.event.topic.publish(this.eventNames.dblselect, { node: node });
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.selectedNode) {
|
||||
this.deselect();
|
||||
}
|
||||
|
||||
this.doSelect(node);
|
||||
|
||||
dojo.event.topic.publish(this.eventNames.select, {node: node} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Deselect node if target tree is out of our concern
|
||||
*/
|
||||
onMoveFrom: function(message) {
|
||||
if (message.child !== this.selectedNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dojo.lang.inArray(this.listenedTrees, message.newTree)) {
|
||||
this.deselect();
|
||||
}
|
||||
},
|
||||
|
||||
onRemoveNode: function(message) {
|
||||
if (message.child !== this.selectedNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.deselect();
|
||||
},
|
||||
|
||||
doSelect: function(node){
|
||||
|
||||
node.markSelected();
|
||||
|
||||
this.selectedNode = node;
|
||||
},
|
||||
|
||||
deselect: function(){
|
||||
|
||||
var node = this.selectedNode;
|
||||
|
||||
this.selectedNode = null;
|
||||
node.unMarkSelected();
|
||||
dojo.event.topic.publish(this.eventNames.deselect, {node: node} );
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
576
webapp/web/src/widget/Widget.js
Normal file
576
webapp/web/src/widget/Widget.js
Normal file
|
@ -0,0 +1,576 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Widget");
|
||||
dojo.provide("dojo.widget.tags");
|
||||
|
||||
dojo.require("dojo.lang.func");
|
||||
dojo.require("dojo.lang.array");
|
||||
dojo.require("dojo.lang.extras");
|
||||
dojo.require("dojo.lang.declare");
|
||||
dojo.require("dojo.widget.Manager");
|
||||
dojo.require("dojo.event.*");
|
||||
|
||||
dojo.declare("dojo.widget.Widget", null, {
|
||||
initializer: function() {
|
||||
// these properties aren't primitives and need to be created on a per-item
|
||||
// basis.
|
||||
this.children = [];
|
||||
// this.selection = new dojo.widget.Selection();
|
||||
// FIXME: need to replace this with context menu stuff
|
||||
this.extraArgs = {};
|
||||
},
|
||||
// FIXME: need to be able to disambiguate what our rendering context is
|
||||
// here!
|
||||
//
|
||||
// needs to be a string with the end classname. Every subclass MUST
|
||||
// over-ride.
|
||||
//
|
||||
// base widget properties
|
||||
parent: null,
|
||||
// obviously, top-level and modal widgets should set these appropriately
|
||||
isTopLevel: false,
|
||||
isModal: false,
|
||||
|
||||
isEnabled: true,
|
||||
isHidden: false,
|
||||
isContainer: false, // can we contain other widgets?
|
||||
widgetId: "",
|
||||
widgetType: "Widget", // used for building generic widgets
|
||||
|
||||
toString: function() {
|
||||
return '[Widget ' + this.widgetType + ', ' + (this.widgetId || 'NO ID') + ']';
|
||||
},
|
||||
|
||||
repr: function(){
|
||||
return this.toString();
|
||||
},
|
||||
|
||||
enable: function(){
|
||||
// should be over-ridden
|
||||
this.isEnabled = true;
|
||||
},
|
||||
|
||||
disable: function(){
|
||||
// should be over-ridden
|
||||
this.isEnabled = false;
|
||||
},
|
||||
|
||||
hide: function(){
|
||||
// should be over-ridden
|
||||
this.isHidden = true;
|
||||
},
|
||||
|
||||
show: function(){
|
||||
// should be over-ridden
|
||||
this.isHidden = false;
|
||||
},
|
||||
|
||||
onResized: function(){
|
||||
// Clients should override this function to do special processing,
|
||||
// then call this.notifyChildrenOfResize() to notify children of resize
|
||||
this.notifyChildrenOfResize();
|
||||
},
|
||||
|
||||
notifyChildrenOfResize: function(){
|
||||
for(var i=0; i<this.children.length; i++){
|
||||
var child = this.children[i];
|
||||
//dojo.debug(this.widgetId + " resizing child " + child.widgetId);
|
||||
if( child.onResized ){
|
||||
child.onResized();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
create: function(args, fragment, parentComp){
|
||||
// dojo.debug(this.widgetType, "create");
|
||||
this.satisfyPropertySets(args, fragment, parentComp);
|
||||
// dojo.debug(this.widgetType, "-> mixInProperties");
|
||||
this.mixInProperties(args, fragment, parentComp);
|
||||
// dojo.debug(this.widgetType, "-> postMixInProperties");
|
||||
this.postMixInProperties(args, fragment, parentComp);
|
||||
// dojo.debug(this.widgetType, "-> dojo.widget.manager.add");
|
||||
dojo.widget.manager.add(this);
|
||||
// dojo.debug(this.widgetType, "-> buildRendering");
|
||||
this.buildRendering(args, fragment, parentComp);
|
||||
// dojo.debug(this.widgetType, "-> initialize");
|
||||
this.initialize(args, fragment, parentComp);
|
||||
// dojo.debug(this.widgetType, "-> postInitialize");
|
||||
this.postInitialize(args, fragment, parentComp);
|
||||
// dojo.debug(this.widgetType, "-> postCreate");
|
||||
this.postCreate(args, fragment, parentComp);
|
||||
// dojo.debug(this.widgetType, "done!");
|
||||
return this;
|
||||
},
|
||||
|
||||
// Destroy this widget and it's descendants
|
||||
destroy: function(finalize){
|
||||
// FIXME: this is woefully incomplete
|
||||
this.destroyChildren();
|
||||
this.uninitialize();
|
||||
this.destroyRendering(finalize);
|
||||
dojo.widget.manager.removeById(this.widgetId);
|
||||
},
|
||||
|
||||
// Destroy the children of this widget, and their descendents
|
||||
destroyChildren: function(){
|
||||
while(this.children.length > 0){
|
||||
var tc = this.children[0];
|
||||
this.removeChild(tc);
|
||||
tc.destroy();
|
||||
}
|
||||
},
|
||||
|
||||
getChildrenOfType: function(type, recurse){
|
||||
var ret = [];
|
||||
var isFunc = dojo.lang.isFunction(type);
|
||||
if(!isFunc){
|
||||
type = type.toLowerCase();
|
||||
}
|
||||
for(var x=0; x<this.children.length; x++){
|
||||
if(isFunc){
|
||||
if(this.children[x] instanceof type){
|
||||
ret.push(this.children[x]);
|
||||
}
|
||||
}else{
|
||||
if(this.children[x].widgetType.toLowerCase() == type){
|
||||
ret.push(this.children[x]);
|
||||
}
|
||||
}
|
||||
if(recurse){
|
||||
ret = ret.concat(this.children[x].getChildrenOfType(type, recurse));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
|
||||
getDescendants: function(){
|
||||
var result = [];
|
||||
var stack = [this];
|
||||
var elem;
|
||||
while (elem = stack.pop()){
|
||||
result.push(elem);
|
||||
dojo.lang.forEach(elem.children, function(elem) { stack.push(elem); });
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
satisfyPropertySets: function(args){
|
||||
// dojo.profile.start("satisfyPropertySets");
|
||||
// get the default propsets for our component type
|
||||
/*
|
||||
var typePropSets = []; // FIXME: need to pull these from somewhere!
|
||||
var localPropSets = []; // pull out propsets from the parser's return structure
|
||||
|
||||
// for(var x=0; x<args.length; x++){
|
||||
// }
|
||||
|
||||
for(var x=0; x<typePropSets.length; x++){
|
||||
}
|
||||
|
||||
for(var x=0; x<localPropSets.length; x++){
|
||||
}
|
||||
*/
|
||||
// dojo.profile.end("satisfyPropertySets");
|
||||
|
||||
return args;
|
||||
},
|
||||
|
||||
mixInProperties: function(args, frag){
|
||||
if((args["fastMixIn"])||(frag["fastMixIn"])){
|
||||
// dojo.profile.start("mixInProperties_fastMixIn");
|
||||
// fast mix in assumes case sensitivity, no type casting, etc...
|
||||
// dojo.lang.mixin(this, args);
|
||||
for(var x in args){
|
||||
this[x] = args[x];
|
||||
}
|
||||
// dojo.profile.end("mixInProperties_fastMixIn");
|
||||
return;
|
||||
}
|
||||
// dojo.profile.start("mixInProperties");
|
||||
/*
|
||||
* the actual mix-in code attempts to do some type-assignment based on
|
||||
* PRE-EXISTING properties of the "this" object. When a named property
|
||||
* of a propset is located, it is first tested to make sure that the
|
||||
* current object already "has one". Properties which are undefined in
|
||||
* the base widget are NOT settable here. The next step is to try to
|
||||
* determine type of the pre-existing property. If it's a string, the
|
||||
* property value is simply assigned. If a function, the property is
|
||||
* replaced with a "new Function()" declaration. If an Array, the
|
||||
* system attempts to split the string value on ";" chars, and no
|
||||
* further processing is attempted (conversion of array elements to a
|
||||
* integers, for instance). If the property value is an Object
|
||||
* (testObj.constructor === Object), the property is split first on ";"
|
||||
* chars, secondly on ":" chars, and the resulting key/value pairs are
|
||||
* assigned to an object in a map style. The onus is on the property
|
||||
* user to ensure that all property values are converted to the
|
||||
* expected type before usage.
|
||||
*/
|
||||
|
||||
var undef;
|
||||
|
||||
// NOTE: we cannot assume that the passed properties are case-correct
|
||||
// (esp due to some browser bugs). Therefore, we attempt to locate
|
||||
// properties for assignment regardless of case. This may cause
|
||||
// problematic assignments and bugs in the future and will need to be
|
||||
// documented with big bright neon lights.
|
||||
|
||||
// FIXME: fails miserably if a mixin property has a default value of null in
|
||||
// a widget
|
||||
|
||||
// NOTE: caching lower-cased args in the prototype is only
|
||||
// acceptable if the properties are invariant.
|
||||
// if we have a name-cache, get it
|
||||
var lcArgs = dojo.widget.lcArgsCache[this.widgetType];
|
||||
if ( lcArgs == null ){
|
||||
// build a lower-case property name cache if we don't have one
|
||||
lcArgs = {};
|
||||
for(var y in this){
|
||||
lcArgs[((new String(y)).toLowerCase())] = y;
|
||||
}
|
||||
dojo.widget.lcArgsCache[this.widgetType] = lcArgs;
|
||||
}
|
||||
var visited = {};
|
||||
for(var x in args){
|
||||
if(!this[x]){ // check the cache for properties
|
||||
var y = lcArgs[(new String(x)).toLowerCase()];
|
||||
if(y){
|
||||
args[y] = args[x];
|
||||
x = y;
|
||||
}
|
||||
}
|
||||
if(visited[x]){ continue; }
|
||||
visited[x] = true;
|
||||
if((typeof this[x]) != (typeof undef)){
|
||||
if(typeof args[x] != "string"){
|
||||
this[x] = args[x];
|
||||
}else{
|
||||
if(dojo.lang.isString(this[x])){
|
||||
this[x] = args[x];
|
||||
}else if(dojo.lang.isNumber(this[x])){
|
||||
this[x] = new Number(args[x]); // FIXME: what if NaN is the result?
|
||||
}else if(dojo.lang.isBoolean(this[x])){
|
||||
this[x] = (args[x].toLowerCase()=="false") ? false : true;
|
||||
}else if(dojo.lang.isFunction(this[x])){
|
||||
|
||||
// FIXME: need to determine if always over-writing instead
|
||||
// of attaching here is appropriate. I suspect that we
|
||||
// might want to only allow attaching w/ action items.
|
||||
|
||||
// RAR, 1/19/05: I'm going to attach instead of
|
||||
// over-write here. Perhaps function objects could have
|
||||
// some sort of flag set on them? Or mixed-into objects
|
||||
// could have some list of non-mutable properties
|
||||
// (although I'm not sure how that would alleviate this
|
||||
// particular problem)?
|
||||
|
||||
// this[x] = new Function(args[x]);
|
||||
|
||||
// after an IRC discussion last week, it was decided
|
||||
// that these event handlers should execute in the
|
||||
// context of the widget, so that the "this" pointer
|
||||
// takes correctly.
|
||||
|
||||
// argument that contains no punctuation other than . is
|
||||
// considered a function spec, not code
|
||||
if(args[x].search(/[^\w\.]+/i) == -1){
|
||||
this[x] = dojo.evalObjPath(args[x], false);
|
||||
}else{
|
||||
var tn = dojo.lang.nameAnonFunc(new Function(args[x]), this);
|
||||
dojo.event.connect(this, x, this, tn);
|
||||
}
|
||||
}else if(dojo.lang.isArray(this[x])){ // typeof [] == "object"
|
||||
this[x] = args[x].split(";");
|
||||
} else if (this[x] instanceof Date) {
|
||||
this[x] = new Date(Number(args[x])); // assume timestamp
|
||||
}else if(typeof this[x] == "object"){
|
||||
// FIXME: should we be allowing extension here to handle
|
||||
// other object types intelligently?
|
||||
|
||||
// if we defined a URI, we probablt want to allow plain strings
|
||||
// to override it
|
||||
if (this[x] instanceof dojo.uri.Uri){
|
||||
|
||||
this[x] = args[x];
|
||||
}else{
|
||||
|
||||
// FIXME: unlike all other types, we do not replace the
|
||||
// object with a new one here. Should we change that?
|
||||
var pairs = args[x].split(";");
|
||||
for(var y=0; y<pairs.length; y++){
|
||||
var si = pairs[y].indexOf(":");
|
||||
if((si != -1)&&(pairs[y].length>si)){
|
||||
this[x][pairs[y].substr(0, si).replace(/^\s+|\s+$/g, "")] = pairs[y].substr(si+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
// the default is straight-up string assignment. When would
|
||||
// we ever hit this?
|
||||
this[x] = args[x];
|
||||
}
|
||||
}
|
||||
}else{
|
||||
// collect any extra 'non mixed in' args
|
||||
this.extraArgs[x.toLowerCase()] = args[x];
|
||||
}
|
||||
}
|
||||
// dojo.profile.end("mixInProperties");
|
||||
},
|
||||
|
||||
postMixInProperties: function(){
|
||||
},
|
||||
|
||||
initialize: function(args, frag){
|
||||
// dojo.unimplemented("dojo.widget.Widget.initialize");
|
||||
return false;
|
||||
},
|
||||
|
||||
postInitialize: function(args, frag){
|
||||
return false;
|
||||
},
|
||||
|
||||
postCreate: function(args, frag){
|
||||
return false;
|
||||
},
|
||||
|
||||
uninitialize: function(){
|
||||
// dojo.unimplemented("dojo.widget.Widget.uninitialize");
|
||||
return false;
|
||||
},
|
||||
|
||||
buildRendering: function(){
|
||||
// SUBCLASSES MUST IMPLEMENT
|
||||
dojo.unimplemented("dojo.widget.Widget.buildRendering, on "+this.toString()+", ");
|
||||
return false;
|
||||
},
|
||||
|
||||
destroyRendering: function(){
|
||||
// SUBCLASSES MUST IMPLEMENT
|
||||
dojo.unimplemented("dojo.widget.Widget.destroyRendering");
|
||||
return false;
|
||||
},
|
||||
|
||||
cleanUp: function(){
|
||||
// SUBCLASSES MUST IMPLEMENT
|
||||
dojo.unimplemented("dojo.widget.Widget.cleanUp");
|
||||
return false;
|
||||
},
|
||||
|
||||
addedTo: function(parent){
|
||||
// this is just a signal that can be caught
|
||||
},
|
||||
|
||||
addChild: function(child){
|
||||
// SUBCLASSES MUST IMPLEMENT
|
||||
dojo.unimplemented("dojo.widget.Widget.addChild");
|
||||
return false;
|
||||
},
|
||||
|
||||
// Detach the given child widget from me, but don't destroy it
|
||||
removeChild: function(widget){
|
||||
for(var x=0; x<this.children.length; x++){
|
||||
if(this.children[x] === widget){
|
||||
this.children.splice(x, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return widget;
|
||||
},
|
||||
|
||||
resize: function(width, height){
|
||||
// both width and height may be set as percentages. The setWidth and
|
||||
// setHeight functions attempt to determine if the passed param is
|
||||
// specified in percentage or native units. Integers without a
|
||||
// measurement are assumed to be in the native unit of measure.
|
||||
this.setWidth(width);
|
||||
this.setHeight(height);
|
||||
},
|
||||
|
||||
setWidth: function(width){
|
||||
if((typeof width == "string")&&(width.substr(-1) == "%")){
|
||||
this.setPercentageWidth(width);
|
||||
}else{
|
||||
this.setNativeWidth(width);
|
||||
}
|
||||
},
|
||||
|
||||
setHeight: function(height){
|
||||
if((typeof height == "string")&&(height.substr(-1) == "%")){
|
||||
this.setPercentageHeight(height);
|
||||
}else{
|
||||
this.setNativeHeight(height);
|
||||
}
|
||||
},
|
||||
|
||||
setPercentageHeight: function(height){
|
||||
// SUBCLASSES MUST IMPLEMENT
|
||||
return false;
|
||||
},
|
||||
|
||||
setNativeHeight: function(height){
|
||||
// SUBCLASSES MUST IMPLEMENT
|
||||
return false;
|
||||
},
|
||||
|
||||
setPercentageWidth: function(width){
|
||||
// SUBCLASSES MUST IMPLEMENT
|
||||
return false;
|
||||
},
|
||||
|
||||
setNativeWidth: function(width){
|
||||
// SUBCLASSES MUST IMPLEMENT
|
||||
return false;
|
||||
},
|
||||
|
||||
getPreviousSibling: function() {
|
||||
var idx = this.getParentIndex();
|
||||
|
||||
// first node is idx=0 not found is idx<0
|
||||
if (idx<=0) return null;
|
||||
|
||||
return this.getSiblings()[idx-1];
|
||||
},
|
||||
|
||||
getSiblings: function() {
|
||||
return this.parent.children;
|
||||
},
|
||||
|
||||
getParentIndex: function() {
|
||||
return dojo.lang.indexOf( this.getSiblings(), this, true);
|
||||
},
|
||||
|
||||
getNextSibling: function() {
|
||||
|
||||
var idx = this.getParentIndex();
|
||||
|
||||
if (idx == this.getSiblings().length-1) return null; // last node
|
||||
if (idx < 0) return null; // not found
|
||||
|
||||
return this.getSiblings()[idx+1];
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// Lower case name cache: listing of the lower case elements in each widget.
|
||||
// We can't store the lcArgs in the widget itself because if B subclasses A,
|
||||
// then B.prototype.lcArgs might return A.prototype.lcArgs, which is not what we
|
||||
// want
|
||||
dojo.widget.lcArgsCache = {};
|
||||
|
||||
// TODO: should have a more general way to add tags or tag libraries?
|
||||
// TODO: need a default tags class to inherit from for things like getting propertySets
|
||||
// TODO: parse properties/propertySets into component attributes
|
||||
// TODO: parse subcomponents
|
||||
// TODO: copy/clone raw markup fragments/nodes as appropriate
|
||||
dojo.widget.tags = {};
|
||||
dojo.widget.tags.addParseTreeHandler = function(type){
|
||||
var ltype = type.toLowerCase();
|
||||
this[ltype] = function(fragment, widgetParser, parentComp, insertionIndex, localProps){
|
||||
return dojo.widget.buildWidgetFromParseTree(ltype, fragment, widgetParser, parentComp, insertionIndex, localProps);
|
||||
}
|
||||
}
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:widget");
|
||||
|
||||
dojo.widget.tags["dojo:propertyset"] = function(fragment, widgetParser, parentComp){
|
||||
// FIXME: Is this needed?
|
||||
// FIXME: Not sure that this parses into the structure that I want it to parse into...
|
||||
// FIXME: add support for nested propertySets
|
||||
var properties = widgetParser.parseProperties(fragment["dojo:propertyset"]);
|
||||
}
|
||||
|
||||
// FIXME: need to add the <dojo:connect />
|
||||
dojo.widget.tags["dojo:connect"] = function(fragment, widgetParser, parentComp){
|
||||
var properties = widgetParser.parseProperties(fragment["dojo:connect"]);
|
||||
}
|
||||
|
||||
// FIXME: if we know the insertion point (to a reasonable location), why then do we:
|
||||
// - create a template node
|
||||
// - clone the template node
|
||||
// - render the clone and set properties
|
||||
// - remove the clone from the render tree
|
||||
// - place the clone
|
||||
// this is quite dumb
|
||||
dojo.widget.buildWidgetFromParseTree = function(type, frag,
|
||||
parser, parentComp,
|
||||
insertionIndex, localProps){
|
||||
var stype = type.split(":");
|
||||
stype = (stype.length == 2) ? stype[1] : type;
|
||||
// FIXME: we don't seem to be doing anything with this!
|
||||
// var propertySets = parser.getPropertySets(frag);
|
||||
var localProperties = localProps || parser.parseProperties(frag["dojo:"+stype]);
|
||||
// var tic = new Date();
|
||||
var twidget = dojo.widget.manager.getImplementation(stype);
|
||||
if(!twidget){
|
||||
throw new Error("cannot find \"" + stype + "\" widget");
|
||||
}else if (!twidget.create){
|
||||
throw new Error("\"" + stype + "\" widget object does not appear to implement *Widget");
|
||||
}
|
||||
localProperties["dojoinsertionindex"] = insertionIndex;
|
||||
// FIXME: we loose no less than 5ms in construction!
|
||||
var ret = twidget.create(localProperties, frag, parentComp);
|
||||
// dojo.debug(new Date() - tic);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a widget constructor function (aka widgetClass)
|
||||
*/
|
||||
dojo.widget.defineWidget = function(widgetClass /*string*/, renderer /*string*/, superclasses /*function||array*/, init /*function*/, props /*object*/){
|
||||
// This meta-function does parameter juggling for backward compat and overloading
|
||||
// if 4th argument is a string, we are using the old syntax
|
||||
// old sig: widgetClass, superclasses, props (object), renderer (string), init (function)
|
||||
if(dojo.lang.isString(arguments[3])){
|
||||
dojo.widget._defineWidget(arguments[0], arguments[3], arguments[1], arguments[4], arguments[2]);
|
||||
}else{
|
||||
// widgetClass
|
||||
var args = [ arguments[0] ], p = 3;
|
||||
if(dojo.lang.isString(arguments[1])){
|
||||
// renderer, superclass
|
||||
args.push(arguments[1], arguments[2]);
|
||||
}else{
|
||||
// superclass
|
||||
args.push('', arguments[1]);
|
||||
p = 2;
|
||||
}
|
||||
if(dojo.lang.isFunction(arguments[p])){
|
||||
// init (function), props (object)
|
||||
args.push(arguments[p], arguments[p+1]);
|
||||
}else{
|
||||
// props (object)
|
||||
args.push(null, arguments[p]);
|
||||
}
|
||||
dojo.widget._defineWidget.apply(this, args);
|
||||
}
|
||||
}
|
||||
|
||||
dojo.widget.defineWidget.renderers = "html|svg|vml";
|
||||
|
||||
dojo.widget._defineWidget = function(widgetClass /*string*/, renderer /*string*/, superclasses /*function||array*/, init /*function*/, props /*object*/){
|
||||
// FIXME: uncomment next line to test parameter juggling ... remove when confidence improves
|
||||
//dojo.debug('(c:)' + widgetClass + '\n\n(r:)' + renderer + '\n\n(i:)' + init + '\n\n(p:)' + props);
|
||||
// widgetClass takes the form foo.bar.baz<.renderer>.WidgetName (e.g. foo.bar.baz.WidgetName or foo.bar.baz.html.WidgetName)
|
||||
var namespace = widgetClass.split(".");
|
||||
var type = namespace.pop(); // type <= WidgetName, namespace <= foo.bar.baz<.renderer>
|
||||
var regx = "\\.(" + (renderer ? renderer + '|' : '') + dojo.widget.defineWidget.renderers + ")\\.";
|
||||
var r = widgetClass.search(new RegExp(regx));
|
||||
namespace = (r < 0 ? namespace.join(".") : widgetClass.substr(0, r));
|
||||
|
||||
dojo.widget.manager.registerWidgetPackage(namespace);
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:"+type.toLowerCase());
|
||||
|
||||
props=(props)||{};
|
||||
props.widgetType = type;
|
||||
if((!init)&&(props["classConstructor"])){
|
||||
init = props.classConstructor;
|
||||
delete props.classConstructor;
|
||||
}
|
||||
dojo.declare(widgetClass, superclasses, init, props);
|
||||
}
|
210
webapp/web/src/widget/Wizard.js
Normal file
210
webapp/web/src/widget/Wizard.js
Normal file
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Wizard");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.LayoutContainer");
|
||||
dojo.require("dojo.widget.ContentPane");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.style");
|
||||
|
||||
//////////////////////////////////////////
|
||||
// WizardContainer -- a set of panels
|
||||
//////////////////////////////////////////
|
||||
dojo.widget.WizardContainer = function() {
|
||||
dojo.widget.html.LayoutContainer.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.WizardContainer, dojo.widget.html.LayoutContainer);
|
||||
|
||||
dojo.lang.extend(dojo.widget.WizardContainer, {
|
||||
|
||||
widgetType: "WizardContainer",
|
||||
|
||||
labelPosition: "top",
|
||||
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/Wizard.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/Wizard.css"),
|
||||
|
||||
selected: null, // currently selected panel
|
||||
wizardNode: null, // the outer wizard node
|
||||
wizardPanelContainerNode: null, // the container for the panels
|
||||
wizardControlContainerNode: null, // the container for the wizard controls
|
||||
previousButton: null, // the previous button
|
||||
nextButton: null, // the next button
|
||||
cancelButton: null, // the cancel button
|
||||
doneButton: null, // the done button
|
||||
nextButtonLabel: "next",
|
||||
previousButtonLabel: "previous",
|
||||
cancelButtonLabel: "cancel",
|
||||
doneButtonLabel: "done",
|
||||
cancelFunction : "",
|
||||
|
||||
hideDisabledButtons: false,
|
||||
|
||||
fillInTemplate: function(args, frag){
|
||||
dojo.event.connect(this.nextButton, "onclick", this, "nextPanel");
|
||||
dojo.event.connect(this.previousButton, "onclick", this, "previousPanel");
|
||||
if (this.cancelFunction){
|
||||
dojo.event.connect(this.cancelButton, "onclick", this.cancelFunction);
|
||||
}else{
|
||||
this.cancelButton.style.display = "none";
|
||||
}
|
||||
dojo.event.connect(this.doneButton, "onclick", this, "done");
|
||||
this.nextButton.value = this.nextButtonLabel;
|
||||
this.previousButton.value = this.previousButtonLabel;
|
||||
this.cancelButton.value = this.cancelButtonLabel;
|
||||
this.doneButton.value = this.doneButtonLabel;
|
||||
},
|
||||
|
||||
checkButtons: function(){
|
||||
var lastStep = !this.hasNextPanel();
|
||||
this.nextButton.disabled = lastStep;
|
||||
this.setButtonClass(this.nextButton);
|
||||
if(this.selected.doneFunction){
|
||||
this.doneButton.style.display = "";
|
||||
// hide the next button if this is the last one and we have a done function
|
||||
if(lastStep){
|
||||
this.nextButton.style.display = "none";
|
||||
}
|
||||
}else{
|
||||
this.doneButton.style.display = "none";
|
||||
}
|
||||
this.previousButton.disabled = ((!this.hasPreviousPanel()) || (!this.selected.canGoBack));
|
||||
this.setButtonClass(this.previousButton);
|
||||
},
|
||||
|
||||
setButtonClass: function(button){
|
||||
if(!this.hideDisabledButtons){
|
||||
button.style.display = "";
|
||||
dojo.html.setClass(button, button.disabled ? "WizardButtonDisabled" : "WizardButton");
|
||||
}else{
|
||||
button.style.display = button.disabled ? "none" : "";
|
||||
}
|
||||
},
|
||||
|
||||
registerChild: function(panel, insertionIndex){
|
||||
dojo.widget.WizardContainer.superclass.registerChild.call(this, panel, insertionIndex);
|
||||
this.wizardPanelContainerNode.appendChild(panel.domNode);
|
||||
panel.hide();
|
||||
|
||||
if(!this.selected){
|
||||
this.onSelected(panel);
|
||||
}
|
||||
this.checkButtons();
|
||||
},
|
||||
|
||||
onSelected: function(panel){
|
||||
// Deselect old panel and select new one
|
||||
if(this.selected ){
|
||||
if (this.selected.checkPass()) {
|
||||
this.selected.hide();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
panel.show();
|
||||
this.selected = panel;
|
||||
},
|
||||
|
||||
getPanels: function() {
|
||||
return this.getChildrenOfType("WizardPane", false);
|
||||
},
|
||||
|
||||
selectedIndex: function() {
|
||||
if (this.selected) {
|
||||
return dojo.lang.indexOf(this.getPanels(), this.selected);
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
|
||||
nextPanel: function() {
|
||||
var selectedIndex = this.selectedIndex();
|
||||
if ( selectedIndex > -1 ) {
|
||||
var childPanels = this.getPanels();
|
||||
if (childPanels[selectedIndex + 1]) {
|
||||
this.onSelected(childPanels[selectedIndex + 1]);
|
||||
}
|
||||
}
|
||||
this.checkButtons();
|
||||
},
|
||||
|
||||
previousPanel: function() {
|
||||
var selectedIndex = this.selectedIndex();
|
||||
if ( selectedIndex > -1 ) {
|
||||
var childPanels = this.getPanels();
|
||||
if (childPanels[selectedIndex - 1]) {
|
||||
this.onSelected(childPanels[selectedIndex - 1]);
|
||||
}
|
||||
}
|
||||
this.checkButtons();
|
||||
},
|
||||
|
||||
hasNextPanel: function() {
|
||||
var selectedIndex = this.selectedIndex();
|
||||
return (selectedIndex < (this.getPanels().length - 1));
|
||||
},
|
||||
|
||||
hasPreviousPanel: function() {
|
||||
var selectedIndex = this.selectedIndex();
|
||||
return (selectedIndex > 0);
|
||||
},
|
||||
|
||||
done: function() {
|
||||
this.selected.done();
|
||||
}
|
||||
});
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:WizardContainer");
|
||||
|
||||
//////////////////////////////////////////
|
||||
// WizardPane -- a panel in a wizard
|
||||
//////////////////////////////////////////
|
||||
dojo.widget.WizardPane = function() {
|
||||
dojo.widget.html.ContentPane.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.WizardPane, dojo.widget.html.ContentPane);
|
||||
|
||||
dojo.lang.extend(dojo.widget.WizardPane, {
|
||||
widgetType: "WizardPane",
|
||||
|
||||
canGoBack: true,
|
||||
|
||||
passFunction: "",
|
||||
doneFunction: "",
|
||||
|
||||
fillInTemplate: function(args, frag) {
|
||||
if (this.passFunction) {
|
||||
this.passFunction = dj_global[this.passFunction];
|
||||
}
|
||||
if (this.doneFunction) {
|
||||
this.doneFunction = dj_global[this.doneFunction];
|
||||
}
|
||||
},
|
||||
|
||||
checkPass: function() {
|
||||
if (this.passFunction && dojo.lang.isFunction(this.passFunction)) {
|
||||
var failMessage = this.passFunction();
|
||||
if (failMessage) {
|
||||
alert(failMessage);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
done: function() {
|
||||
if (this.doneFunction && dojo.lang.isFunction(this.doneFunction)) {
|
||||
this.doneFunction();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:WizardPane");
|
27
webapp/web/src/widget/YahooMap.js
Normal file
27
webapp/web/src/widget/YahooMap.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.YahooMap");
|
||||
dojo.provide("dojo.widget.YahooMap.Controls");
|
||||
dojo.require("dojo.widget.*");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.YahooMap",
|
||||
dojo.widget.Widget,
|
||||
{ isContainer: false }
|
||||
);
|
||||
|
||||
dojo.widget.YahooMap.Controls={
|
||||
MapType:"maptype",
|
||||
Pan:"pan",
|
||||
ZoomLong:"zoomlong",
|
||||
ZoomShort:"zoomshort"
|
||||
};
|
||||
dojo.requireAfterIf("html", "dojo.widget.html.YahooMap");
|
23
webapp/web/src/widget/__package__.js
Normal file
23
webapp/web/src/widget/__package__.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.kwCompoundRequire({
|
||||
common: ["dojo.xml.Parse",
|
||||
"dojo.widget.Widget",
|
||||
"dojo.widget.Parse",
|
||||
"dojo.widget.Manager"],
|
||||
browser: ["dojo.widget.DomWidget",
|
||||
"dojo.widget.HtmlWidget"],
|
||||
dashboard: ["dojo.widget.DomWidget",
|
||||
"dojo.widget.HtmlWidget"],
|
||||
svg: ["dojo.widget.SvgWidget"],
|
||||
rhino: ["dojo.widget.SwtWidget"]
|
||||
});
|
||||
dojo.provide("dojo.widget.*");
|
107
webapp/web/src/widget/demoEngine/DemoContainer.js
Normal file
107
webapp/web/src/widget/demoEngine/DemoContainer.js
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.demoEngine.DemoContainer");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.widget.demoEngine.DemoPane");
|
||||
dojo.require("dojo.widget.demoEngine.SourcePane");
|
||||
dojo.require("dojo.widget.TabContainer");
|
||||
|
||||
dojo.widget.defineWidget("my.widget.demoEngine.DemoContainer",
|
||||
dojo.widget.HtmlWidget,
|
||||
{
|
||||
templatePath: dojo.uri.dojoUri("src/widget/demoEngine/templates/DemoContainer.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/demoEngine/templates/DemoContainer.css"),
|
||||
postCreate: function() {
|
||||
dojo.html.addClass(this.domNode,this.domNodeClass);
|
||||
dojo.html.addClass(this.tabNode, this.tabClass);
|
||||
dojo.html.addClass(this.returnImageNode, this.returnClass);
|
||||
this.returnImageNode.src=this.returnImage;
|
||||
|
||||
this.tabContainer = dojo.widget.createWidget("TabContainer",{},this.tabNode);
|
||||
|
||||
this.demoTab = dojo.widget.createWidget("DemoPane",{});
|
||||
this.tabContainer.addChild(this.demoTab);
|
||||
|
||||
this.sourceTab= dojo.widget.createWidget("SourcePane",{});
|
||||
this.tabContainer.addChild(this.sourceTab);
|
||||
|
||||
dojo.html.setOpacity(this.domNode,0);
|
||||
dojo.html.hide(this.domNode);
|
||||
},
|
||||
|
||||
loadDemo: function(url) {
|
||||
this.demoTab.setHref(url);
|
||||
this.sourceTab.setHref(url);
|
||||
this.showDemo();
|
||||
},
|
||||
|
||||
setName: function(name) {
|
||||
dojo.html.removeChildren(this.demoNameNode);
|
||||
this.demoNameNode.appendChild(document.createTextNode(name));
|
||||
},
|
||||
|
||||
setSummary: function(summary) {
|
||||
dojo.html.removeChildren(this.summaryNode);
|
||||
this.summaryNode.appendChild(document.createTextNode(summary));
|
||||
},
|
||||
|
||||
showSource: function() {
|
||||
dojo.html.removeClass(this.demoButtonNode,this.selectedButtonClass);
|
||||
dojo.html.addClass(this.sourceButtonNode,this.selectedButtonClass);
|
||||
this.tabContainer.selectTab(this.sourceTab);
|
||||
},
|
||||
|
||||
showDemo: function() {
|
||||
dojo.html.removeClass(this.sourceButtonNode,this.selectedButtonClass);
|
||||
dojo.html.addClass(this.demoButtonNode,this.selectedButtonClass);
|
||||
this.tabContainer.selectTab(this.demoTab);
|
||||
},
|
||||
|
||||
returnToDemos: function() {
|
||||
dojo.debug("Return To Demos");
|
||||
},
|
||||
|
||||
show: function() {
|
||||
dojo.html.setOpacity(this.domNode,1);
|
||||
dojo.html.show(this.domNode);
|
||||
this.tabContainer.checkSize();
|
||||
}
|
||||
},
|
||||
"",
|
||||
function() {
|
||||
dojo.debug("DemoPane Init");
|
||||
this.domNodeClass="demoContainer";
|
||||
|
||||
this.tabContainer="";
|
||||
this.sourceTab="";
|
||||
this.demoTab="";
|
||||
|
||||
this.headerNode="";
|
||||
this.returnNode="";
|
||||
|
||||
this.returnImageNode="";
|
||||
this.returnImage="images/dojoDemos.gif";
|
||||
this.returnClass="return";
|
||||
|
||||
this.summaryNode="";
|
||||
this.demoNameNode="";
|
||||
this.tabControlNode="";
|
||||
|
||||
this.tabNode="";
|
||||
this.tabClass = "demoContainerTabs";
|
||||
|
||||
this.sourceButtonNode="";
|
||||
this.demoButtonNode="";
|
||||
|
||||
this.selectedButtonClass="selected";
|
||||
}
|
||||
);
|
71
webapp/web/src/widget/demoEngine/DemoItem.js
Normal file
71
webapp/web/src/widget/demoEngine/DemoItem.js
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.demoEngine.DemoItem");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
|
||||
dojo.widget.defineWidget("my.widget.demoEngine.DemoItem",
|
||||
dojo.widget.HtmlWidget,
|
||||
{
|
||||
templatePath: dojo.uri.dojoUri("src/widget/demoEngine/templates/DemoItem.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/demoEngine/templates/DemoItem.css"),
|
||||
postCreate: function() {
|
||||
dojo.html.addClass(this.domNode,this.domNodeClass);
|
||||
dojo.html.addClass(this.summaryBoxNode, this.summaryBoxClass);
|
||||
dojo.html.addClass(this.screenshotTdNode, this.screenshotTdClass);
|
||||
dojo.html.addClass(this.summaryContainerNode, this.summaryContainerClass);
|
||||
dojo.html.addClass(this.summaryNode, this.summaryClass);
|
||||
dojo.html.addClass(this.viewDemoLinkNode, this.viewDemoLinkClass);
|
||||
|
||||
this.nameNode.appendChild(document.createTextNode(this.name));
|
||||
this.descriptionNode.appendChild(document.createTextNode(this.description));
|
||||
this.thumbnailImageNode.src = this.thumbnail;
|
||||
this.thumbnailImageNode.name=this.name;
|
||||
this.viewDemoImageNode.src = this.viewDemoImage;
|
||||
this.viewDemoImageNode.name=this.name;
|
||||
},
|
||||
onSelectDemo: function() {
|
||||
//Attach to this to do something when a demo is selected
|
||||
}
|
||||
},
|
||||
"",
|
||||
function() {
|
||||
this.demo = "";
|
||||
|
||||
this.domNodeClass="demoItemWrapper";
|
||||
|
||||
this.summaryBoxNode="";
|
||||
this.summaryBoxClass="demoItemSummaryBox";
|
||||
|
||||
this.nameNode="";
|
||||
this.thumbnailImageNode="";
|
||||
this.viewDemoImageNode="";
|
||||
|
||||
this.screenshotTdNode="";
|
||||
this.screenshotTdClass="demoItemScreenshot";
|
||||
|
||||
this.summaryContainerNode="";
|
||||
this.summaryContainerClass="demoItemSummaryContainer";
|
||||
|
||||
this.summaryNode="";
|
||||
this.summaryClass="demoItemSummary";
|
||||
|
||||
this.viewDemoLinkNode="";
|
||||
this.viewDemoLinkClass="demoItemView";
|
||||
|
||||
this.descriptionNode="";
|
||||
|
||||
this.name="Some Demo";
|
||||
this.description="This is the description of this demo.";
|
||||
this.thumbnail="images/test_thumb.gif";
|
||||
this.viewDemoImage="images/viewDemo.png";
|
||||
}
|
||||
);
|
188
webapp/web/src/widget/demoEngine/DemoNavigator.js
Normal file
188
webapp/web/src/widget/demoEngine/DemoNavigator.js
Normal file
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.demoEngine.DemoNavigator");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.widget.Button");
|
||||
dojo.require("dojo.widget.demoEngine.DemoItem");
|
||||
dojo.require("dojo.io.*");
|
||||
dojo.require("dojo.lfx.*");
|
||||
dojo.require("dojo.lang.Common");
|
||||
|
||||
dojo.widget.defineWidget("my.widget.demoEngine.DemoNavigator",
|
||||
dojo.widget.HtmlWidget,
|
||||
{
|
||||
templatePath: dojo.uri.dojoUri("src/widget/demoEngine/templates/DemoNavigator.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/demoEngine/templates/DemoNavigator.css"),
|
||||
postCreate: function() {
|
||||
dojo.html.addClass(this.domNode,this.domNodeClass);
|
||||
dojo.html.addClass(this.demoListWrapperNode,this.demoListWrapperClass);
|
||||
dojo.html.addClass(this.demoListContainerNode,this.demoListContainerClass);
|
||||
|
||||
if (dojo.render.html.ie) {
|
||||
dojo.debug("render ie");
|
||||
dojo.html.hide(this.demoListWrapperNode);
|
||||
} else {
|
||||
dojo.debug("render non-ie");
|
||||
dojo.lfx.html.fadeHide(this.demoListWrapperNode, 0).play();
|
||||
}
|
||||
|
||||
this.getRegistry(this.demoRegistryUrl);
|
||||
|
||||
this.demoContainer = dojo.widget.createWidget("DemoContainer",{returnImage: this.returnImage},this.demoNode);
|
||||
dojo.event.connect(this.demoContainer,"returnToDemos", this, "returnToDemos");
|
||||
this.demoContainer.hide();
|
||||
},
|
||||
|
||||
returnToDemos: function() {
|
||||
this.demoContainer.hide();
|
||||
if (dojo.render.html.ie) {
|
||||
dojo.debug("render ie");
|
||||
dojo.html.show(this.navigationContainer) ;
|
||||
} else {
|
||||
dojo.debug("render non-ie");
|
||||
dojo.lfx.html.fadeShow(this.navigationContainer,250).play();
|
||||
}
|
||||
|
||||
//if (dojo.render.html.ie) {
|
||||
// dojo.html.setOpacity(this.navigationContainer);
|
||||
//}
|
||||
|
||||
dojo.lang.forEach(this.categoriesChildren, dojo.lang.hitch(this, function(child){
|
||||
child.checkSize();
|
||||
}));
|
||||
|
||||
dojo.lang.forEach(this.demoListChildren, dojo.lang.hitch(this, function(child){
|
||||
child.checkSize();
|
||||
}));
|
||||
},
|
||||
|
||||
show: function() {
|
||||
//dojo.widget.demoEngine.DemoNavigator.superclass.show.call(this);
|
||||
dojo.html.show(this.domNode);
|
||||
dojo.html.setOpacity(this.domNode,1);
|
||||
//dojo.html.setOpacity(this.navigationContainer);
|
||||
//dojo.html.show(this.navigationContainer);
|
||||
dojo.html.setOpacity(this.navigationContainer,1);
|
||||
|
||||
dojo.lang.forEach(this.categoriesChildren, dojo.lang.hitch(this, function(child){
|
||||
child.checkSize();
|
||||
}));
|
||||
|
||||
dojo.lang.forEach(this.demoListChildren, dojo.lang.hitch(this, function(child){
|
||||
child.checkSize();
|
||||
}));
|
||||
},
|
||||
getRegistry: function(url) {
|
||||
dojo.io.bind({
|
||||
url: url,
|
||||
load: dojo.lang.hitch(this,this.processRegistry),
|
||||
mimetype: "text/json"
|
||||
});
|
||||
},
|
||||
|
||||
processRegistry: function(type,registry,e) {
|
||||
dojo.debug("Processing Registry");
|
||||
this.registry = registry;
|
||||
dojo.lang.forEach(this.registry.navigation, dojo.lang.hitch(this,this.addCategory));
|
||||
},
|
||||
|
||||
addCategory: function(category) {
|
||||
var newCat = dojo.widget.createWidget("Button",{caption: category.name});
|
||||
|
||||
if(!dojo.lang.isObject(this.registry.categories)) {
|
||||
this.registry.categories=function(){};
|
||||
}
|
||||
|
||||
this.registry.categories[category.name] = category;
|
||||
this.categoriesChildren.push(newCat);
|
||||
this.categoriesButtonsNode.appendChild(newCat.domNode);
|
||||
newCat.domNode.categoryName = category.name;
|
||||
dojo.event.connect(newCat,"onClick", this, "onSelectCategory");
|
||||
},
|
||||
|
||||
addDemo: function(demoName) {
|
||||
var demo = this.registry.definitions[demoName];
|
||||
|
||||
if (dojo.render.html.ie) {
|
||||
dojo.html.show(this.demoListWrapperNode)
|
||||
} else {
|
||||
dojo.lfx.html.fadeShow(this.demoListWrapperNode, 250).play();
|
||||
}
|
||||
|
||||
var newDemo = dojo.widget.createWidget("DemoItem",{viewDemoImage: this.viewDemoImage, name: demoName, description: demo.description, thumbnail: demo.thumbnail});
|
||||
this.demoListChildren.push(newDemo);
|
||||
this.demoListContainerNode.appendChild(newDemo.domNode);
|
||||
dojo.event.connect(newDemo,"onSelectDemo",this,"onSelectDemo");
|
||||
},
|
||||
|
||||
onSelectCategory: function(e) {
|
||||
catName = e.currentTarget.categoryName;
|
||||
dojo.debug("Selected Category: " + catName);
|
||||
//Remove current list of demos
|
||||
dojo.lang.forEach(this.demoListChildren, function(child) {
|
||||
child.destroy();
|
||||
});
|
||||
this.demoListChildren=[];
|
||||
|
||||
//add demos from this cat
|
||||
dojo.lang.forEach(this.registry.categories[catName].demos, dojo.lang.hitch(this,function(demoName){
|
||||
this.addDemo(demoName);
|
||||
}));
|
||||
},
|
||||
|
||||
onSelectDemo: function(e) {
|
||||
//Attach to this to do something when a demo is selected
|
||||
dojo.debug("Demo Selected: " + e.target.name);
|
||||
|
||||
if (dojo.render.html.ie) {
|
||||
dojo.debug("render ie");
|
||||
dojo.html.hide(this.navigationContainer) ;
|
||||
this.demoContainer.show();
|
||||
this.demoContainer.showDemo();
|
||||
} else {
|
||||
dojo.debug("render non-ie");
|
||||
dojo.lfx.html.fadeHide(this.navigationContainer,250,null,dojo.lang.hitch(this, function() {
|
||||
this.demoContainer.show();
|
||||
this.demoContainer.showDemo();
|
||||
})).play();
|
||||
}
|
||||
|
||||
this.demoContainer.loadDemo(this.registry.definitions[e.target.name].url);
|
||||
this.demoContainer.setName(e.target.name);
|
||||
this.demoContainer.setSummary(this.registry.definitions[e.target.name].description);
|
||||
}
|
||||
|
||||
},
|
||||
"",
|
||||
function() {
|
||||
this.demoRegistryUrl="demoRegistry.json";
|
||||
this.registry=function(){};
|
||||
|
||||
this.categoriesNode="";
|
||||
this.categoriesButtonsNode="";
|
||||
this.navigationContainer="";
|
||||
|
||||
this.domNodeClass="demoNavigator";
|
||||
|
||||
this.demoNode="";
|
||||
this.demoContainer="";
|
||||
|
||||
this.demoListWrapperNode="";
|
||||
this.demoListWrapperClass="demoNavigatorListWrapper";
|
||||
this.demoListContainerClass="demoNavigatorListContainer";
|
||||
|
||||
this.returnImage="images/dojoDemos.gif";
|
||||
this.viewDemoImage="images/viewDemo.png";
|
||||
this.demoListChildren = [];
|
||||
this.categoriesChildren = [];
|
||||
}
|
||||
);
|
44
webapp/web/src/widget/demoEngine/DemoPane.js
Normal file
44
webapp/web/src/widget/demoEngine/DemoPane.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.demoEngine.DemoPane");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
|
||||
dojo.widget.defineWidget("my.widget.demoEngine.DemoPane",
|
||||
dojo.widget.HtmlWidget,
|
||||
{
|
||||
templatePath: dojo.uri.dojoUri("src/widget/demoEngine/templates/DemoPane.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/demoEngine/templates/DemoPane.css"),
|
||||
postCreate: function() {
|
||||
dojo.html.addClass(this.domNode,this.domNodeClass);
|
||||
dojo.debug("PostCreate");
|
||||
this._launchDemo();
|
||||
},
|
||||
|
||||
_launchDemo: function() {
|
||||
dojo.debug("Launching Demo");
|
||||
dojo.debug(this.demoNode);
|
||||
this.demoNode.src=this.href;
|
||||
},
|
||||
|
||||
setHref: function(url) {
|
||||
this.href = url;
|
||||
this._launchDemo();
|
||||
}
|
||||
},
|
||||
"",
|
||||
function() {
|
||||
dojo.debug("DemoPane Init");
|
||||
this.domNodeClass="demoPane";
|
||||
this.demoNode = "";
|
||||
this.href = "";
|
||||
}
|
||||
);
|
52
webapp/web/src/widget/demoEngine/SourcePane.js
Normal file
52
webapp/web/src/widget/demoEngine/SourcePane.js
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.demoEngine.SourcePane");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.io.*");
|
||||
|
||||
dojo.widget.defineWidget("my.widget.demoEngine.SourcePane",
|
||||
dojo.widget.HtmlWidget,
|
||||
{
|
||||
templatePath: dojo.uri.dojoUri("src/widget/demoEngine/templates/SourcePane.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/demoEngine/templates/SourcePane.css"),
|
||||
postCreate: function() {
|
||||
dojo.html.addClass(this.domNode,this.domNodeClass);
|
||||
dojo.debug("PostCreate");
|
||||
},
|
||||
|
||||
getSource: function() {
|
||||
if (this.href) {
|
||||
dojo.io.bind({
|
||||
url: this.href,
|
||||
load: dojo.lang.hitch(this, "fillInSource"),
|
||||
mimetype: "text/plain"
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
fillInSource: function(type, source, e) {
|
||||
this.sourceNode.value=source;
|
||||
},
|
||||
|
||||
setHref: function(url) {
|
||||
this.href = url;
|
||||
this.getSource();
|
||||
}
|
||||
},
|
||||
"",
|
||||
function() {
|
||||
dojo.debug("SourcePane Init");
|
||||
this.domNodeClass="sourcePane";
|
||||
this.sourceNode = "";
|
||||
this.href = "";
|
||||
}
|
||||
);
|
20
webapp/web/src/widget/demoEngine/__package__.js
Normal file
20
webapp/web/src/widget/demoEngine/__package__.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.kwCompoundRequire({
|
||||
browser: [
|
||||
"dojo.widget.demoEngine.DemoItem",
|
||||
"dojo.widget.demoEngine.DemoNavigator",
|
||||
"dojo.widget.demoEngine.DemoPane",
|
||||
"dojo.widget.demoEngine.SourcePane",
|
||||
"dojo.widget.demoEngine.DemoContainer"
|
||||
]
|
||||
});
|
||||
dojo.provide("dojo.widget.demoEngine.*");
|
39
webapp/web/src/widget/demoEngine/templates/DemoContainer.css
Normal file
39
webapp/web/src/widget/demoEngine/templates/DemoContainer.css
Normal file
|
@ -0,0 +1,39 @@
|
|||
.demoContainer{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.demoContainer .return {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.demoContainer span {
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.demoContainer .selected {
|
||||
border-bottom: 5px solid #95bfff;
|
||||
}
|
||||
|
||||
.demoContainer table {
|
||||
background: #f5f5f5;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.demoContainerTabs {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.demoContainerTabs .dojoTabLabels-top {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.demoContainerTabs .dojoTabPaneWrapper {
|
||||
border: 0px;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<div dojoAttachPoint="domNode">
|
||||
<table width="100%" cellspacing="0" cellpadding="5">
|
||||
<tbody>
|
||||
<tr dojoAttachPoint="headerNode">
|
||||
<td dojoAttachPoint="returnNode" valign="middle" width="1%">
|
||||
<img dojoAttachPoint="returnImageNode" dojoAttachEvent="onclick: returnToDemos"/>
|
||||
</td>
|
||||
<td>
|
||||
<h1 dojoAttachPoint="demoNameNode"></h1>
|
||||
<p dojoAttachPoint="summaryNode"></p>
|
||||
</td>
|
||||
<td dojoAttachPoint="tabControlNode" valign="middle" align="right" nowrap>
|
||||
<span dojoAttachPoint="sourceButtonNode" dojoAttachEvent="onclick: showSource">source</span>
|
||||
<span dojoAttachPoint="demoButtonNode" dojoAttachEvent="onclick: showDemo">demo</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<div dojoAttachPoint="tabNode">
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
58
webapp/web/src/widget/demoEngine/templates/DemoItem.css
Normal file
58
webapp/web/src/widget/demoEngine/templates/DemoItem.css
Normal file
|
@ -0,0 +1,58 @@
|
|||
.demoItemSummaryBox {
|
||||
background: #efefef;
|
||||
border:1px solid #dae3ee;
|
||||
}
|
||||
|
||||
.demoItemScreenshot {
|
||||
padding:0.65em;
|
||||
width:175px;
|
||||
border-right:1px solid #fafafa;
|
||||
text-align:center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.demoItemWrapper{
|
||||
margin-bottom:1em;
|
||||
}
|
||||
|
||||
.demoItemWrapper a:link, .demoItemWrapper a:visited {
|
||||
color:#a6238f;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.demoItemSummaryContainer {
|
||||
border-left:1px solid #ddd;
|
||||
}
|
||||
|
||||
.demoItemSummaryContainer h1 {
|
||||
background-color:#e8e8e8;
|
||||
border-bottom: 1px solid #e6e6e6;
|
||||
color:#738fb9;
|
||||
margin:1px;
|
||||
padding:0.5em;
|
||||
font-family:"Lucida Grande", "Tahoma", serif;
|
||||
font-size:1.25em;
|
||||
font-weight:normal;
|
||||
}
|
||||
|
||||
.demoItemSummaryContainer h1 .packageSummary {
|
||||
display:block;
|
||||
color:#000;
|
||||
font-size:10px;
|
||||
margin-top:2px;
|
||||
}
|
||||
|
||||
.demoItemSummaryContainer .demoItemSummary{
|
||||
padding:1em;
|
||||
}
|
||||
|
||||
.demoItemSummaryContainer .demoItemSummary p {
|
||||
font-size:0.85em;
|
||||
padding:0;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
.demoItemView {
|
||||
text-align:right;
|
||||
cursor: pointer;
|
||||
}
|
21
webapp/web/src/widget/demoEngine/templates/DemoItem.html
Normal file
21
webapp/web/src/widget/demoEngine/templates/DemoItem.html
Normal file
|
@ -0,0 +1,21 @@
|
|||
<div dojoAttachPoint="domNode">
|
||||
<div dojoAttachPoint="summaryBoxNode">
|
||||
<table width="100%" cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td dojoAttachPoint="screenshotTdNode" valign="top" width="1%">
|
||||
<img dojoAttachPoint="thumbnailImageNode" dojoAttachEvent="onclick: onSelectDemo" />
|
||||
</td>
|
||||
<td dojoAttachPoint="summaryContainerNode" valign="top">
|
||||
<h1 dojoAttachPoint="nameNode">
|
||||
</h1>
|
||||
<div dojoAttachPoint="summaryNode">
|
||||
<p dojoAttachPoint="descriptionNode"></p>
|
||||
<div dojoAttachPoint="viewDemoLinkNode"><img dojoAttachPoint="viewDemoImageNode"/ dojoAttachEvent="onclick: onSelectDemo"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
28
webapp/web/src/widget/demoEngine/templates/DemoNavigator.css
Normal file
28
webapp/web/src/widget/demoEngine/templates/DemoNavigator.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
.demoNavigatorListWrapper {
|
||||
border:1px solid #dcdbdb;
|
||||
background-color:#f8f8f8;
|
||||
padding:2px;
|
||||
}
|
||||
|
||||
.demoNavigatorListContainer {
|
||||
border:1px solid #f0f0f0;
|
||||
background-color:#fff;
|
||||
padding:1em;
|
||||
}
|
||||
|
||||
.demoNavigator h1 {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 10px;
|
||||
font-size: 1.2em;
|
||||
border-bottom:1px dotted #a9ccf5;
|
||||
}
|
||||
|
||||
.demoNavigator .dojoButton {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.demoNavigator .dojoButton .dojoButtonContents {
|
||||
font-size: 1.1em;
|
||||
width: 100px;
|
||||
color: black;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<div dojoAttachPoint="domNode">
|
||||
<table width="100%" cellspacing="0" cellpadding="5">
|
||||
<tbody>
|
||||
<tr dojoAttachPoint="navigationContainer">
|
||||
<td dojoAttachPoint="categoriesNode" valign="top" width="1%">
|
||||
<h1>Categories</h1>
|
||||
<div dojoAttachPoint="categoriesButtonsNode"></div>
|
||||
</td>
|
||||
|
||||
<td dojoAttachPoint="demoListNode" valign="top">
|
||||
<div dojoAttachPoint="demoListWrapperNode">
|
||||
<div dojoAttachPoint="demoListContainerNode">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div dojoAttachPoint="demoNode"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
18
webapp/web/src/widget/demoEngine/templates/DemoPane.css
Normal file
18
webapp/web/src/widget/demoEngine/templates/DemoPane.css
Normal file
|
@ -0,0 +1,18 @@
|
|||
.demoPane {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.demoPane iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0px;
|
||||
border: none;
|
||||
overflow: auto;
|
||||
padding: 0px;
|
||||
margin:0px;
|
||||
background: #ffffff;
|
||||
}
|
3
webapp/web/src/widget/demoEngine/templates/DemoPane.html
Normal file
3
webapp/web/src/widget/demoEngine/templates/DemoPane.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<div dojoAttachPoint="domNode">
|
||||
<iframe dojoAttachPoint="demoNode"></iframe>
|
||||
</div>
|
20
webapp/web/src/widget/demoEngine/templates/SourcePane.css
Normal file
20
webapp/web/src/widget/demoEngine/templates/SourcePane.css
Normal file
|
@ -0,0 +1,20 @@
|
|||
.sourcePane {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sourcePane textarea{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0px;
|
||||
overflow: auto;
|
||||
padding: 0px;
|
||||
margin:0px;
|
||||
}
|
||||
|
||||
* html .sourcePane {
|
||||
overflow: auto;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
<div dojoAttachPoint="domNode">
|
||||
<textarea dojoAttachPoint="sourceNode" rows="100%"></textarea>
|
||||
</div>
|
73
webapp/web/src/widget/demoEngine/templates/general.css
Normal file
73
webapp/web/src/widget/demoEngine/templates/general.css
Normal file
|
@ -0,0 +1,73 @@
|
|||
.demoListWrapper {
|
||||
border:1px solid #dcdbdb;
|
||||
background-color:#f8f8f8;
|
||||
padding:2px;
|
||||
}
|
||||
|
||||
.demoListContainer {
|
||||
border:1px solid #f0f0f0;
|
||||
background-color:#fff;
|
||||
padding:1em;
|
||||
}
|
||||
|
||||
.demoSummaryBox {
|
||||
background: #efefef;
|
||||
border:1px solid #dae3ee;
|
||||
}
|
||||
|
||||
.screenshot {
|
||||
padding:0.65em;
|
||||
width:175px;
|
||||
border-right:1px solid #fafafa;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.demoSummary {
|
||||
margin-bottom:1em;
|
||||
}
|
||||
|
||||
.demoSummary a:link, .demoSummary a:visited {
|
||||
color:#a6238f;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.summaryContainer {
|
||||
border-left:1px solid #ddd;
|
||||
}
|
||||
|
||||
.summaryContainer h1 {
|
||||
background-color:#e8e8e8;
|
||||
border-bottom: 1px solid #e6e6e6;
|
||||
color:#738fb9;
|
||||
margin:1px;
|
||||
padding:0.5em;
|
||||
font-family:"Lucida Grande", "Tahoma", serif;
|
||||
font-size:1.25em;
|
||||
font-weight:normal;
|
||||
}
|
||||
|
||||
.summaryContainer h1 .packageSummary {
|
||||
display:block;
|
||||
color:#000;
|
||||
font-size:10px;
|
||||
margin-top:2px;
|
||||
}
|
||||
|
||||
.summaryContainer .summary {
|
||||
padding:1em;
|
||||
}
|
||||
|
||||
.summaryContainer .summary p {
|
||||
font-size:0.85em;
|
||||
padding:0;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
.reflection {
|
||||
background: url("images/demoBoxReflection.gif") repeat-x top left;
|
||||
height:25px;
|
||||
}
|
||||
|
||||
.view {
|
||||
text-align:right;
|
||||
}
|
BIN
webapp/web/src/widget/demoEngine/templates/images/test_thumb.gif
Normal file
BIN
webapp/web/src/widget/demoEngine/templates/images/test_thumb.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
BIN
webapp/web/src/widget/demoEngine/templates/images/viewDemo.png
Normal file
BIN
webapp/web/src/widget/demoEngine/templates/images/viewDemo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 859 B |
98
webapp/web/src/widget/html/AccordionPane.js
Normal file
98
webapp/web/src/widget/html/AccordionPane.js
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.AccordionPane");
|
||||
dojo.require("dojo.widget.TitlePane");
|
||||
|
||||
dojo.widget.html.AccordionPane = function(){
|
||||
|
||||
dojo.widget.html.TitlePane.call(this);
|
||||
this.widgetType = "AccordionPane";
|
||||
|
||||
this.open=false;
|
||||
this.allowCollapse=true;
|
||||
this.label="";
|
||||
this.open=false;
|
||||
|
||||
this.labelNodeClass="";
|
||||
this.containerNodeClass="";
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.AccordionPane, dojo.widget.html.TitlePane);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.AccordionPane, {
|
||||
postCreate: function() {
|
||||
dojo.widget.html.AccordionPane.superclass.postCreate.call(this);
|
||||
this.domNode.widgetType=this.widgetType;
|
||||
this.setSizes();
|
||||
dojo.html.addClass(this.labelNode, this.labelNodeClass);
|
||||
dojo.html.disableSelection(this.labelNode);
|
||||
dojo.html.addClass(this.containerNode, this.containerNodeClass);
|
||||
},
|
||||
|
||||
collapse: function() {
|
||||
//dojo.fx.html.wipeOut(this.containerNode,250);
|
||||
//var anim = dojo.fx.html.wipe(this.containerNode, 1000, this.containerNode.offsetHeight, 0, null, true);
|
||||
this.containerNode.style.display="none";
|
||||
this.open=false;
|
||||
},
|
||||
|
||||
expand: function() {
|
||||
//dojo.fx.html.wipeIn(this.containerNode,250);
|
||||
this.containerNode.style.display="block";
|
||||
//var anim = dojo.fx.html.wipe(this.containerNode, 1000, 0, this.containerNode.scrollHeight, null, true);
|
||||
this.open=true;
|
||||
},
|
||||
|
||||
getCollapsedHeight: function() {
|
||||
return dojo.style.getOuterHeight(this.labelNode)+1;
|
||||
},
|
||||
|
||||
setSizes: function() {
|
||||
var siblings = this.domNode.parentNode.childNodes;
|
||||
var height=dojo.style.getInnerHeight(this.domNode.parentNode)-this.getCollapsedHeight();
|
||||
|
||||
this.siblingWidgets = [];
|
||||
|
||||
for (var x=0; x<siblings.length; x++) {
|
||||
if (siblings[x].widgetType==this.widgetType) {
|
||||
if (this.domNode != siblings[x]) {
|
||||
var ap = dojo.widget.byNode(siblings[x]);
|
||||
this.siblingWidgets.push(ap);
|
||||
height -= ap.getCollapsedHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var x=0; x<this.siblingWidgets.length; x++) {
|
||||
dojo.style.setOuterHeight(this.siblingWidgets[x].containerNode,height);
|
||||
}
|
||||
|
||||
dojo.style.setOuterHeight(this.containerNode,height);
|
||||
},
|
||||
|
||||
onLabelClick: function() {
|
||||
this.setSizes();
|
||||
if (!this.open) {
|
||||
for (var x=0; x<this.siblingWidgets.length;x++) {
|
||||
if (this.siblingWidgets[x].open) {
|
||||
this.siblingWidgets[x].collapse();
|
||||
}
|
||||
}
|
||||
this.expand();
|
||||
} else {
|
||||
if (this.allowCollapse) {
|
||||
this.collapse();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:AccordionPane");
|
25
webapp/web/src/widget/html/Button2.js
Normal file
25
webapp/web/src/widget/html/Button2.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
// this is a stub that will be removed in 0.4, see ../Button2.html for details
|
||||
|
||||
dojo.provide("dojo.widget.html.Button2");
|
||||
|
||||
dojo.widget.html.Button2 = function(){}
|
||||
dojo.inherits(dojo.widget.html.Button2, dojo.widget.html.Button);
|
||||
dojo.lang.extend(dojo.widget.html.Button2, { widgetType: "Button2" });
|
||||
|
||||
dojo.widget.html.DropDownButton2 = function(){}
|
||||
dojo.inherits(dojo.widget.html.DropDownButton2, dojo.widget.html.DropDownButton);
|
||||
dojo.lang.extend(dojo.widget.html.DropDownButton2, { widgetType: "DropDownButton2" });
|
||||
|
||||
dojo.widget.html.ComboButton2 = function(){}
|
||||
dojo.inherits(dojo.widget.html.ComboButton2, dojo.widget.html.ComboButton);
|
||||
dojo.lang.extend(dojo.widget.html.ComboButton2, { widgetType: "ComboButton2" });
|
82
webapp/web/src/widget/html/Checkbox.js
Normal file
82
webapp/web/src/widget/html/Checkbox.js
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.Checkbox");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.event");
|
||||
dojo.require("dojo.html");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.Checkbox",
|
||||
dojo.widget.HtmlWidget,
|
||||
{
|
||||
widgetType: "Checkbox",
|
||||
|
||||
templatePath: dojo.uri.dojoUri('src/widget/templates/HtmlCheckBox.html'),
|
||||
|
||||
srcOn: dojo.uri.dojoUri('src/widget/templates/check_on.gif'),
|
||||
srcOff: dojo.uri.dojoUri('src/widget/templates/check_off.gif'),
|
||||
srcDisabledOn: dojo.uri.dojoUri('src/widget/templates/check_disabled_on.gif'),
|
||||
srcDisabledOff: dojo.uri.dojoUri('src/widget/templates/check_disabled_off.gif'),
|
||||
srcHoverOn: dojo.uri.dojoUri('src/widget/templates/check_hover_on.gif'),
|
||||
srcHoverOff: dojo.uri.dojoUri('src/widget/templates/check_hover_off.gif'),
|
||||
|
||||
imgSrc: null,
|
||||
|
||||
// parameters
|
||||
disabled: "enabled",
|
||||
name: "",
|
||||
checked: false,
|
||||
tabIndex: -1,
|
||||
|
||||
imgNode: null,
|
||||
inputNode: null,
|
||||
|
||||
postMixInProperties: function(){
|
||||
// set correct source for image before instantiating template
|
||||
this._updateImgSrc();
|
||||
},
|
||||
|
||||
onMouseUp: function(){
|
||||
if(this.disabled == "enabled"){
|
||||
this.checked = !this.checked;
|
||||
this.inputNode.checked = this.checked;
|
||||
this._updateImgSrc();
|
||||
}
|
||||
},
|
||||
|
||||
onMouseOver: function(){
|
||||
this.hover=true;
|
||||
this._updateImgSrc();
|
||||
},
|
||||
|
||||
onMouseOut: function(){
|
||||
this.hover=false;
|
||||
this._updateImgSrc();
|
||||
},
|
||||
|
||||
_updateImgSrc: function(){
|
||||
if(this.disabled == "enabled"){
|
||||
if(this.hover){
|
||||
this.imgSrc = this.checked ? this.srcHoverOn : this.srcHoverOff;
|
||||
}else{
|
||||
this.imgSrc = this.checked ? this.srcOn : this.srcOff;
|
||||
}
|
||||
}else{
|
||||
this.imgSrc = this.checked ? this.srcDisabledOn : this.srcDisabledOff;
|
||||
}
|
||||
if(this.imgNode){
|
||||
this.imgNode.src = this.imgSrc;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
611
webapp/web/src/widget/html/ComboBox.js
Normal file
611
webapp/web/src/widget/html/ComboBox.js
Normal file
|
@ -0,0 +1,611 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.ComboBox");
|
||||
dojo.require("dojo.widget.ComboBox");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.io.*");
|
||||
dojo.require("dojo.lfx.*");
|
||||
dojo.require("dojo.dom");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.string");
|
||||
dojo.require("dojo.widget.html.stabile");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.ComboBox",
|
||||
[dojo.widget.HtmlWidget, dojo.widget.ComboBox],
|
||||
{
|
||||
autoComplete: true,
|
||||
formInputName: "",
|
||||
name: "", // clone in the name from the DOM node
|
||||
textInputNode: null,
|
||||
comboBoxValue: null,
|
||||
comboBoxSelectionValue: null,
|
||||
optionsListWrapper: null,
|
||||
optionsListNode: null,
|
||||
downArrowNode: null,
|
||||
cbTableNode: null,
|
||||
searchTimer: null,
|
||||
searchDelay: 100,
|
||||
dataUrl: "",
|
||||
fadeTime: 200,
|
||||
// maxListLength limits list to X visible rows, scroll on rest
|
||||
maxListLength: 8,
|
||||
// mode can also be "remote" for JSON-returning live search or "html" for
|
||||
// dumber live search
|
||||
mode: "local",
|
||||
selectedResult: null,
|
||||
_highlighted_option: null,
|
||||
_prev_key_backspace: false,
|
||||
_prev_key_esc: false,
|
||||
_result_list_open: false,
|
||||
_gotFocus: false,
|
||||
_mouseover_list: false,
|
||||
dataProviderClass: "dojo.widget.ComboBoxDataProvider",
|
||||
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlComboBox.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlComboBox.css"),
|
||||
|
||||
setValue: function(value) {
|
||||
this.comboBoxValue.value = value;
|
||||
if (this.textInputNode.value != value) { // prevent mucking up of selection
|
||||
this.textInputNode.value = value;
|
||||
}
|
||||
dojo.widget.html.stabile.setState(this.widgetId, this.getState(), true);
|
||||
},
|
||||
|
||||
getValue: function() {
|
||||
return this.comboBoxValue.value;
|
||||
},
|
||||
|
||||
getState: function() {
|
||||
return {value: this.getValue()};
|
||||
},
|
||||
|
||||
setState: function(state) {
|
||||
this.setValue(state.value);
|
||||
},
|
||||
|
||||
getCaretPos: function(element){
|
||||
// khtml 3.5.2 has selection* methods as does webkit nightlies from 2005-06-22
|
||||
if(dojo.lang.isNumber(element.selectionStart)){
|
||||
// FIXME: this is totally borked on Moz < 1.3. Any recourse?
|
||||
return element.selectionStart;
|
||||
}else if(dojo.render.html.ie){
|
||||
// in the case of a mouse click in a popup being handled,
|
||||
// then the document.selection is not the textarea, but the popup
|
||||
// var r = document.selection.createRange();
|
||||
// hack to get IE 6 to play nice. What a POS browser.
|
||||
var tr = document.selection.createRange().duplicate();
|
||||
var ntr = element.createTextRange();
|
||||
tr.move("character",0);
|
||||
ntr.move("character",0);
|
||||
try {
|
||||
// If control doesnt have focus, you get an exception.
|
||||
// Seems to happen on reverse-tab, but can also happen on tab (seems to be a race condition - only happens sometimes).
|
||||
// There appears to be no workaround for this - googled for quite a while.
|
||||
ntr.setEndPoint("EndToEnd", tr);
|
||||
return String(ntr.text).replace(/\r/g,"").length;
|
||||
} catch (e) {
|
||||
return 0; // If focus has shifted, 0 is fine for caret pos.
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
setCaretPos: function(element, location){
|
||||
location = parseInt(location);
|
||||
this.setSelectedRange(element, location, location);
|
||||
},
|
||||
|
||||
setSelectedRange: function(element, start, end){
|
||||
if(!end){ end = element.value.length; } // NOTE: Strange - should be able to put caret at start of text?
|
||||
// Mozilla
|
||||
// parts borrowed from http://www.faqts.com/knowledge_base/view.phtml/aid/13562/fid/130
|
||||
if(element.setSelectionRange){
|
||||
element.focus();
|
||||
element.setSelectionRange(start, end);
|
||||
}else if(element.createTextRange){ // IE
|
||||
var range = element.createTextRange();
|
||||
with(range){
|
||||
collapse(true);
|
||||
moveEnd('character', end);
|
||||
moveStart('character', start);
|
||||
select();
|
||||
}
|
||||
}else{ //otherwise try the event-creation hack (our own invention)
|
||||
// do we need these?
|
||||
element.value = element.value;
|
||||
element.blur();
|
||||
element.focus();
|
||||
// figure out how far back to go
|
||||
var dist = parseInt(element.value.length)-end;
|
||||
var tchar = String.fromCharCode(37);
|
||||
var tcc = tchar.charCodeAt(0);
|
||||
for(var x = 0; x < dist; x++){
|
||||
var te = document.createEvent("KeyEvents");
|
||||
te.initKeyEvent("keypress", true, true, null, false, false, false, false, tcc, tcc);
|
||||
element.dispatchEvent(te);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// does the keyboard related stuff
|
||||
_handleKeyEvents: function(evt){
|
||||
if(evt.ctrlKey || evt.altKey){ return; }
|
||||
|
||||
// reset these
|
||||
this._prev_key_backspace = false;
|
||||
this._prev_key_esc = false;
|
||||
|
||||
var k = dojo.event.browser.keys;
|
||||
var doSearch = true;
|
||||
|
||||
// mozilla quirk
|
||||
// space has no keyCode in mozilla
|
||||
var keyCode = evt.keyCode;
|
||||
if(keyCode==0 && evt.charCode==k.KEY_SPACE){
|
||||
keyCode = k.KEY_SPACE;
|
||||
}
|
||||
switch(keyCode){
|
||||
case k.KEY_DOWN_ARROW:
|
||||
if(!this._result_list_open){
|
||||
this.startSearchFromInput();
|
||||
}
|
||||
this.highlightNextOption();
|
||||
dojo.event.browser.stopEvent(evt);
|
||||
return;
|
||||
case k.KEY_UP_ARROW:
|
||||
this.highlightPrevOption();
|
||||
dojo.event.browser.stopEvent(evt);
|
||||
return;
|
||||
case k.KEY_ENTER:
|
||||
// prevent submitting form if we press enter with list open
|
||||
if(this._result_list_open){
|
||||
dojo.event.browser.stopEvent(evt);
|
||||
}
|
||||
// fallthrough
|
||||
case k.KEY_TAB:
|
||||
// using linux alike tab for autocomplete
|
||||
if(!this.autoComplete && this._result_list_open && this._highlighted_option){
|
||||
dojo.event.browser.stopEvent(evt);
|
||||
this.selectOption({ 'target': this._highlighted_option, 'noHide': true });
|
||||
|
||||
// put caret last
|
||||
this.setSelectedRange(this.textInputNode, this.textInputNode.value.length, null);
|
||||
}else{
|
||||
this.selectOption();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case k.KEY_SPACE:
|
||||
if(this._result_list_open && this._highlighted_option){
|
||||
dojo.event.browser.stopEvent(evt);
|
||||
this.selectOption();
|
||||
this.hideResultList();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case k.KEY_ESCAPE:
|
||||
this.hideResultList();
|
||||
this._prev_key_esc = true;
|
||||
return;
|
||||
case k.KEY_BACKSPACE:
|
||||
this._prev_key_backspace = true;
|
||||
if(!this.textInputNode.value.length){
|
||||
this.setAllValues("", "");
|
||||
this.hideResultList();
|
||||
doSearch = false;
|
||||
}
|
||||
break;
|
||||
case k.KEY_RIGHT_ARROW: // fall through
|
||||
case k.KEY_LEFT_ARROW: // fall through
|
||||
case k.KEY_SHIFT:
|
||||
doSearch = false;
|
||||
break;
|
||||
default:// non char keys (F1-F12 etc..) shouldn't open list
|
||||
if(evt.charCode==0){
|
||||
doSearch = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(this.searchTimer){
|
||||
clearTimeout(this.searchTimer);
|
||||
}
|
||||
if(doSearch){
|
||||
// if we have gotten this far we dont want to keep our highlight
|
||||
this.blurOptionNode();
|
||||
|
||||
// need to wait a tad before start search so that the event bubbles through DOM and we have value visible
|
||||
this.searchTimer = setTimeout(dojo.lang.hitch(this, this.startSearchFromInput), this.searchDelay);
|
||||
}
|
||||
},
|
||||
|
||||
onKeyDown: function(evt){
|
||||
// IE needs to stop keyDown others need to stop keyPress
|
||||
if(!document.createEvent){ // only IE
|
||||
this._handleKeyEvents(evt);
|
||||
}
|
||||
// FIXME: What about ESC ??
|
||||
},
|
||||
|
||||
onKeyPress: function(evt){
|
||||
if(document.createEvent){ // never IE
|
||||
this._handleKeyEvents(evt);
|
||||
}
|
||||
},
|
||||
|
||||
onKeyUp: function(evt){
|
||||
this.setValue(this.textInputNode.value);
|
||||
},
|
||||
|
||||
setSelectedValue: function(value){
|
||||
// FIXME, not sure what to do here!
|
||||
this.comboBoxSelectionValue.value = value;
|
||||
},
|
||||
|
||||
setAllValues: function(value1, value2){
|
||||
this.setValue(value1);
|
||||
this.setSelectedValue(value2);
|
||||
},
|
||||
|
||||
// opera, khtml, safari doesnt support node.scrollIntoView(), workaround
|
||||
scrollIntoView: function(){
|
||||
var node = this._highlighted_option;
|
||||
var parent = this.optionsListNode;
|
||||
// don't rely on that node.scrollIntoView works just because the function is there
|
||||
// it doesnt work in Konqueror or Opera even though the function is there and probably
|
||||
// not safari either
|
||||
// dont like browser sniffs implementations but sometimes you have to use it
|
||||
if(dojo.render.html.ie || dojo.render.html.mozilla){
|
||||
// IE, mozilla
|
||||
node.scrollIntoView(false);
|
||||
}else{
|
||||
var parentBottom = parent.scrollTop + dojo.style.getInnerHeight(parent);
|
||||
var nodeBottom = node.offsetTop + dojo.style.getOuterHeight(node);
|
||||
if(parentBottom < nodeBottom){
|
||||
parent.scrollTop += (nodeBottom - parentBottom);
|
||||
}else if(parent.scrollTop > node.offsetTop){
|
||||
parent.scrollTop -= (parent.scrollTop - node.offsetTop);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// does the actual highlight
|
||||
focusOptionNode: function(node){
|
||||
if(this._highlighted_option != node){
|
||||
this.blurOptionNode();
|
||||
this._highlighted_option = node;
|
||||
dojo.html.addClass(this._highlighted_option, "dojoComboBoxItemHighlight");
|
||||
}
|
||||
},
|
||||
|
||||
// removes highlight on highlighted
|
||||
blurOptionNode: function(){
|
||||
if(this._highlighted_option){
|
||||
dojo.html.removeClass(this._highlighted_option, "dojoComboBoxItemHighlight");
|
||||
this._highlighted_option = null;
|
||||
}
|
||||
},
|
||||
|
||||
highlightNextOption: function(){
|
||||
if((!this._highlighted_option) || !this._highlighted_option.parentNode){
|
||||
this.focusOptionNode(this.optionsListNode.firstChild);
|
||||
}else if(this._highlighted_option.nextSibling){
|
||||
this.focusOptionNode(this._highlighted_option.nextSibling);
|
||||
}
|
||||
this.scrollIntoView();
|
||||
},
|
||||
|
||||
highlightPrevOption: function(){
|
||||
if(this._highlighted_option && this._highlighted_option.previousSibling){
|
||||
this.focusOptionNode(this._highlighted_option.previousSibling);
|
||||
}else{
|
||||
this._highlighted_option = null;
|
||||
this.hideResultList();
|
||||
return;
|
||||
}
|
||||
this.scrollIntoView();
|
||||
},
|
||||
|
||||
itemMouseOver: function(evt){
|
||||
this.focusOptionNode(evt.target);
|
||||
dojo.html.addClass(this._highlighted_option, "dojoComboBoxItemHighlight");
|
||||
},
|
||||
|
||||
itemMouseOut: function(evt){
|
||||
this.blurOptionNode();
|
||||
},
|
||||
|
||||
fillInTemplate: function(args, frag){
|
||||
// FIXME: need to get/assign DOM node names for form participation here.
|
||||
this.comboBoxValue.name = this.name;
|
||||
this.comboBoxSelectionValue.name = this.name+"_selected";
|
||||
|
||||
var source = this.getFragNodeRef(frag);
|
||||
dojo.html.copyStyle(this.domNode, source);
|
||||
|
||||
var dpClass;
|
||||
if(this.mode == "remote"){
|
||||
dpClass = dojo.widget.incrementalComboBoxDataProvider;
|
||||
}else if(typeof this.dataProviderClass == "string"){
|
||||
dpClass = dojo.evalObjPath(this.dataProviderClass)
|
||||
}else{
|
||||
dpClass = this.dataProviderClass;
|
||||
}
|
||||
this.dataProvider = new dpClass();
|
||||
this.dataProvider.init(this, this.getFragNodeRef(frag));
|
||||
|
||||
// Prevent IE bleed-through problem
|
||||
this.optionsIframe = new dojo.html.BackgroundIframe(this.optionsListWrapper);
|
||||
this.optionsIframe.size([0,0,0,0]);
|
||||
},
|
||||
|
||||
|
||||
focus: function(){
|
||||
// summary
|
||||
// set focus to input node from code
|
||||
this.tryFocus();
|
||||
},
|
||||
|
||||
openResultList: function(results){
|
||||
this.clearResultList();
|
||||
if(!results.length){
|
||||
this.hideResultList();
|
||||
}
|
||||
|
||||
if( (this.autoComplete)&&
|
||||
(results.length)&&
|
||||
(!this._prev_key_backspace)&&
|
||||
(this.textInputNode.value.length > 0)){
|
||||
var cpos = this.getCaretPos(this.textInputNode);
|
||||
// only try to extend if we added the last character at the end of the input
|
||||
if((cpos+1) > this.textInputNode.value.length){
|
||||
// only add to input node as we would overwrite Capitalisation of chars
|
||||
this.textInputNode.value += results[0][0].substr(cpos);
|
||||
// build a new range that has the distance from the earlier
|
||||
// caret position to the end of the first string selected
|
||||
this.setSelectedRange(this.textInputNode, cpos, this.textInputNode.value.length);
|
||||
}
|
||||
}
|
||||
|
||||
var even = true;
|
||||
while(results.length){
|
||||
var tr = results.shift();
|
||||
if(tr){
|
||||
var td = document.createElement("div");
|
||||
td.appendChild(document.createTextNode(tr[0]));
|
||||
td.setAttribute("resultName", tr[0]);
|
||||
td.setAttribute("resultValue", tr[1]);
|
||||
td.className = "dojoComboBoxItem "+((even) ? "dojoComboBoxItemEven" : "dojoComboBoxItemOdd");
|
||||
even = (!even);
|
||||
this.optionsListNode.appendChild(td);
|
||||
dojo.event.connect(td, "onmouseover", this, "itemMouseOver");
|
||||
dojo.event.connect(td, "onmouseout", this, "itemMouseOut");
|
||||
}
|
||||
}
|
||||
|
||||
// show our list (only if we have content, else nothing)
|
||||
this.showResultList();
|
||||
},
|
||||
|
||||
onFocusInput: function(){
|
||||
this._hasFocus = true;
|
||||
},
|
||||
|
||||
onBlurInput: function(){
|
||||
this._hasFocus = false;
|
||||
this._handleBlurTimer(true, 500);
|
||||
},
|
||||
|
||||
// collect all blur timers issues here
|
||||
_handleBlurTimer: function(/*Boolean*/clear, /*Number*/ millisec){
|
||||
if(this.blurTimer && (clear || millisec)){
|
||||
clearTimeout(this.blurTimer);
|
||||
}
|
||||
if(millisec){ // we ignore that zero is false and never sets as that never happens in this widget
|
||||
this.blurTimer = dojo.lang.setTimeout(this, "checkBlurred", millisec);
|
||||
}
|
||||
},
|
||||
|
||||
// these 2 are needed in IE and Safari as inputTextNode loses focus when scrolling optionslist
|
||||
_onMouseOver: function(evt){
|
||||
if(!this._mouseover_list){
|
||||
this._handleBlurTimer(true, 0);
|
||||
this._mouseover_list = true;
|
||||
}
|
||||
},
|
||||
|
||||
_onMouseOut:function(evt){
|
||||
var relTarget = evt.relatedTarget;
|
||||
if(!relTarget || relTarget.parentNode!=this.optionsListNode){
|
||||
this._mouseover_list = false;
|
||||
this._handleBlurTimer(true, 100);
|
||||
this.tryFocus();
|
||||
}
|
||||
},
|
||||
|
||||
_isInputEqualToResult: function(result){
|
||||
input = this.textInputNode.value;
|
||||
if(!this.dataProvider.caseSensitive){
|
||||
input = input.toLowerCase();
|
||||
result = result.toLowerCase();
|
||||
}
|
||||
return (input == result);
|
||||
},
|
||||
|
||||
_isValidOption: function(){
|
||||
tgt = dojo.dom.firstElement(this.optionsListNode);
|
||||
isValidOption = false;
|
||||
while(!isValidOption && tgt){
|
||||
if(this._isInputEqualToResult(tgt.getAttribute("resultName"))){
|
||||
isValidOption = true;
|
||||
}else{
|
||||
tgt = dojo.dom.nextElement(tgt);
|
||||
}
|
||||
}
|
||||
return isValidOption;
|
||||
},
|
||||
|
||||
checkBlurred: function(){
|
||||
if(!this._hasFocus && !this._mouseover_list){
|
||||
this.hideResultList();
|
||||
// clear the list if the user empties field and moves away.
|
||||
if(!this.textInputNode.value.length){
|
||||
this.setAllValues("", "");
|
||||
return;
|
||||
}
|
||||
|
||||
isValidOption = this._isValidOption();
|
||||
// enforce selection from option list
|
||||
if(this.forceValidOption && !isValidOption){
|
||||
this.setAllValues("", "");
|
||||
return;
|
||||
}
|
||||
if(!isValidOption){// clear
|
||||
this.setSelectedValue("");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
sizeBackgroundIframe: function(){
|
||||
var w = dojo.style.getOuterWidth(this.optionsListNode);
|
||||
var h = dojo.style.getOuterHeight(this.optionsListNode);
|
||||
if( w==0 || h==0 ){
|
||||
// need more time to calculate size
|
||||
dojo.lang.setTimeout(this, "sizeBackgroundIframe", 100);
|
||||
return;
|
||||
}
|
||||
if(this._result_list_open){
|
||||
this.optionsIframe.size([0,0,w,h]);
|
||||
}
|
||||
},
|
||||
|
||||
selectOption: function(evt){
|
||||
var tgt = null;
|
||||
if(!evt){
|
||||
evt = { target: this._highlighted_option };
|
||||
}
|
||||
|
||||
if(!dojo.dom.isDescendantOf(evt.target, this.optionsListNode)){
|
||||
// handle autocompletion where the the user has hit ENTER or TAB
|
||||
|
||||
// if the input is empty do nothing
|
||||
if(!this.textInputNode.value.length){
|
||||
return;
|
||||
}
|
||||
tgt = dojo.dom.firstElement(this.optionsListNode);
|
||||
|
||||
// user has input value not in option list
|
||||
if(!tgt || !this._isInputEqualToResult(tgt.getAttribute("resultName"))){
|
||||
return;
|
||||
}
|
||||
// otherwise the user has accepted the autocompleted value
|
||||
}else{
|
||||
tgt = evt.target;
|
||||
}
|
||||
|
||||
while((tgt.nodeType!=1)||(!tgt.getAttribute("resultName"))){
|
||||
tgt = tgt.parentNode;
|
||||
if(tgt === document.body){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
this.textInputNode.value = tgt.getAttribute("resultName");
|
||||
this.selectedResult = [tgt.getAttribute("resultName"), tgt.getAttribute("resultValue")];
|
||||
this.setAllValues(tgt.getAttribute("resultName"), tgt.getAttribute("resultValue"));
|
||||
if(!evt.noHide){
|
||||
this.hideResultList();
|
||||
this.setSelectedRange(this.textInputNode, 0, null);
|
||||
}
|
||||
this.tryFocus();
|
||||
},
|
||||
|
||||
clearResultList: function(){
|
||||
var oln = this.optionsListNode;
|
||||
while(oln.firstChild){
|
||||
dojo.event.disconnect(oln.firstChild, "onmouseover", this, "itemMouseOver");
|
||||
dojo.event.disconnect(oln.firstChild, "onmouseout", this, "itemMouseOut");
|
||||
oln.removeChild(oln.firstChild);
|
||||
}
|
||||
},
|
||||
|
||||
hideResultList: function(){
|
||||
if(this._result_list_open){
|
||||
this._result_list_open = false;
|
||||
this.optionsIframe.size([0,0,0,0]);
|
||||
dojo.lfx.fadeHide(this.optionsListNode, this.fadeTime).play();
|
||||
}
|
||||
},
|
||||
|
||||
showResultList: function(){
|
||||
// Our dear friend IE doesnt take max-height so we need to calculate that on our own every time
|
||||
var childs = this.optionsListNode.childNodes;
|
||||
if(childs.length){
|
||||
var visibleCount = this.maxListLength;
|
||||
if(childs.length < visibleCount){
|
||||
visibleCount = childs.length;
|
||||
}
|
||||
|
||||
with(this.optionsListNode.style){
|
||||
display = "";
|
||||
height = ((visibleCount) ? (dojo.style.getOuterHeight(childs[0]) * visibleCount) : 0)+"px";
|
||||
width = dojo.html.getOuterWidth(this.cbTableNode)-2+"px";
|
||||
}
|
||||
// only fadein once (flicker)
|
||||
if(!this._result_list_open){
|
||||
dojo.html.setOpacity(this.optionsListNode, 0);
|
||||
dojo.lfx.fadeIn(this.optionsListNode, this.fadeTime).play();
|
||||
}
|
||||
|
||||
// prevent IE bleed through
|
||||
this._iframeTimer = dojo.lang.setTimeout(this, "sizeBackgroundIframe", 200);
|
||||
this._result_list_open = true;
|
||||
}else{
|
||||
this.hideResultList();
|
||||
}
|
||||
},
|
||||
|
||||
handleArrowClick: function(){
|
||||
this._handleBlurTimer(true, 0);
|
||||
this.tryFocus();
|
||||
if(this._result_list_open){
|
||||
this.hideResultList();
|
||||
}else{
|
||||
this.startSearchFromInput();
|
||||
}
|
||||
},
|
||||
|
||||
tryFocus: function(){
|
||||
try {
|
||||
this.textInputNode.focus();
|
||||
} catch (e) {
|
||||
// element isn't focusable if disabled, or not visible etc - not easy to test for.
|
||||
};
|
||||
},
|
||||
|
||||
startSearchFromInput: function(){
|
||||
this.startSearch(this.textInputNode.value);
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
dojo.event.connect(this, "startSearch", this.dataProvider, "startSearch");
|
||||
dojo.event.connect(this.dataProvider, "provideSearchResults", this, "openResultList");
|
||||
dojo.event.connect(this.textInputNode, "onblur", this, "onBlurInput");
|
||||
dojo.event.connect(this.textInputNode, "onfocus", this, "onFocusInput");
|
||||
|
||||
var s = dojo.widget.html.stabile.getState(this.widgetId);
|
||||
if (s) {
|
||||
this.setState(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
566
webapp/web/src/widget/html/ContentPane.js
Normal file
566
webapp/web/src/widget/html/ContentPane.js
Normal file
|
@ -0,0 +1,566 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.ContentPane");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.io.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.widget.ContentPane");
|
||||
dojo.require("dojo.string");
|
||||
dojo.require("dojo.string.extras");
|
||||
dojo.require("dojo.style");
|
||||
|
||||
dojo.widget.html.ContentPane = function(){
|
||||
this._onLoadStack = [];
|
||||
this._onUnLoadStack = [];
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.ContentPane, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.ContentPane, {
|
||||
widgetType: "ContentPane",
|
||||
isContainer: true,
|
||||
|
||||
// remote loading options
|
||||
adjustPaths: true,
|
||||
href: "",
|
||||
extractContent: true,
|
||||
parseContent: true,
|
||||
cacheContent: true,
|
||||
preload: false, // force load of data even if pane is hidden
|
||||
refreshOnShow: false,
|
||||
handler: "", // generate pane content from a java function
|
||||
executeScripts: false, // if true scripts in content will be evaled after content is set and parsed
|
||||
scriptScope: null, // scopeContainer for downloaded scripts
|
||||
|
||||
// If the user want a global in the remote script he/she just omitts the var
|
||||
// examples:
|
||||
//--------------------------
|
||||
// these gets collected by scriptScope and is reached by dojo.widget.byId('..').scriptScope.myCustomproperty
|
||||
// this.myString = "dojo is a great javascript toolkit!";
|
||||
//
|
||||
// this.alertMyString = function(){
|
||||
// alert(myString);
|
||||
// }
|
||||
// -------------------------
|
||||
// these go into the global namespace (window) notice lack of var, equiv to window.myString
|
||||
// myString = "dojo is a javascript toolkit!";
|
||||
//
|
||||
// alertMyString = function(){
|
||||
// alert(myString);
|
||||
// }
|
||||
|
||||
|
||||
// private
|
||||
_remoteStyles: null, // array of stylenodes inserted to document head
|
||||
// by remote content, used when we clean up for new content
|
||||
|
||||
_callOnUnLoad: false, // used by setContent and _handleDefults, makes sure onUnLoad is only called once
|
||||
|
||||
postCreate: function(args, frag, parentComp){
|
||||
if ( this.handler != "" ){
|
||||
this.setHandler(this.handler);
|
||||
}
|
||||
if(this.isShowing()||this.preload){ this.loadContents(); }
|
||||
},
|
||||
|
||||
show: function(){
|
||||
// if refreshOnShow is true, reload the contents every time; otherwise, load only the first time
|
||||
if(this.refreshOnShow){
|
||||
this.refresh();
|
||||
}else{
|
||||
this.loadContents();
|
||||
}
|
||||
dojo.widget.html.ContentPane.superclass.show.call(this);
|
||||
},
|
||||
|
||||
refresh: function(){
|
||||
this.isLoaded=false;
|
||||
this.loadContents();
|
||||
},
|
||||
|
||||
loadContents: function() {
|
||||
if ( this.isLoaded ){
|
||||
return;
|
||||
}
|
||||
this.isLoaded=true;
|
||||
if ( dojo.lang.isFunction(this.handler)) {
|
||||
this._runHandler();
|
||||
} else if ( this.href != "" ) {
|
||||
this._downloadExternalContent(this.href, this.cacheContent);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
setUrl: function(/*String*/ url) {
|
||||
// summary:
|
||||
// Reset the (external defined) content of this pane and replace with new url
|
||||
this.href = url;
|
||||
this.isLoaded = false;
|
||||
if ( this.preload || this.isShowing() ){
|
||||
this.loadContents();
|
||||
}
|
||||
},
|
||||
|
||||
_downloadExternalContent: function(url, useCache) {
|
||||
this._handleDefaults("Loading...", "onDownloadStart");
|
||||
var self = this;
|
||||
dojo.io.bind({
|
||||
url: url,
|
||||
useCache: useCache,
|
||||
preventCache: !useCache,
|
||||
mimetype: "text/html",
|
||||
handler: function(type, data, e) {
|
||||
if(type == "load") {
|
||||
self.onDownloadEnd.call(self, url, data);
|
||||
} else {
|
||||
// works best when from a live server instead of from file system
|
||||
self._handleDefaults.call(self, "Error loading '" + url + "' (" + e.status + " "+ e.statusText + ")", "onDownloadError");
|
||||
self.onLoad();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// called when setContent is finished
|
||||
onLoad: function(e){
|
||||
this._runStack("_onLoadStack");
|
||||
},
|
||||
|
||||
// called before old content is cleared
|
||||
onUnLoad: function(e){
|
||||
this._runStack("_onUnLoadStack");
|
||||
this.scriptScope = null;
|
||||
},
|
||||
|
||||
_runStack: function(stName){
|
||||
var st = this[stName]; var err = "";
|
||||
for(var i = 0;i < st.length; i++){
|
||||
try{
|
||||
st[i].call(this.scriptScope);
|
||||
}catch(e){
|
||||
err += "\n"+st[i]+" failed: "+e.description;
|
||||
}
|
||||
}
|
||||
this[stName] = [];
|
||||
|
||||
if(err.length){
|
||||
var name = (stName== "_onLoadStack") ? "addOnLoad" : "addOnUnLoad";
|
||||
this._handleDefaults(name+" failure\n "+err, "onExecError", true);
|
||||
}
|
||||
},
|
||||
|
||||
addOnLoad: function(obj, func){
|
||||
// summary
|
||||
// same as to dojo.addOnLoad but does not take "function_name" as a string
|
||||
this._pushOnStack(this._onLoadStack, obj, func);
|
||||
},
|
||||
|
||||
addOnUnLoad: function(obj, func){
|
||||
// summary
|
||||
// same as to dojo.addUnOnLoad but does not take "function_name" as a string
|
||||
this._pushOnStack(this._onUnLoadStack, obj, func);
|
||||
},
|
||||
|
||||
_pushOnStack: function(stack, obj, func){
|
||||
if(typeof func == 'undefined') {
|
||||
stack.push(obj);
|
||||
}else{
|
||||
stack.push(function(){ obj[func](); });
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function(){
|
||||
// make sure we call onUnLoad
|
||||
this.onUnLoad();
|
||||
dojo.widget.html.ContentPane.superclass.destroy.call(this);
|
||||
},
|
||||
|
||||
// called when content script eval error or Java error occurs, preventDefault-able
|
||||
onExecError: function(e){ /*stub*/ },
|
||||
|
||||
// called on DOM faults, require fault etc in content, preventDefault-able
|
||||
onContentError: function(e){ /*stub*/ },
|
||||
|
||||
// called when download error occurs, preventDefault-able
|
||||
onDownloadError: function(e){ /*stub*/ },
|
||||
|
||||
// called before download starts, preventDefault-able
|
||||
onDownloadStart: function(e){ /*stub*/ },
|
||||
|
||||
// called when download is finished
|
||||
onDownloadEnd: function(url, data){
|
||||
data = this.splitAndFixPaths(data, url);
|
||||
this.setContent(data);
|
||||
},
|
||||
|
||||
// usefull if user wants to prevent default behaviour ie: _setContent("Error...")
|
||||
_handleDefaults: function(e, handler, useAlert){
|
||||
if(!handler){ handler = "onContentError"; }
|
||||
if(dojo.lang.isString(e)){
|
||||
e = {
|
||||
"text": e,
|
||||
"toString": function(){ return this.text; }
|
||||
}
|
||||
}
|
||||
if(typeof e.returnValue != "boolean"){
|
||||
e.returnValue = true;
|
||||
}
|
||||
if(typeof e.preventDefault != "function"){
|
||||
e.preventDefault = function(){
|
||||
this.returnValue = false;
|
||||
}
|
||||
}
|
||||
// call our handler
|
||||
this[handler](e);
|
||||
if(e.returnValue){
|
||||
if(useAlert){
|
||||
alert(e.toString());
|
||||
}else{
|
||||
if(this._callOnUnLoad){
|
||||
this.onUnLoad(); // makes sure scripts can clean up after themselves, before we setContent
|
||||
}
|
||||
this._callOnUnLoad = false; // makes sure we dont try to call onUnLoad again on this event,
|
||||
// ie onUnLoad before 'Loading...' but not before clearing 'Loading...'
|
||||
this._setContent(e.toString());
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
splitAndFixPaths: function(/*String*/s, /*dojo.uri.Uri?*/url){
|
||||
// summary:
|
||||
// fixes all remote paths in (hopefully) all cases for example images, remote scripts, links etc.
|
||||
// splits up content in different pieces, scripts, title, style, link and whats left becomes .xml
|
||||
|
||||
if(!url) { url = "./"; } // point to this page if not set
|
||||
if(!s) { return ""; }
|
||||
|
||||
// fix up paths in data
|
||||
var titles = []; var scripts = []; var linkStyles = [];
|
||||
var styles = []; var remoteScripts = []; var requires = [];
|
||||
|
||||
// khtml is much more picky about dom faults, you can't for example attach a style node under body of document
|
||||
// must go into head, as does a title node, so we need to cut out those tags
|
||||
// cut out title tags
|
||||
var match = [];
|
||||
while(match){
|
||||
match = s.match(/<title[^>]*>([\s\S]*?)<\/title>/i); // can't match with dot as that
|
||||
if(!match){ break;} //doesnt match newline in js
|
||||
titles.push(match[1]);
|
||||
s = s.replace(/<title[^>]*>[\s\S]*?<\/title>/i, "");
|
||||
}
|
||||
|
||||
// cut out <style> url(...) </style>, as that bails out in khtml
|
||||
var match = [];
|
||||
while(match){
|
||||
match = s.match(/<style[^>]*>([\s\S]*?)<\/style>/i);
|
||||
if(!match){ break; }
|
||||
styles.push(dojo.style.fixPathsInCssText(match[1], url));
|
||||
s = s.replace(/<style[^>]*?>[\s\S]*?<\/style>/i, "");
|
||||
}
|
||||
|
||||
// attributepaths one tag can have multiple paths example:
|
||||
// <input src="..." style="url(..)"/> or <a style="url(..)" href="..">
|
||||
// strip out the tag and run fix on that.
|
||||
// this guarantees that we won't run replace another tag's attribute + it was easier do
|
||||
var pos = 0; var pos2 = 0; var stop = 0 ;var str = ""; var fixedPath = "";
|
||||
var attr = []; var fix = ""; var tagFix = ""; var tag = ""; var regex = "";
|
||||
while(pos>-1){
|
||||
pos = s.search(/<[a-z][a-z0-9]*[^>]*\s(?:(?:src|href|style)=[^>])+[^>]*>/i);
|
||||
if(pos==-1){ break; }
|
||||
str += s.substring(0, pos);
|
||||
s = s.substring(pos, s.length);
|
||||
tag = s.match(/^<[a-z][a-z0-9]*[^>]*>/i)[0];
|
||||
s = s.substring(tag.length, s.length);
|
||||
|
||||
// loop through attributes
|
||||
pos2 = 0; tagFix = ""; fix = ""; regex = ""; var regexlen = 0;
|
||||
while(pos2!=-1){
|
||||
// slices up before next attribute check, values from previous loop
|
||||
tagFix += tag.substring(0, pos2) + fix;
|
||||
tag = tag.substring(pos2+regexlen, tag.length);
|
||||
|
||||
// fix next attribute or bail out when done
|
||||
// hopefully this charclass covers most urls
|
||||
attr = tag.match(/ (src|href|style)=(['"]?)([\w()\[\]\/.,\\'"-:;#=&?\s@]+?)\2/i);
|
||||
if(!attr){ break; }
|
||||
|
||||
switch(attr[1].toLowerCase()){
|
||||
case "src":// falltrough
|
||||
case "href":
|
||||
// this hopefully covers most common protocols
|
||||
if(attr[3].search(/^(?:[#]|(?:(?:https?|ftps?|file|javascript|mailto|news):))/)==-1){
|
||||
fixedPath = (new dojo.uri.Uri(url, attr[3]).toString());
|
||||
} else {
|
||||
pos2 = pos2 + attr[3].length;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case "style":// style
|
||||
fixedPath = dojo.style.fixPathsInCssText(attr[3], url);
|
||||
break;
|
||||
default:
|
||||
pos2 = pos2 + attr[3].length;
|
||||
continue;
|
||||
}
|
||||
|
||||
regex = " " + attr[1] + "=" + attr[2] + attr[3] + attr[2];
|
||||
regexlen = regex.length;
|
||||
fix = " " + attr[1] + "=" + attr[2] + fixedPath + attr[2];
|
||||
pos2 = tag.search(new RegExp(dojo.string.escapeRegExp(regex)));
|
||||
}
|
||||
str += tagFix + tag;
|
||||
pos = 0; // reset for next mainloop
|
||||
}
|
||||
s = str+s;
|
||||
|
||||
// cut out all script tags, push them into scripts array
|
||||
match = []; var tmp = [];
|
||||
while(match){
|
||||
match = s.match(/<script([^>]*)>([\s\S]*?)<\/script>/i);
|
||||
if(!match){ break; }
|
||||
if(match[1]){
|
||||
attr = match[1].match(/src=(['"]?)([^"']*)\1/i);
|
||||
if(attr){
|
||||
// remove a dojo.js or dojo.js.uncompressed.js from remoteScripts
|
||||
// we declare all files with dojo.js as bad, regardless of folder
|
||||
var tmp = attr[2].search(/.*(\bdojo\b(?:\.uncompressed)?\.js)$/);
|
||||
if(tmp > -1){
|
||||
dojo.debug("Security note! inhibit:"+attr[2]+" from beeing loaded again.");
|
||||
}else{
|
||||
remoteScripts.push(attr[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(match[2]){
|
||||
// strip out all djConfig variables from script tags nodeValue
|
||||
// this is ABSOLUTLY needed as reinitialize djConfig after dojo is initialised
|
||||
// makes a dissaster greater than Titanic, update remove writeIncludes() to
|
||||
var sc = match[2].replace(/(?:var )?\bdjConfig\b(?:[\s]*=[\s]*\{[^}]+\}|\.[\w]*[\s]*=[\s]*[^;\n]*)?;?|dojo\.hostenv\.writeIncludes\(\s*\);?/g, "");
|
||||
if(!sc){ continue; }
|
||||
|
||||
// cut out all dojo.require (...) calls, if we have execute
|
||||
// scripts false widgets dont get there require calls
|
||||
// does suck out possible widgetpackage registration as well
|
||||
tmp = [];
|
||||
while(tmp && requires.length<100){
|
||||
tmp = sc.match(/dojo\.(?:(?:require(?:After)?(?:If)?)|(?:widget\.(?:manager\.)?registerWidgetPackage)|(?:(?:hostenv\.)?setModulePrefix))\((['"]).*?\1\)\s*;?/);
|
||||
if(!tmp){ break;}
|
||||
requires.push(tmp[0]);
|
||||
sc = sc.replace(tmp[0], "");
|
||||
}
|
||||
scripts.push(sc);
|
||||
}
|
||||
s = s.replace(/<script[^>]*>[\s\S]*?<\/script>/i, "");
|
||||
}
|
||||
|
||||
// scan for scriptScope in html eventHandlers and replace with link to this pane
|
||||
if(this.executeScripts){
|
||||
var regex = /(<[a-zA-Z][a-zA-Z0-9]*\s[^>]*\S=(['"])[^>]*[^\.\]])scriptScope([^>]*>)/;
|
||||
var pos = 0;var str = "";match = [];var cit = "";
|
||||
while(pos > -1){
|
||||
pos = s.search(regex);
|
||||
if(pos > -1){
|
||||
cit = ((RegExp.$2=="'") ? '"': "'");
|
||||
str += s.substring(0, pos);
|
||||
s = s.substr(pos).replace(regex, "$1dojo.widget.byId("+ cit + this.widgetId + cit + ").scriptScope$3");
|
||||
}
|
||||
}
|
||||
s = str + s;
|
||||
}
|
||||
|
||||
// cut out all <link rel="stylesheet" href="..">
|
||||
match = [];
|
||||
while(match){
|
||||
match = s.match(/<link ([^>]*rel=['"]?stylesheet['"]?[^>]*)>/i);
|
||||
if(!match){ break; }
|
||||
attr = match[1].match(/href=(['"]?)([^'">]*)\1/i);
|
||||
if(attr){
|
||||
linkStyles.push(attr[2]);
|
||||
}
|
||||
s = s.replace(new RegExp(match[0]), "");
|
||||
}
|
||||
|
||||
return {"xml": s, // Object
|
||||
"styles": styles,
|
||||
"linkStyles": linkStyles,
|
||||
"titles": titles,
|
||||
"requires": requires,
|
||||
"scripts": scripts,
|
||||
"remoteScripts": remoteScripts,
|
||||
"url": url};
|
||||
},
|
||||
|
||||
|
||||
_setContent: function(/*String*/ xml){
|
||||
// summary:
|
||||
// private internal function without path regExpCheck and no onLoad calls aftervards
|
||||
|
||||
// remove old children from current content
|
||||
this.destroyChildren();
|
||||
|
||||
// remove old stylenodes from HEAD
|
||||
if(this._remoteStyles){
|
||||
for(var i = 0; i < this._remoteStyles.length; i++){
|
||||
if(this._remoteStyles[i] && this._remoteStyles.parentNode){
|
||||
this._remoteStyles[i].parentNode.removeChild(this._remoteStyles[i]);
|
||||
}
|
||||
}
|
||||
this._remoteStyles = null;
|
||||
}
|
||||
|
||||
var node = this.containerNode || this.domNode;
|
||||
try{
|
||||
if(typeof xml != "string"){
|
||||
node.innerHTML = "";
|
||||
node.appendChild(xml);
|
||||
}else{
|
||||
node.innerHTML = xml;
|
||||
}
|
||||
} catch(e){
|
||||
e = "Could'nt load content:"+e;
|
||||
this._handleDefaults(e, "onContentError");
|
||||
}
|
||||
},
|
||||
|
||||
setContent: function(/*String*/ data){
|
||||
// summary:
|
||||
// Destroys old content and setting new content, and possibly initialize any widgets within 'data'
|
||||
|
||||
if(this._callOnUnLoad){ // this tells a remote script clean up after itself
|
||||
this.onUnLoad();
|
||||
}
|
||||
this._callOnUnLoad = true;
|
||||
|
||||
if(!data || dojo.dom.isNode(data)){
|
||||
// if we do a clean using setContent(""); or setContent(#node) bypass all parseing, extractContent etc
|
||||
this._setContent(data);
|
||||
this.onResized();
|
||||
this.onLoad();
|
||||
}else{
|
||||
// need to run splitAndFixPaths? ie. manually setting content
|
||||
if((!data.xml)&&(this.adjustPaths)){
|
||||
data = this.splitAndFixPaths(data);
|
||||
}
|
||||
if(this.extractContent) {
|
||||
var matches = data.xml.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
|
||||
if(matches) { data.xml = matches[1]; }
|
||||
}
|
||||
// insert styleNodes, from <style>....
|
||||
for(var i = 0; i < data.styles.length; i++){
|
||||
if(i==0){
|
||||
this._remoteStyles = [];
|
||||
}
|
||||
this._remoteStyles.push(dojo.style.insertCssText(data.styles[i]));
|
||||
}
|
||||
// insert styleNodes, from <link href="...">
|
||||
for(var i = 0; i < data.linkStyles.length; i++){
|
||||
if(i==0){
|
||||
this._remoteStyles = [];
|
||||
}
|
||||
this._remoteStyles.push(dojo.style.insertCssFile(data.linkStyles[i]));
|
||||
}
|
||||
this._setContent(data.xml);
|
||||
|
||||
if(this.parseContent){
|
||||
for(var i = 0; i < data.requires.length; i++){
|
||||
try{
|
||||
eval(data.requires[i]);
|
||||
} catch(e){
|
||||
this._handleDefaults(e, "onContentError", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
// need to allow async load, Xdomain uses it
|
||||
// is inline function because we cant send args to addOnLoad function
|
||||
var _self = this;
|
||||
function asyncParse(){
|
||||
if(_self.executeScripts){
|
||||
_self._executeScripts(data);
|
||||
}
|
||||
|
||||
if(_self.parseContent){
|
||||
var node = _self.containerNode || _self.domNode;
|
||||
var parser = new dojo.xml.Parse();
|
||||
var frag = parser.parseElement(node, null, true);
|
||||
// createSubComponents not createComponents because frag has already been created
|
||||
dojo.widget.getParser().createSubComponents(frag, _self);
|
||||
}
|
||||
|
||||
_self.onResized();
|
||||
_self.onLoad();
|
||||
}
|
||||
// try as long as possible to make setContent sync call
|
||||
if(dojo.hostenv.isXDomain && data.requires.length){
|
||||
dojo.addOnLoad(asyncParse);
|
||||
}else{
|
||||
asyncParse();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Generate pane content from given java function
|
||||
setHandler: function(handler) {
|
||||
var fcn = dojo.lang.isFunction(handler) ? handler : window[handler];
|
||||
if(!dojo.lang.isFunction(fcn)) {
|
||||
// FIXME: needs testing! somebody with java knowledge needs to try this
|
||||
this._handleDefaults("Unable to set handler, '" + handler + "' not a function.", "onExecError", true);
|
||||
return;
|
||||
}
|
||||
this.handler = function() {
|
||||
return fcn.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
|
||||
_runHandler: function() {
|
||||
if(dojo.lang.isFunction(this.handler)) {
|
||||
this.handler(this, this.domNode);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
_executeScripts: function(data) {
|
||||
// do remoteScripts first
|
||||
var self = this;
|
||||
for(var i = 0; i < data.remoteScripts.length; i++){
|
||||
dojo.io.bind({
|
||||
"url": data.remoteScripts[i],
|
||||
"useCash": this.cacheContent,
|
||||
"load": function(type, scriptStr){
|
||||
dojo.lang.hitch(self, data.scripts.push(scriptStr));
|
||||
},
|
||||
"error": function(type, error){
|
||||
self._handleDefaults.call(self, type + " downloading remote script", "onExecError", true);
|
||||
},
|
||||
"mimetype": "text/plain",
|
||||
"sync": true
|
||||
});
|
||||
}
|
||||
|
||||
var scripts = "";
|
||||
for(var i = 0; i < data.scripts.length; i++){
|
||||
scripts += data.scripts[i];
|
||||
}
|
||||
|
||||
try{
|
||||
// initialize a new anonymous container for our script, dont make it part of this widgets scope chain
|
||||
// instead send in a variable that points to this widget, usefull to connect events to onLoad, onUnLoad etc..
|
||||
this.scriptScope = null;
|
||||
this.scriptScope = new (new Function('_container_', scripts+'; return this;'))(self);
|
||||
}catch(e){
|
||||
this._handleDefaults("Error running scripts from content:\n"+e, "onExecError", true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:ContentPane");
|
166
webapp/web/src/widget/html/ContextMenu.js
Normal file
166
webapp/web/src/widget/html/ContextMenu.js
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.ContextMenu");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.widget.ContextMenu");
|
||||
dojo.require("dojo.lang");
|
||||
|
||||
dojo.widget.html.ContextMenu = function(){
|
||||
dojo.widget.ContextMenu.call(this);
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
|
||||
this.isShowing = 0;
|
||||
this.templatePath = dojo.uri.dojoUri("src/widget/templates/HtmlContextMenuTemplate.html");
|
||||
this.templateCssPath = dojo.uri.dojoUri("src/widget/templates/Menu.css");
|
||||
|
||||
this.targetNodeIds = []; // fill this with nodeIds upon widget creation and it only responds to those nodes
|
||||
|
||||
// default event detection method
|
||||
var eventType = "oncontextmenu";
|
||||
|
||||
var doc = document.documentElement || document.body;
|
||||
|
||||
var _blockHide = false;
|
||||
|
||||
this.fillInTemplate = function(args, frag){
|
||||
|
||||
var func = "onOpen";
|
||||
var attached = false;
|
||||
|
||||
// connect with rightclick if oncontextmenu is not around
|
||||
// NOTE: It would be very nice to have a dojo.event.browser.supportsEvent here
|
||||
// NOTE: Opera does not have rightclick events, it is listed here only because
|
||||
// it bails out when connecting with oncontextmenu event
|
||||
|
||||
if((dojo.render.html.khtml && !dojo.render.html.safari) || (dojo.render.html.opera)){
|
||||
eventType = "onmousedown";
|
||||
func = "_checkRightClick";
|
||||
}
|
||||
|
||||
// attach event listeners to our selected nodes
|
||||
for(var i=0; i<this.targetNodeIds.length; i++){
|
||||
var node = document.getElementById(this.targetNodeIds[i]);
|
||||
if(node){
|
||||
dojo.event.connect(node, eventType, this, func);
|
||||
attached = true;
|
||||
}else{
|
||||
// remove this nodeId
|
||||
dojo.debug("Couldent find "+this.targetNodeIds[i]+", cant do ContextMenu on this node");
|
||||
this.targetNodeIds.splice(i,1);
|
||||
}
|
||||
}
|
||||
|
||||
// if we got attached to a node, hide on all non node contextevents
|
||||
if(attached){ func = "_canHide"; }
|
||||
|
||||
dojo.event.connect(doc, eventType, this, func);
|
||||
}
|
||||
|
||||
this.onOpen = function(evt){
|
||||
// if (this.isShowing){ this.onHide(evt); } // propably not needed
|
||||
this.isShowing = 1;
|
||||
|
||||
// if I do this, I cant preventDefault in khtml
|
||||
//evt = dojo.event.browser.fixEvent(evt);
|
||||
|
||||
// stop default contextmenu, needed in khtml
|
||||
if (evt.preventDefault){ evt.preventDefault(); }
|
||||
|
||||
// need to light up this one before we check width and height
|
||||
this.domNode.style.left = "-9999px";
|
||||
this.domNode.style.top = "-9999px";
|
||||
this.domNode.style.display = "block";
|
||||
|
||||
// calculate if menu is going to apear within window
|
||||
// or if its partially out of visable area
|
||||
with(dojo.html){
|
||||
|
||||
var menuW = getInnerWidth(this.domNode);
|
||||
var menuH = getInnerHeight(this.domNode);
|
||||
|
||||
var viewport = getViewportSize();
|
||||
var scrolloffset = getScrollOffset();
|
||||
}
|
||||
|
||||
var minX = viewport[0];
|
||||
var minY = viewport[1];
|
||||
|
||||
var maxX = (viewport[0] + scrolloffset[0]) - menuW;
|
||||
var maxY = (viewport[1] + scrolloffset[1]) - menuH;
|
||||
|
||||
var posX = evt.clientX + scrolloffset[0];
|
||||
var posY = evt.clientY + scrolloffset[1];
|
||||
|
||||
if (posX > maxX){ posX = posX - menuW; }
|
||||
if (posY > maxY){ posY = posY - menuH; }
|
||||
|
||||
this.domNode.style.left = posX + "px";
|
||||
this.domNode.style.top = posY + "px";
|
||||
|
||||
|
||||
// block the onclick that follows this particular right click
|
||||
// not if the eventtrigger is documentElement and always when
|
||||
// we use onmousedown hack
|
||||
_blockHide = (evt.currentTarget!=doc || eventType=='onmousedown');
|
||||
|
||||
//return false; // we propably doesnt need to return false as we dont stop the event as we did before
|
||||
}
|
||||
|
||||
/*
|
||||
* _canHide is meant to block the onHide call that follows the event that triggered
|
||||
* onOpen. This is (hopefully) faster that event.connect and event.disconnect every
|
||||
* time the code executes and it makes connecting with onmousedown event possible
|
||||
* and we dont have to stop the event from bubbling further.
|
||||
*
|
||||
* this code is moved into a separete function because it makes it possible for the
|
||||
* user to connect to a onHide event, if anyone would like that.
|
||||
*/
|
||||
|
||||
this._canHide = function(evt){
|
||||
// block the onclick that follows the same event that turn on contextmenu
|
||||
if(_blockHide){
|
||||
// the onclick check is needed to prevent displaying multiple
|
||||
// menus when we have 2 or more contextmenus loaded and are using
|
||||
// the onmousedown hack
|
||||
if(evt.type=='click' || eventType=='oncontextmenu'){
|
||||
_blockHide = false;
|
||||
return;
|
||||
}else{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.onHide(evt);
|
||||
}
|
||||
|
||||
this.onHide = function(evt){
|
||||
// FIXME: use whatever we use to do more general style setting?
|
||||
this.domNode.style.display = "none";
|
||||
//dojo.event.disconnect(doc, "onclick", this, "onHide");
|
||||
this.isShowing = 0;
|
||||
}
|
||||
|
||||
// callback for rightclicks, needed for browsers that doesnt implement oncontextmenu, konqueror and more?
|
||||
this._checkRightClick = function(evt){
|
||||
|
||||
// for some reason konq comes here even when we are not clicking on the attached nodes
|
||||
// added check for targetnode
|
||||
if (evt.button==2 && (this.targetNodeIds.length==0 || (evt.currentTarget.id!="" && dojo.lang.inArray(this.targetNodeIds, evt.currentTarget.id)))){
|
||||
|
||||
return this.onOpen(evt);
|
||||
}
|
||||
}
|
||||
|
||||
dojo.event.connect(doc, "onclick", this, "_canHide");
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.ContextMenu, dojo.widget.HtmlWidget);
|
346
webapp/web/src/widget/html/DatePicker.js
Normal file
346
webapp/web/src/widget/html/DatePicker.js
Normal file
|
@ -0,0 +1,346 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.DatePicker");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.widget.DatePicker");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.date");
|
||||
|
||||
/*
|
||||
Some assumptions:
|
||||
- I'm planning on always showing 42 days at a time, and we can scroll by week,
|
||||
not just by month or year
|
||||
- To get a sense of what month to highlight, I basically initialize on the
|
||||
first Saturday of each month, since that will be either the first of two or
|
||||
the second of three months being partially displayed, and then I work forwards
|
||||
and backwards from that point.
|
||||
Currently, I assume that dates are stored in the RFC 3339 format,
|
||||
because I find it to be most human readable and easy to parse
|
||||
http://www.faqs.org/rfcs/rfc3339.html: 2005-06-30T08:05:00-07:00
|
||||
*/
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.DatePicker",
|
||||
dojo.widget.HtmlWidget,
|
||||
{
|
||||
classConstructor: function() {
|
||||
// mixin dojo.widget.DatePicker non-demoninational code
|
||||
dojo.widget.DatePicker.call(this);
|
||||
// today's date, JS Date object
|
||||
this.today = "";
|
||||
// selected date, JS Date object
|
||||
this.date = "";
|
||||
// rfc 3339 date
|
||||
this.storedDate = "";
|
||||
// date currently selected in the UI, stored in year, month, date in the format that will be actually displayed
|
||||
this.currentDate = {};
|
||||
// stored in year, month, date in the format that will be actually displayed
|
||||
this.firstSaturday = {};
|
||||
},
|
||||
classNames: {
|
||||
previous: "previousMonth",
|
||||
current: "currentMonth",
|
||||
next: "nextMonth",
|
||||
currentDate: "currentDate",
|
||||
selectedDate: "selectedItem"
|
||||
},
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlDatePicker.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlDatePicker.css"),
|
||||
|
||||
fillInTemplate: function(){
|
||||
dojo.widget.DatePicker.call(this);
|
||||
this.initData();
|
||||
this.initUI();
|
||||
},
|
||||
initData: function() {
|
||||
this.today = new Date();
|
||||
if(this.storedDate && (this.storedDate.split("-").length > 2)) {
|
||||
this.date = dojo.widget.DatePicker.util.fromRfcDate(this.storedDate);
|
||||
} else {
|
||||
this.date = this.today;
|
||||
}
|
||||
// calendar math is simplified if time is set to 0
|
||||
this.today.setHours(0);
|
||||
this.date.setHours(0);
|
||||
var month = this.date.getMonth();
|
||||
var tempSaturday = dojo.widget.DatePicker.util.initFirstSaturday(this.date.getMonth().toString(), this.date.getFullYear());
|
||||
this.firstSaturday.year = tempSaturday.year;
|
||||
this.firstSaturday.month = tempSaturday.month;
|
||||
this.firstSaturday.date = tempSaturday.date;
|
||||
},
|
||||
|
||||
setDate: function(rfcDate) {
|
||||
this.storedDate = rfcDate;
|
||||
},
|
||||
|
||||
initUI: function() {
|
||||
this.selectedIsUsed = false;
|
||||
this.currentIsUsed = false;
|
||||
var currentClassName = "";
|
||||
var previousDate = new Date();
|
||||
var calendarNodes = this.calendarDatesContainerNode.getElementsByTagName("td");
|
||||
var currentCalendarNode;
|
||||
// set hours of date such that there is no chance of rounding error due to
|
||||
// time change in local time zones
|
||||
previousDate.setHours(8);
|
||||
var nextDate = new Date(this.firstSaturday.year, this.firstSaturday.month, this.firstSaturday.date, 8);
|
||||
|
||||
if(this.firstSaturday.date < 7) {
|
||||
// this means there are days to show from the previous month
|
||||
var dayInWeek = 6;
|
||||
for (var i=this.firstSaturday.date; i>0; i--) {
|
||||
currentCalendarNode = calendarNodes.item(dayInWeek);
|
||||
currentCalendarNode.innerHTML = nextDate.getDate();
|
||||
dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "current"));
|
||||
dayInWeek--;
|
||||
previousDate = nextDate;
|
||||
nextDate = this.incrementDate(nextDate, false);
|
||||
}
|
||||
for(var i=dayInWeek; i>-1; i--) {
|
||||
currentCalendarNode = calendarNodes.item(i);
|
||||
currentCalendarNode.innerHTML = nextDate.getDate();
|
||||
dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "previous"));
|
||||
previousDate = nextDate;
|
||||
nextDate = this.incrementDate(nextDate, false);
|
||||
}
|
||||
} else {
|
||||
nextDate.setDate(this.firstSaturday.date-6);
|
||||
for(var i=0; i<7; i++) {
|
||||
currentCalendarNode = calendarNodes.item(i);
|
||||
currentCalendarNode.innerHTML = nextDate.getDate();
|
||||
dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "current"));
|
||||
previousDate = nextDate;
|
||||
nextDate = this.incrementDate(nextDate, true);
|
||||
}
|
||||
}
|
||||
previousDate.setDate(this.firstSaturday.date);
|
||||
previousDate.setMonth(this.firstSaturday.month);
|
||||
previousDate.setFullYear(this.firstSaturday.year);
|
||||
nextDate = this.incrementDate(previousDate, true);
|
||||
var count = 7;
|
||||
currentCalendarNode = calendarNodes.item(count);
|
||||
while((nextDate.getMonth() == previousDate.getMonth()) && (count<42)) {
|
||||
currentCalendarNode.innerHTML = nextDate.getDate();
|
||||
dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "current"));
|
||||
currentCalendarNode = calendarNodes.item(++count);
|
||||
previousDate = nextDate;
|
||||
nextDate = this.incrementDate(nextDate, true);
|
||||
}
|
||||
|
||||
while(count < 42) {
|
||||
currentCalendarNode.innerHTML = nextDate.getDate();
|
||||
dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "next"));
|
||||
currentCalendarNode = calendarNodes.item(++count);
|
||||
previousDate = nextDate;
|
||||
nextDate = this.incrementDate(nextDate, true);
|
||||
}
|
||||
this.setMonthLabel(this.firstSaturday.month);
|
||||
this.setYearLabels(this.firstSaturday.year);
|
||||
},
|
||||
|
||||
incrementDate: function(date, bool) {
|
||||
// bool: true to increase, false to decrease
|
||||
var time = date.getTime();
|
||||
var increment = 1000 * 60 * 60 * 24;
|
||||
time = (bool) ? (time + increment) : (time - increment);
|
||||
var returnDate = new Date();
|
||||
returnDate.setTime(time);
|
||||
return returnDate;
|
||||
},
|
||||
|
||||
incrementWeek: function(evt) {
|
||||
var date = this.firstSaturday.date;
|
||||
var month = this.firstSaturday.month;
|
||||
var year = this.firstSaturday.year;
|
||||
switch(evt.target) {
|
||||
case this.increaseWeekNode.getElementsByTagName("img").item(0):
|
||||
case this.increaseWeekNode:
|
||||
date = date + 7;
|
||||
if (date>this._daysIn(month,year)) {
|
||||
date = date - this._daysIn(month,year);
|
||||
if (month < 11) {
|
||||
month++;
|
||||
} else {
|
||||
month=0;
|
||||
year++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case this.decreaseWeekNode.getElementsByTagName("img").item(0):
|
||||
case this.decreaseWeekNode:
|
||||
if (date > 7) {
|
||||
date = date - 7;
|
||||
} else {
|
||||
var diff = 7 - date;
|
||||
if (month > 0) {
|
||||
month--;
|
||||
date = this._daysIn(month,year) - diff;
|
||||
}else {
|
||||
year--;
|
||||
month=11;
|
||||
date = 31 - diff;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
this.firstSaturday.date=date;
|
||||
this.firstSaturday.month=month;
|
||||
this.firstSaturday.year=year;
|
||||
this.initUI();
|
||||
},
|
||||
|
||||
incrementMonth: function(evt) {
|
||||
var month = this.firstSaturday.month;
|
||||
var year = this.firstSaturday.year;
|
||||
switch(evt.currentTarget) {
|
||||
case this.increaseMonthNode:
|
||||
if(month < 11) {
|
||||
month++;
|
||||
} else {
|
||||
month = 0;
|
||||
year++;
|
||||
|
||||
this.setYearLabels(year);
|
||||
}
|
||||
break;
|
||||
case this.decreaseMonthNode:
|
||||
if(month > 0) {
|
||||
month--;
|
||||
} else {
|
||||
month = 11;
|
||||
year--;
|
||||
this.setYearLabels(year);
|
||||
}
|
||||
break;
|
||||
case this.increaseMonthNode.getElementsByTagName("img").item(0):
|
||||
if(month < 11) {
|
||||
month++;
|
||||
} else {
|
||||
month = 0;
|
||||
year++;
|
||||
this.setYearLabels(year);
|
||||
}
|
||||
break;
|
||||
case this.decreaseMonthNode.getElementsByTagName("img").item(0):
|
||||
if(month > 0) {
|
||||
month--;
|
||||
} else {
|
||||
month = 11;
|
||||
year--;
|
||||
this.setYearLabels(year);
|
||||
}
|
||||
break;
|
||||
}
|
||||
var tempSaturday = dojo.widget.DatePicker.util.initFirstSaturday(month.toString(), year);
|
||||
this.firstSaturday.year = tempSaturday.year;
|
||||
this.firstSaturday.month = tempSaturday.month;
|
||||
this.firstSaturday.date = tempSaturday.date;
|
||||
this.initUI();
|
||||
},
|
||||
|
||||
incrementYear: function(evt) {
|
||||
var year = this.firstSaturday.year;
|
||||
switch(evt.target) {
|
||||
case this.nextYearLabelNode:
|
||||
year++;
|
||||
break;
|
||||
case this.previousYearLabelNode:
|
||||
year--;
|
||||
break;
|
||||
}
|
||||
var tempSaturday = dojo.widget.DatePicker.util.initFirstSaturday(this.firstSaturday.month.toString(), year);
|
||||
this.firstSaturday.year = tempSaturday.year;
|
||||
this.firstSaturday.month = tempSaturday.month;
|
||||
this.firstSaturday.date = tempSaturday.date;
|
||||
this.initUI();
|
||||
},
|
||||
|
||||
_daysIn: function(month,year) {
|
||||
var daysIn = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
||||
|
||||
if (month==1) {
|
||||
return (year%400 == 0) ? 29: (year%100 == 0) ? 28: (year%4 == 0) ? 29: 28;
|
||||
} else {
|
||||
return daysIn[month];
|
||||
}
|
||||
},
|
||||
|
||||
onIncrementDate: function(evt) {
|
||||
dojo.unimplemented('dojo.widget.html.DatePicker.onIncrementDate');
|
||||
},
|
||||
|
||||
onIncrementWeek: function(evt) {
|
||||
evt.stopPropagation();
|
||||
this.incrementWeek(evt);
|
||||
},
|
||||
|
||||
onIncrementMonth: function(evt) {
|
||||
evt.stopPropagation();
|
||||
this.incrementMonth(evt);
|
||||
},
|
||||
|
||||
onIncrementYear: function(evt) {
|
||||
evt.stopPropagation();
|
||||
this.incrementYear(evt);
|
||||
},
|
||||
|
||||
setMonthLabel: function(monthIndex) {
|
||||
this.monthLabelNode.innerHTML = dojo.date.months[monthIndex];
|
||||
},
|
||||
|
||||
setYearLabels: function(year) {
|
||||
this.previousYearLabelNode.innerHTML = year - 1;
|
||||
this.currentYearLabelNode.innerHTML = year;
|
||||
this.nextYearLabelNode.innerHTML = year + 1;
|
||||
},
|
||||
|
||||
getDateClassName: function(date, monthState) {
|
||||
var currentClassName = this.classNames[monthState];
|
||||
if ((!this.selectedIsUsed) && (date.getDate() == this.date.getDate()) && (date.getMonth() == this.date.getMonth()) && (date.getFullYear() == this.date.getFullYear())) {
|
||||
currentClassName = this.classNames.selectedDate + " " + currentClassName;
|
||||
this.selectedIsUsed = 1;
|
||||
}
|
||||
if((!this.currentIsUsed) && (date.getDate() == this.today.getDate()) && (date.getMonth() == this.today.getMonth()) && (date.getFullYear() == this.today.getFullYear())) {
|
||||
currentClassName = currentClassName + " " + this.classNames.currentDate;
|
||||
this.currentIsUsed = 1;
|
||||
}
|
||||
return currentClassName;
|
||||
},
|
||||
|
||||
onClick: function(evt) {
|
||||
dojo.event.browser.stopEvent(evt)
|
||||
},
|
||||
|
||||
onSetDate: function(evt) {
|
||||
dojo.event.browser.stopEvent(evt);
|
||||
this.selectedIsUsed = 0;
|
||||
this.todayIsUsed = 0;
|
||||
var month = this.firstSaturday.month;
|
||||
var year = this.firstSaturday.year;
|
||||
if (dojo.html.hasClass(evt.target, this.classNames["next"])) {
|
||||
month = ++month % 12;
|
||||
// if month is now == 0, add a year
|
||||
year = (month==0) ? ++year : year;
|
||||
} else if (dojo.html.hasClass(evt.target, this.classNames["previous"])) {
|
||||
month = --month % 12;
|
||||
// if month is now == 0, add a year
|
||||
year = (month==11) ? --year : year;
|
||||
}
|
||||
this.date = new Date(year, month, evt.target.innerHTML);
|
||||
this.setDate(dojo.widget.DatePicker.util.toRfcDate(this.date));
|
||||
this.initUI();
|
||||
}
|
||||
}
|
||||
);
|
31
webapp/web/src/widget/html/DebugConsole.js
Normal file
31
webapp/web/src/widget/html/DebugConsole.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.DebugConsole");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.FloatingPane");
|
||||
|
||||
dojo.widget.html.DebugConsole= function(){
|
||||
|
||||
dojo.widget.html.FloatingPane.call(this);
|
||||
dojo.widget.DebugConsole.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.DebugConsole, dojo.widget.html.FloatingPane);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.DebugConsole, {
|
||||
fillInTemplate: function() {
|
||||
dojo.widget.html.DebugConsole.superclass.fillInTemplate.apply(this, arguments);
|
||||
this.containerNode.id = "debugConsoleClientPane";
|
||||
djConfig.isDebug = true;
|
||||
djConfig.debugContainerId = this.containerNode.id;
|
||||
}
|
||||
});
|
210
webapp/web/src/widget/html/DocPane.js
Normal file
210
webapp/web/src/widget/html/DocPane.js
Normal file
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.DocPane");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.io.*");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
|
||||
dojo.widget.html.DocPane = function(){
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
|
||||
this.templatePath = dojo.uri.dojoUri("src/widget/templates/HtmlDocPane.html");
|
||||
this.templateCssPath = dojo.uri.dojoUri("src/widget/templates/HtmlDocPane.css");
|
||||
this.widgetType = "DocPane";
|
||||
this.isContainer = true;
|
||||
|
||||
this.select;
|
||||
this.result;
|
||||
this.fn;
|
||||
this.fnLink;
|
||||
this.count;
|
||||
this.row;
|
||||
this.summary;
|
||||
this.description;
|
||||
this.variables;
|
||||
this.vRow;
|
||||
this.vLink;
|
||||
this.vDesc;
|
||||
this.parameters;
|
||||
this.pRow;
|
||||
this.pLink;
|
||||
this.pDesc;
|
||||
this.pOpt;
|
||||
this.pType;
|
||||
this.source;
|
||||
this.sType;
|
||||
this.sName;
|
||||
this.sParams;
|
||||
this.sPType;
|
||||
this.sPTypeSave;
|
||||
this.sPName;
|
||||
this.sPNameSave;
|
||||
|
||||
dojo.event.topic.subscribe("/doc/results", this, "onDocResults");
|
||||
dojo.event.topic.subscribe("/doc/functionDetail", this, "onDocSelectFunction");
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.DocPane, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.DocPane, {
|
||||
fillInTemplate: function(){
|
||||
this.homeSave = this.containerNode.cloneNode(true);
|
||||
this.selectSave = dojo.dom.removeNode(this.select);
|
||||
this.resultSave = dojo.dom.removeNode(this.result);
|
||||
this.rowParent = this.row.parentNode;
|
||||
this.rowSave = dojo.dom.removeNode(this.row);
|
||||
this.vParent = this.vRow.parentNode;
|
||||
this.vSave = dojo.dom.removeNode(this.vRow);
|
||||
this.pParent = this.pRow.parentNode;
|
||||
this.pSave = dojo.dom.removeNode(this.pRow);
|
||||
this.sPTypeSave = dojo.dom.removeNode(this.sPType);
|
||||
this.sPNameSave = dojo.dom.removeNode(this.sPName);
|
||||
},
|
||||
|
||||
onDocSelectFunction: function(message){
|
||||
var meta = message.meta;
|
||||
if(meta){
|
||||
var variables = meta.variables;
|
||||
var this_variables = meta.this_variables;
|
||||
var child_variables = meta.child_variables;
|
||||
var parameters = meta.parameters;
|
||||
}
|
||||
var doc = message.doc;
|
||||
|
||||
var appends = [];
|
||||
dojo.dom.removeChildren(this.domNode);
|
||||
this.fn.innerHTML = message.name;
|
||||
this.description.innerHTML = doc.description;
|
||||
|
||||
this.variables.style.display = "block";
|
||||
var all = [];
|
||||
if(variables){
|
||||
all = variables;
|
||||
}
|
||||
if(this_variables){
|
||||
all = all.concat(this_variables);
|
||||
}
|
||||
if(child_variables){
|
||||
all = all.concat(child_variables);
|
||||
}
|
||||
if(!all.length){
|
||||
this.variables.style.display = "none";
|
||||
}else{
|
||||
for(var i = 0, one; one = all[i]; i++){
|
||||
this.vLink.innerHTML = one;
|
||||
this.vDesc.parentNode.style.display = "none";
|
||||
appends.push(this.vParent.appendChild(this.vSave.cloneNode(true)));
|
||||
}
|
||||
}
|
||||
|
||||
this.sParams.innerHTML = "";
|
||||
for(var param in parameters){
|
||||
var paramType = parameters[param][0];
|
||||
var paramName = parameters[param][1];
|
||||
this.parameters.style.display = "block";
|
||||
this.pLink.innerHTML = paramName;
|
||||
this.pOpt.style.display = "none";
|
||||
if(parameters[param].opt){
|
||||
this.pOpt.style.display = "inline";
|
||||
}
|
||||
this.pType.parentNode.style.display = "none";
|
||||
if(parameters[param][0]){
|
||||
this.pType.parentNode.style.display = "inline";
|
||||
this.pType.innerHTML = paramType;
|
||||
}
|
||||
this.pDesc.parentNode.style.display = "none";
|
||||
if(doc.parameters[paramName] && doc.parameters[paramName].description){
|
||||
this.pDesc.parentNode.style.display = "inline";
|
||||
this.pDesc.innerHTML = doc.parameters[paramName].description;
|
||||
}
|
||||
appends.push(this.pParent.appendChild(this.pSave.cloneNode(true)));
|
||||
|
||||
if(param > 0) {
|
||||
this.sParams.appendChild(document.createTextNode(", "));
|
||||
}
|
||||
if(paramType){
|
||||
dojo.debug(this.sPTypeSave);
|
||||
this.sPTypeSave.innerHTML = paramType;
|
||||
this.sParams.appendChild(this.sPTypeSave.cloneNode(true));
|
||||
this.sParams.appendChild(document.createTextNode(" "));
|
||||
}
|
||||
dojo.debug(this.sPNameSave);
|
||||
this.sPNameSave.innerHTML = paramName;
|
||||
this.sParams.appendChild(this.sPNameSave.cloneNode(true))
|
||||
}
|
||||
|
||||
if(message.returns){
|
||||
this.sType.innerHTML = message.returns;
|
||||
}else{
|
||||
this.sType.innerHTML = "void";
|
||||
}
|
||||
|
||||
this.sName.innerHTML = message.name;
|
||||
|
||||
dojo.dom.removeChildren(this.source);
|
||||
this.source.appendChild(document.createTextNode("\n\r"));
|
||||
this.source.appendChild(document.createTextNode(message.src.replace(/\n/g, "\r\n\t")));
|
||||
this.source.appendChild(document.createTextNode("\n\r"));
|
||||
|
||||
this.domNode.appendChild(this.selectSave.cloneNode(true));
|
||||
|
||||
for(var i = 0, append; append = appends[i]; i++){
|
||||
dojo.dom.removeNode(append);
|
||||
}
|
||||
},
|
||||
|
||||
onDocResults: function(message){
|
||||
var results = message.docResults;
|
||||
|
||||
if(results.length == 1){
|
||||
dojo.event.topic.publish("/doc/selectFunction", results[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
dojo.dom.removeChildren(this.domNode);
|
||||
|
||||
this.count.innerHTML = results.length;
|
||||
var appends = [];
|
||||
for(var i = 0, row; row = results[i]; i++){
|
||||
this.fnLink.innerHTML = row.name;
|
||||
this.fnLink.href = "#" + row.name;
|
||||
if(row.id){
|
||||
this.fnLink.href = this.fnLink.href + "," + row.id;
|
||||
}
|
||||
this.summary.parentNode.style.display = "none";
|
||||
if(row.summary){
|
||||
this.summary.parentNode.style.display = "inline";
|
||||
this.summary.innerHTML = row.summary;
|
||||
}
|
||||
appends.push(this.rowParent.appendChild(this.rowSave.cloneNode(true)));
|
||||
}
|
||||
|
||||
function makeSelect(x){
|
||||
return function(e) {
|
||||
dojo.event.topic.publish("/doc/selectFunction", x);
|
||||
}
|
||||
}
|
||||
|
||||
this.domNode.appendChild(this.resultSave.cloneNode(true));
|
||||
var as = this.domNode.getElementsByTagName("a");
|
||||
for(var i = 0, a; a = as[i]; i++){
|
||||
dojo.event.connect(a, "onclick", makeSelect(results[i]));
|
||||
}
|
||||
|
||||
for(var i = 0, append; append = appends[i]; i++){
|
||||
this.rowParent.removeChild(append);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:DocPane");
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue