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:
jeb228 2010-01-29 22:13:57 +00:00
commit 4f2e303079
1839 changed files with 235630 additions and 0 deletions

View 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
});

View 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");

View 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';
}
}
);

View 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");
}
});

View 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
View 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");

View 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");

View 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");

View 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 = "&nbsp;";
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";
}
}
}
});

View 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");

View 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");

View 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");

View 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()};
}
}

View 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");

View 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();
}
}
);

View 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");

View 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");
}
});

View 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");

View 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");

View 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");

View 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(){}
});

View 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);
}
}
);

View 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;
}
}));
}
);

View 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() {
}
});

View 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");

View 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");

View 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(); });
}
});

View 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;
}
}
});

View 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");

View 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

View 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;
})();

View 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");

File diff suppressed because it is too large Load diff

View 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");

View 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()};
}
}

View 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);
}

View 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;
}
});

View 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 = "";
}
});

View 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");

File diff suppressed because it is too large Load diff

View 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

View 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);
}
});

View 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");

View 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");

View 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");

View 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 = "&nbsp;";
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);

View 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;
}
}
}
);

View 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);

View 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");

View 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");

View 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>";
}

View 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); }

View 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");
}

View 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?
});

View 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");

View 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;
}
}

View 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");

View 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");

View 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);
}

View 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");

View 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();
}
});

View 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;
}
});

View 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()+"]";
}
});

View 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]);
}
}
}
});

View 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);
}
});

View 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+"]";
}
});

View 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);
}
});

View 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} );
}
});

View 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);
}

View 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");

View 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");

View 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.*");

View 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";
}
);

View 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";
}
);

View 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 = [];
}
);

View 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 = "";
}
);

View 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 = "";
}
);

View 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.*");

View 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;
}

View file

@ -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>

View 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;
}

View 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>

View 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;
}

View file

@ -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>

View 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;
}

View file

@ -0,0 +1,3 @@
<div dojoAttachPoint="domNode">
<iframe dojoAttachPoint="demoNode"></iframe>
</div>

View 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;
}

View file

@ -0,0 +1,3 @@
<div dojoAttachPoint="domNode">
<textarea dojoAttachPoint="sourceNode" rows="100%"></textarea>
</div>

View 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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 859 B

View 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");

View 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" });

View 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;
}
}
}
);

View 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);
}
}
}
);

View 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");

View 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);

View 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();
}
}
);

View 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;
}
});

View 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