Improve output: distinguish between failed assertions (failures) and unexpected exceptions (errors), and print a filtered stack trace for any exception.
This commit is contained in:
commit
4f2e303079
1839 changed files with 235630 additions and 0 deletions
98
webapp/web/src/widget/html/AccordionPane.js
Normal file
98
webapp/web/src/widget/html/AccordionPane.js
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.AccordionPane");
|
||||
dojo.require("dojo.widget.TitlePane");
|
||||
|
||||
dojo.widget.html.AccordionPane = function(){
|
||||
|
||||
dojo.widget.html.TitlePane.call(this);
|
||||
this.widgetType = "AccordionPane";
|
||||
|
||||
this.open=false;
|
||||
this.allowCollapse=true;
|
||||
this.label="";
|
||||
this.open=false;
|
||||
|
||||
this.labelNodeClass="";
|
||||
this.containerNodeClass="";
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.AccordionPane, dojo.widget.html.TitlePane);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.AccordionPane, {
|
||||
postCreate: function() {
|
||||
dojo.widget.html.AccordionPane.superclass.postCreate.call(this);
|
||||
this.domNode.widgetType=this.widgetType;
|
||||
this.setSizes();
|
||||
dojo.html.addClass(this.labelNode, this.labelNodeClass);
|
||||
dojo.html.disableSelection(this.labelNode);
|
||||
dojo.html.addClass(this.containerNode, this.containerNodeClass);
|
||||
},
|
||||
|
||||
collapse: function() {
|
||||
//dojo.fx.html.wipeOut(this.containerNode,250);
|
||||
//var anim = dojo.fx.html.wipe(this.containerNode, 1000, this.containerNode.offsetHeight, 0, null, true);
|
||||
this.containerNode.style.display="none";
|
||||
this.open=false;
|
||||
},
|
||||
|
||||
expand: function() {
|
||||
//dojo.fx.html.wipeIn(this.containerNode,250);
|
||||
this.containerNode.style.display="block";
|
||||
//var anim = dojo.fx.html.wipe(this.containerNode, 1000, 0, this.containerNode.scrollHeight, null, true);
|
||||
this.open=true;
|
||||
},
|
||||
|
||||
getCollapsedHeight: function() {
|
||||
return dojo.style.getOuterHeight(this.labelNode)+1;
|
||||
},
|
||||
|
||||
setSizes: function() {
|
||||
var siblings = this.domNode.parentNode.childNodes;
|
||||
var height=dojo.style.getInnerHeight(this.domNode.parentNode)-this.getCollapsedHeight();
|
||||
|
||||
this.siblingWidgets = [];
|
||||
|
||||
for (var x=0; x<siblings.length; x++) {
|
||||
if (siblings[x].widgetType==this.widgetType) {
|
||||
if (this.domNode != siblings[x]) {
|
||||
var ap = dojo.widget.byNode(siblings[x]);
|
||||
this.siblingWidgets.push(ap);
|
||||
height -= ap.getCollapsedHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var x=0; x<this.siblingWidgets.length; x++) {
|
||||
dojo.style.setOuterHeight(this.siblingWidgets[x].containerNode,height);
|
||||
}
|
||||
|
||||
dojo.style.setOuterHeight(this.containerNode,height);
|
||||
},
|
||||
|
||||
onLabelClick: function() {
|
||||
this.setSizes();
|
||||
if (!this.open) {
|
||||
for (var x=0; x<this.siblingWidgets.length;x++) {
|
||||
if (this.siblingWidgets[x].open) {
|
||||
this.siblingWidgets[x].collapse();
|
||||
}
|
||||
}
|
||||
this.expand();
|
||||
} else {
|
||||
if (this.allowCollapse) {
|
||||
this.collapse();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:AccordionPane");
|
25
webapp/web/src/widget/html/Button2.js
Normal file
25
webapp/web/src/widget/html/Button2.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
// this is a stub that will be removed in 0.4, see ../Button2.html for details
|
||||
|
||||
dojo.provide("dojo.widget.html.Button2");
|
||||
|
||||
dojo.widget.html.Button2 = function(){}
|
||||
dojo.inherits(dojo.widget.html.Button2, dojo.widget.html.Button);
|
||||
dojo.lang.extend(dojo.widget.html.Button2, { widgetType: "Button2" });
|
||||
|
||||
dojo.widget.html.DropDownButton2 = function(){}
|
||||
dojo.inherits(dojo.widget.html.DropDownButton2, dojo.widget.html.DropDownButton);
|
||||
dojo.lang.extend(dojo.widget.html.DropDownButton2, { widgetType: "DropDownButton2" });
|
||||
|
||||
dojo.widget.html.ComboButton2 = function(){}
|
||||
dojo.inherits(dojo.widget.html.ComboButton2, dojo.widget.html.ComboButton);
|
||||
dojo.lang.extend(dojo.widget.html.ComboButton2, { widgetType: "ComboButton2" });
|
82
webapp/web/src/widget/html/Checkbox.js
Normal file
82
webapp/web/src/widget/html/Checkbox.js
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.Checkbox");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.event");
|
||||
dojo.require("dojo.html");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.Checkbox",
|
||||
dojo.widget.HtmlWidget,
|
||||
{
|
||||
widgetType: "Checkbox",
|
||||
|
||||
templatePath: dojo.uri.dojoUri('src/widget/templates/HtmlCheckBox.html'),
|
||||
|
||||
srcOn: dojo.uri.dojoUri('src/widget/templates/check_on.gif'),
|
||||
srcOff: dojo.uri.dojoUri('src/widget/templates/check_off.gif'),
|
||||
srcDisabledOn: dojo.uri.dojoUri('src/widget/templates/check_disabled_on.gif'),
|
||||
srcDisabledOff: dojo.uri.dojoUri('src/widget/templates/check_disabled_off.gif'),
|
||||
srcHoverOn: dojo.uri.dojoUri('src/widget/templates/check_hover_on.gif'),
|
||||
srcHoverOff: dojo.uri.dojoUri('src/widget/templates/check_hover_off.gif'),
|
||||
|
||||
imgSrc: null,
|
||||
|
||||
// parameters
|
||||
disabled: "enabled",
|
||||
name: "",
|
||||
checked: false,
|
||||
tabIndex: -1,
|
||||
|
||||
imgNode: null,
|
||||
inputNode: null,
|
||||
|
||||
postMixInProperties: function(){
|
||||
// set correct source for image before instantiating template
|
||||
this._updateImgSrc();
|
||||
},
|
||||
|
||||
onMouseUp: function(){
|
||||
if(this.disabled == "enabled"){
|
||||
this.checked = !this.checked;
|
||||
this.inputNode.checked = this.checked;
|
||||
this._updateImgSrc();
|
||||
}
|
||||
},
|
||||
|
||||
onMouseOver: function(){
|
||||
this.hover=true;
|
||||
this._updateImgSrc();
|
||||
},
|
||||
|
||||
onMouseOut: function(){
|
||||
this.hover=false;
|
||||
this._updateImgSrc();
|
||||
},
|
||||
|
||||
_updateImgSrc: function(){
|
||||
if(this.disabled == "enabled"){
|
||||
if(this.hover){
|
||||
this.imgSrc = this.checked ? this.srcHoverOn : this.srcHoverOff;
|
||||
}else{
|
||||
this.imgSrc = this.checked ? this.srcOn : this.srcOff;
|
||||
}
|
||||
}else{
|
||||
this.imgSrc = this.checked ? this.srcDisabledOn : this.srcDisabledOff;
|
||||
}
|
||||
if(this.imgNode){
|
||||
this.imgNode.src = this.imgSrc;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
611
webapp/web/src/widget/html/ComboBox.js
Normal file
611
webapp/web/src/widget/html/ComboBox.js
Normal file
|
@ -0,0 +1,611 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.ComboBox");
|
||||
dojo.require("dojo.widget.ComboBox");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.io.*");
|
||||
dojo.require("dojo.lfx.*");
|
||||
dojo.require("dojo.dom");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.string");
|
||||
dojo.require("dojo.widget.html.stabile");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.ComboBox",
|
||||
[dojo.widget.HtmlWidget, dojo.widget.ComboBox],
|
||||
{
|
||||
autoComplete: true,
|
||||
formInputName: "",
|
||||
name: "", // clone in the name from the DOM node
|
||||
textInputNode: null,
|
||||
comboBoxValue: null,
|
||||
comboBoxSelectionValue: null,
|
||||
optionsListWrapper: null,
|
||||
optionsListNode: null,
|
||||
downArrowNode: null,
|
||||
cbTableNode: null,
|
||||
searchTimer: null,
|
||||
searchDelay: 100,
|
||||
dataUrl: "",
|
||||
fadeTime: 200,
|
||||
// maxListLength limits list to X visible rows, scroll on rest
|
||||
maxListLength: 8,
|
||||
// mode can also be "remote" for JSON-returning live search or "html" for
|
||||
// dumber live search
|
||||
mode: "local",
|
||||
selectedResult: null,
|
||||
_highlighted_option: null,
|
||||
_prev_key_backspace: false,
|
||||
_prev_key_esc: false,
|
||||
_result_list_open: false,
|
||||
_gotFocus: false,
|
||||
_mouseover_list: false,
|
||||
dataProviderClass: "dojo.widget.ComboBoxDataProvider",
|
||||
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlComboBox.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlComboBox.css"),
|
||||
|
||||
setValue: function(value) {
|
||||
this.comboBoxValue.value = value;
|
||||
if (this.textInputNode.value != value) { // prevent mucking up of selection
|
||||
this.textInputNode.value = value;
|
||||
}
|
||||
dojo.widget.html.stabile.setState(this.widgetId, this.getState(), true);
|
||||
},
|
||||
|
||||
getValue: function() {
|
||||
return this.comboBoxValue.value;
|
||||
},
|
||||
|
||||
getState: function() {
|
||||
return {value: this.getValue()};
|
||||
},
|
||||
|
||||
setState: function(state) {
|
||||
this.setValue(state.value);
|
||||
},
|
||||
|
||||
getCaretPos: function(element){
|
||||
// khtml 3.5.2 has selection* methods as does webkit nightlies from 2005-06-22
|
||||
if(dojo.lang.isNumber(element.selectionStart)){
|
||||
// FIXME: this is totally borked on Moz < 1.3. Any recourse?
|
||||
return element.selectionStart;
|
||||
}else if(dojo.render.html.ie){
|
||||
// in the case of a mouse click in a popup being handled,
|
||||
// then the document.selection is not the textarea, but the popup
|
||||
// var r = document.selection.createRange();
|
||||
// hack to get IE 6 to play nice. What a POS browser.
|
||||
var tr = document.selection.createRange().duplicate();
|
||||
var ntr = element.createTextRange();
|
||||
tr.move("character",0);
|
||||
ntr.move("character",0);
|
||||
try {
|
||||
// If control doesnt have focus, you get an exception.
|
||||
// Seems to happen on reverse-tab, but can also happen on tab (seems to be a race condition - only happens sometimes).
|
||||
// There appears to be no workaround for this - googled for quite a while.
|
||||
ntr.setEndPoint("EndToEnd", tr);
|
||||
return String(ntr.text).replace(/\r/g,"").length;
|
||||
} catch (e) {
|
||||
return 0; // If focus has shifted, 0 is fine for caret pos.
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
setCaretPos: function(element, location){
|
||||
location = parseInt(location);
|
||||
this.setSelectedRange(element, location, location);
|
||||
},
|
||||
|
||||
setSelectedRange: function(element, start, end){
|
||||
if(!end){ end = element.value.length; } // NOTE: Strange - should be able to put caret at start of text?
|
||||
// Mozilla
|
||||
// parts borrowed from http://www.faqts.com/knowledge_base/view.phtml/aid/13562/fid/130
|
||||
if(element.setSelectionRange){
|
||||
element.focus();
|
||||
element.setSelectionRange(start, end);
|
||||
}else if(element.createTextRange){ // IE
|
||||
var range = element.createTextRange();
|
||||
with(range){
|
||||
collapse(true);
|
||||
moveEnd('character', end);
|
||||
moveStart('character', start);
|
||||
select();
|
||||
}
|
||||
}else{ //otherwise try the event-creation hack (our own invention)
|
||||
// do we need these?
|
||||
element.value = element.value;
|
||||
element.blur();
|
||||
element.focus();
|
||||
// figure out how far back to go
|
||||
var dist = parseInt(element.value.length)-end;
|
||||
var tchar = String.fromCharCode(37);
|
||||
var tcc = tchar.charCodeAt(0);
|
||||
for(var x = 0; x < dist; x++){
|
||||
var te = document.createEvent("KeyEvents");
|
||||
te.initKeyEvent("keypress", true, true, null, false, false, false, false, tcc, tcc);
|
||||
element.dispatchEvent(te);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// does the keyboard related stuff
|
||||
_handleKeyEvents: function(evt){
|
||||
if(evt.ctrlKey || evt.altKey){ return; }
|
||||
|
||||
// reset these
|
||||
this._prev_key_backspace = false;
|
||||
this._prev_key_esc = false;
|
||||
|
||||
var k = dojo.event.browser.keys;
|
||||
var doSearch = true;
|
||||
|
||||
// mozilla quirk
|
||||
// space has no keyCode in mozilla
|
||||
var keyCode = evt.keyCode;
|
||||
if(keyCode==0 && evt.charCode==k.KEY_SPACE){
|
||||
keyCode = k.KEY_SPACE;
|
||||
}
|
||||
switch(keyCode){
|
||||
case k.KEY_DOWN_ARROW:
|
||||
if(!this._result_list_open){
|
||||
this.startSearchFromInput();
|
||||
}
|
||||
this.highlightNextOption();
|
||||
dojo.event.browser.stopEvent(evt);
|
||||
return;
|
||||
case k.KEY_UP_ARROW:
|
||||
this.highlightPrevOption();
|
||||
dojo.event.browser.stopEvent(evt);
|
||||
return;
|
||||
case k.KEY_ENTER:
|
||||
// prevent submitting form if we press enter with list open
|
||||
if(this._result_list_open){
|
||||
dojo.event.browser.stopEvent(evt);
|
||||
}
|
||||
// fallthrough
|
||||
case k.KEY_TAB:
|
||||
// using linux alike tab for autocomplete
|
||||
if(!this.autoComplete && this._result_list_open && this._highlighted_option){
|
||||
dojo.event.browser.stopEvent(evt);
|
||||
this.selectOption({ 'target': this._highlighted_option, 'noHide': true });
|
||||
|
||||
// put caret last
|
||||
this.setSelectedRange(this.textInputNode, this.textInputNode.value.length, null);
|
||||
}else{
|
||||
this.selectOption();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case k.KEY_SPACE:
|
||||
if(this._result_list_open && this._highlighted_option){
|
||||
dojo.event.browser.stopEvent(evt);
|
||||
this.selectOption();
|
||||
this.hideResultList();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case k.KEY_ESCAPE:
|
||||
this.hideResultList();
|
||||
this._prev_key_esc = true;
|
||||
return;
|
||||
case k.KEY_BACKSPACE:
|
||||
this._prev_key_backspace = true;
|
||||
if(!this.textInputNode.value.length){
|
||||
this.setAllValues("", "");
|
||||
this.hideResultList();
|
||||
doSearch = false;
|
||||
}
|
||||
break;
|
||||
case k.KEY_RIGHT_ARROW: // fall through
|
||||
case k.KEY_LEFT_ARROW: // fall through
|
||||
case k.KEY_SHIFT:
|
||||
doSearch = false;
|
||||
break;
|
||||
default:// non char keys (F1-F12 etc..) shouldn't open list
|
||||
if(evt.charCode==0){
|
||||
doSearch = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(this.searchTimer){
|
||||
clearTimeout(this.searchTimer);
|
||||
}
|
||||
if(doSearch){
|
||||
// if we have gotten this far we dont want to keep our highlight
|
||||
this.blurOptionNode();
|
||||
|
||||
// need to wait a tad before start search so that the event bubbles through DOM and we have value visible
|
||||
this.searchTimer = setTimeout(dojo.lang.hitch(this, this.startSearchFromInput), this.searchDelay);
|
||||
}
|
||||
},
|
||||
|
||||
onKeyDown: function(evt){
|
||||
// IE needs to stop keyDown others need to stop keyPress
|
||||
if(!document.createEvent){ // only IE
|
||||
this._handleKeyEvents(evt);
|
||||
}
|
||||
// FIXME: What about ESC ??
|
||||
},
|
||||
|
||||
onKeyPress: function(evt){
|
||||
if(document.createEvent){ // never IE
|
||||
this._handleKeyEvents(evt);
|
||||
}
|
||||
},
|
||||
|
||||
onKeyUp: function(evt){
|
||||
this.setValue(this.textInputNode.value);
|
||||
},
|
||||
|
||||
setSelectedValue: function(value){
|
||||
// FIXME, not sure what to do here!
|
||||
this.comboBoxSelectionValue.value = value;
|
||||
},
|
||||
|
||||
setAllValues: function(value1, value2){
|
||||
this.setValue(value1);
|
||||
this.setSelectedValue(value2);
|
||||
},
|
||||
|
||||
// opera, khtml, safari doesnt support node.scrollIntoView(), workaround
|
||||
scrollIntoView: function(){
|
||||
var node = this._highlighted_option;
|
||||
var parent = this.optionsListNode;
|
||||
// don't rely on that node.scrollIntoView works just because the function is there
|
||||
// it doesnt work in Konqueror or Opera even though the function is there and probably
|
||||
// not safari either
|
||||
// dont like browser sniffs implementations but sometimes you have to use it
|
||||
if(dojo.render.html.ie || dojo.render.html.mozilla){
|
||||
// IE, mozilla
|
||||
node.scrollIntoView(false);
|
||||
}else{
|
||||
var parentBottom = parent.scrollTop + dojo.style.getInnerHeight(parent);
|
||||
var nodeBottom = node.offsetTop + dojo.style.getOuterHeight(node);
|
||||
if(parentBottom < nodeBottom){
|
||||
parent.scrollTop += (nodeBottom - parentBottom);
|
||||
}else if(parent.scrollTop > node.offsetTop){
|
||||
parent.scrollTop -= (parent.scrollTop - node.offsetTop);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// does the actual highlight
|
||||
focusOptionNode: function(node){
|
||||
if(this._highlighted_option != node){
|
||||
this.blurOptionNode();
|
||||
this._highlighted_option = node;
|
||||
dojo.html.addClass(this._highlighted_option, "dojoComboBoxItemHighlight");
|
||||
}
|
||||
},
|
||||
|
||||
// removes highlight on highlighted
|
||||
blurOptionNode: function(){
|
||||
if(this._highlighted_option){
|
||||
dojo.html.removeClass(this._highlighted_option, "dojoComboBoxItemHighlight");
|
||||
this._highlighted_option = null;
|
||||
}
|
||||
},
|
||||
|
||||
highlightNextOption: function(){
|
||||
if((!this._highlighted_option) || !this._highlighted_option.parentNode){
|
||||
this.focusOptionNode(this.optionsListNode.firstChild);
|
||||
}else if(this._highlighted_option.nextSibling){
|
||||
this.focusOptionNode(this._highlighted_option.nextSibling);
|
||||
}
|
||||
this.scrollIntoView();
|
||||
},
|
||||
|
||||
highlightPrevOption: function(){
|
||||
if(this._highlighted_option && this._highlighted_option.previousSibling){
|
||||
this.focusOptionNode(this._highlighted_option.previousSibling);
|
||||
}else{
|
||||
this._highlighted_option = null;
|
||||
this.hideResultList();
|
||||
return;
|
||||
}
|
||||
this.scrollIntoView();
|
||||
},
|
||||
|
||||
itemMouseOver: function(evt){
|
||||
this.focusOptionNode(evt.target);
|
||||
dojo.html.addClass(this._highlighted_option, "dojoComboBoxItemHighlight");
|
||||
},
|
||||
|
||||
itemMouseOut: function(evt){
|
||||
this.blurOptionNode();
|
||||
},
|
||||
|
||||
fillInTemplate: function(args, frag){
|
||||
// FIXME: need to get/assign DOM node names for form participation here.
|
||||
this.comboBoxValue.name = this.name;
|
||||
this.comboBoxSelectionValue.name = this.name+"_selected";
|
||||
|
||||
var source = this.getFragNodeRef(frag);
|
||||
dojo.html.copyStyle(this.domNode, source);
|
||||
|
||||
var dpClass;
|
||||
if(this.mode == "remote"){
|
||||
dpClass = dojo.widget.incrementalComboBoxDataProvider;
|
||||
}else if(typeof this.dataProviderClass == "string"){
|
||||
dpClass = dojo.evalObjPath(this.dataProviderClass)
|
||||
}else{
|
||||
dpClass = this.dataProviderClass;
|
||||
}
|
||||
this.dataProvider = new dpClass();
|
||||
this.dataProvider.init(this, this.getFragNodeRef(frag));
|
||||
|
||||
// Prevent IE bleed-through problem
|
||||
this.optionsIframe = new dojo.html.BackgroundIframe(this.optionsListWrapper);
|
||||
this.optionsIframe.size([0,0,0,0]);
|
||||
},
|
||||
|
||||
|
||||
focus: function(){
|
||||
// summary
|
||||
// set focus to input node from code
|
||||
this.tryFocus();
|
||||
},
|
||||
|
||||
openResultList: function(results){
|
||||
this.clearResultList();
|
||||
if(!results.length){
|
||||
this.hideResultList();
|
||||
}
|
||||
|
||||
if( (this.autoComplete)&&
|
||||
(results.length)&&
|
||||
(!this._prev_key_backspace)&&
|
||||
(this.textInputNode.value.length > 0)){
|
||||
var cpos = this.getCaretPos(this.textInputNode);
|
||||
// only try to extend if we added the last character at the end of the input
|
||||
if((cpos+1) > this.textInputNode.value.length){
|
||||
// only add to input node as we would overwrite Capitalisation of chars
|
||||
this.textInputNode.value += results[0][0].substr(cpos);
|
||||
// build a new range that has the distance from the earlier
|
||||
// caret position to the end of the first string selected
|
||||
this.setSelectedRange(this.textInputNode, cpos, this.textInputNode.value.length);
|
||||
}
|
||||
}
|
||||
|
||||
var even = true;
|
||||
while(results.length){
|
||||
var tr = results.shift();
|
||||
if(tr){
|
||||
var td = document.createElement("div");
|
||||
td.appendChild(document.createTextNode(tr[0]));
|
||||
td.setAttribute("resultName", tr[0]);
|
||||
td.setAttribute("resultValue", tr[1]);
|
||||
td.className = "dojoComboBoxItem "+((even) ? "dojoComboBoxItemEven" : "dojoComboBoxItemOdd");
|
||||
even = (!even);
|
||||
this.optionsListNode.appendChild(td);
|
||||
dojo.event.connect(td, "onmouseover", this, "itemMouseOver");
|
||||
dojo.event.connect(td, "onmouseout", this, "itemMouseOut");
|
||||
}
|
||||
}
|
||||
|
||||
// show our list (only if we have content, else nothing)
|
||||
this.showResultList();
|
||||
},
|
||||
|
||||
onFocusInput: function(){
|
||||
this._hasFocus = true;
|
||||
},
|
||||
|
||||
onBlurInput: function(){
|
||||
this._hasFocus = false;
|
||||
this._handleBlurTimer(true, 500);
|
||||
},
|
||||
|
||||
// collect all blur timers issues here
|
||||
_handleBlurTimer: function(/*Boolean*/clear, /*Number*/ millisec){
|
||||
if(this.blurTimer && (clear || millisec)){
|
||||
clearTimeout(this.blurTimer);
|
||||
}
|
||||
if(millisec){ // we ignore that zero is false and never sets as that never happens in this widget
|
||||
this.blurTimer = dojo.lang.setTimeout(this, "checkBlurred", millisec);
|
||||
}
|
||||
},
|
||||
|
||||
// these 2 are needed in IE and Safari as inputTextNode loses focus when scrolling optionslist
|
||||
_onMouseOver: function(evt){
|
||||
if(!this._mouseover_list){
|
||||
this._handleBlurTimer(true, 0);
|
||||
this._mouseover_list = true;
|
||||
}
|
||||
},
|
||||
|
||||
_onMouseOut:function(evt){
|
||||
var relTarget = evt.relatedTarget;
|
||||
if(!relTarget || relTarget.parentNode!=this.optionsListNode){
|
||||
this._mouseover_list = false;
|
||||
this._handleBlurTimer(true, 100);
|
||||
this.tryFocus();
|
||||
}
|
||||
},
|
||||
|
||||
_isInputEqualToResult: function(result){
|
||||
input = this.textInputNode.value;
|
||||
if(!this.dataProvider.caseSensitive){
|
||||
input = input.toLowerCase();
|
||||
result = result.toLowerCase();
|
||||
}
|
||||
return (input == result);
|
||||
},
|
||||
|
||||
_isValidOption: function(){
|
||||
tgt = dojo.dom.firstElement(this.optionsListNode);
|
||||
isValidOption = false;
|
||||
while(!isValidOption && tgt){
|
||||
if(this._isInputEqualToResult(tgt.getAttribute("resultName"))){
|
||||
isValidOption = true;
|
||||
}else{
|
||||
tgt = dojo.dom.nextElement(tgt);
|
||||
}
|
||||
}
|
||||
return isValidOption;
|
||||
},
|
||||
|
||||
checkBlurred: function(){
|
||||
if(!this._hasFocus && !this._mouseover_list){
|
||||
this.hideResultList();
|
||||
// clear the list if the user empties field and moves away.
|
||||
if(!this.textInputNode.value.length){
|
||||
this.setAllValues("", "");
|
||||
return;
|
||||
}
|
||||
|
||||
isValidOption = this._isValidOption();
|
||||
// enforce selection from option list
|
||||
if(this.forceValidOption && !isValidOption){
|
||||
this.setAllValues("", "");
|
||||
return;
|
||||
}
|
||||
if(!isValidOption){// clear
|
||||
this.setSelectedValue("");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
sizeBackgroundIframe: function(){
|
||||
var w = dojo.style.getOuterWidth(this.optionsListNode);
|
||||
var h = dojo.style.getOuterHeight(this.optionsListNode);
|
||||
if( w==0 || h==0 ){
|
||||
// need more time to calculate size
|
||||
dojo.lang.setTimeout(this, "sizeBackgroundIframe", 100);
|
||||
return;
|
||||
}
|
||||
if(this._result_list_open){
|
||||
this.optionsIframe.size([0,0,w,h]);
|
||||
}
|
||||
},
|
||||
|
||||
selectOption: function(evt){
|
||||
var tgt = null;
|
||||
if(!evt){
|
||||
evt = { target: this._highlighted_option };
|
||||
}
|
||||
|
||||
if(!dojo.dom.isDescendantOf(evt.target, this.optionsListNode)){
|
||||
// handle autocompletion where the the user has hit ENTER or TAB
|
||||
|
||||
// if the input is empty do nothing
|
||||
if(!this.textInputNode.value.length){
|
||||
return;
|
||||
}
|
||||
tgt = dojo.dom.firstElement(this.optionsListNode);
|
||||
|
||||
// user has input value not in option list
|
||||
if(!tgt || !this._isInputEqualToResult(tgt.getAttribute("resultName"))){
|
||||
return;
|
||||
}
|
||||
// otherwise the user has accepted the autocompleted value
|
||||
}else{
|
||||
tgt = evt.target;
|
||||
}
|
||||
|
||||
while((tgt.nodeType!=1)||(!tgt.getAttribute("resultName"))){
|
||||
tgt = tgt.parentNode;
|
||||
if(tgt === document.body){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
this.textInputNode.value = tgt.getAttribute("resultName");
|
||||
this.selectedResult = [tgt.getAttribute("resultName"), tgt.getAttribute("resultValue")];
|
||||
this.setAllValues(tgt.getAttribute("resultName"), tgt.getAttribute("resultValue"));
|
||||
if(!evt.noHide){
|
||||
this.hideResultList();
|
||||
this.setSelectedRange(this.textInputNode, 0, null);
|
||||
}
|
||||
this.tryFocus();
|
||||
},
|
||||
|
||||
clearResultList: function(){
|
||||
var oln = this.optionsListNode;
|
||||
while(oln.firstChild){
|
||||
dojo.event.disconnect(oln.firstChild, "onmouseover", this, "itemMouseOver");
|
||||
dojo.event.disconnect(oln.firstChild, "onmouseout", this, "itemMouseOut");
|
||||
oln.removeChild(oln.firstChild);
|
||||
}
|
||||
},
|
||||
|
||||
hideResultList: function(){
|
||||
if(this._result_list_open){
|
||||
this._result_list_open = false;
|
||||
this.optionsIframe.size([0,0,0,0]);
|
||||
dojo.lfx.fadeHide(this.optionsListNode, this.fadeTime).play();
|
||||
}
|
||||
},
|
||||
|
||||
showResultList: function(){
|
||||
// Our dear friend IE doesnt take max-height so we need to calculate that on our own every time
|
||||
var childs = this.optionsListNode.childNodes;
|
||||
if(childs.length){
|
||||
var visibleCount = this.maxListLength;
|
||||
if(childs.length < visibleCount){
|
||||
visibleCount = childs.length;
|
||||
}
|
||||
|
||||
with(this.optionsListNode.style){
|
||||
display = "";
|
||||
height = ((visibleCount) ? (dojo.style.getOuterHeight(childs[0]) * visibleCount) : 0)+"px";
|
||||
width = dojo.html.getOuterWidth(this.cbTableNode)-2+"px";
|
||||
}
|
||||
// only fadein once (flicker)
|
||||
if(!this._result_list_open){
|
||||
dojo.html.setOpacity(this.optionsListNode, 0);
|
||||
dojo.lfx.fadeIn(this.optionsListNode, this.fadeTime).play();
|
||||
}
|
||||
|
||||
// prevent IE bleed through
|
||||
this._iframeTimer = dojo.lang.setTimeout(this, "sizeBackgroundIframe", 200);
|
||||
this._result_list_open = true;
|
||||
}else{
|
||||
this.hideResultList();
|
||||
}
|
||||
},
|
||||
|
||||
handleArrowClick: function(){
|
||||
this._handleBlurTimer(true, 0);
|
||||
this.tryFocus();
|
||||
if(this._result_list_open){
|
||||
this.hideResultList();
|
||||
}else{
|
||||
this.startSearchFromInput();
|
||||
}
|
||||
},
|
||||
|
||||
tryFocus: function(){
|
||||
try {
|
||||
this.textInputNode.focus();
|
||||
} catch (e) {
|
||||
// element isn't focusable if disabled, or not visible etc - not easy to test for.
|
||||
};
|
||||
},
|
||||
|
||||
startSearchFromInput: function(){
|
||||
this.startSearch(this.textInputNode.value);
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
dojo.event.connect(this, "startSearch", this.dataProvider, "startSearch");
|
||||
dojo.event.connect(this.dataProvider, "provideSearchResults", this, "openResultList");
|
||||
dojo.event.connect(this.textInputNode, "onblur", this, "onBlurInput");
|
||||
dojo.event.connect(this.textInputNode, "onfocus", this, "onFocusInput");
|
||||
|
||||
var s = dojo.widget.html.stabile.getState(this.widgetId);
|
||||
if (s) {
|
||||
this.setState(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
566
webapp/web/src/widget/html/ContentPane.js
Normal file
566
webapp/web/src/widget/html/ContentPane.js
Normal file
|
@ -0,0 +1,566 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.ContentPane");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.io.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.widget.ContentPane");
|
||||
dojo.require("dojo.string");
|
||||
dojo.require("dojo.string.extras");
|
||||
dojo.require("dojo.style");
|
||||
|
||||
dojo.widget.html.ContentPane = function(){
|
||||
this._onLoadStack = [];
|
||||
this._onUnLoadStack = [];
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.ContentPane, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.ContentPane, {
|
||||
widgetType: "ContentPane",
|
||||
isContainer: true,
|
||||
|
||||
// remote loading options
|
||||
adjustPaths: true,
|
||||
href: "",
|
||||
extractContent: true,
|
||||
parseContent: true,
|
||||
cacheContent: true,
|
||||
preload: false, // force load of data even if pane is hidden
|
||||
refreshOnShow: false,
|
||||
handler: "", // generate pane content from a java function
|
||||
executeScripts: false, // if true scripts in content will be evaled after content is set and parsed
|
||||
scriptScope: null, // scopeContainer for downloaded scripts
|
||||
|
||||
// If the user want a global in the remote script he/she just omitts the var
|
||||
// examples:
|
||||
//--------------------------
|
||||
// these gets collected by scriptScope and is reached by dojo.widget.byId('..').scriptScope.myCustomproperty
|
||||
// this.myString = "dojo is a great javascript toolkit!";
|
||||
//
|
||||
// this.alertMyString = function(){
|
||||
// alert(myString);
|
||||
// }
|
||||
// -------------------------
|
||||
// these go into the global namespace (window) notice lack of var, equiv to window.myString
|
||||
// myString = "dojo is a javascript toolkit!";
|
||||
//
|
||||
// alertMyString = function(){
|
||||
// alert(myString);
|
||||
// }
|
||||
|
||||
|
||||
// private
|
||||
_remoteStyles: null, // array of stylenodes inserted to document head
|
||||
// by remote content, used when we clean up for new content
|
||||
|
||||
_callOnUnLoad: false, // used by setContent and _handleDefults, makes sure onUnLoad is only called once
|
||||
|
||||
postCreate: function(args, frag, parentComp){
|
||||
if ( this.handler != "" ){
|
||||
this.setHandler(this.handler);
|
||||
}
|
||||
if(this.isShowing()||this.preload){ this.loadContents(); }
|
||||
},
|
||||
|
||||
show: function(){
|
||||
// if refreshOnShow is true, reload the contents every time; otherwise, load only the first time
|
||||
if(this.refreshOnShow){
|
||||
this.refresh();
|
||||
}else{
|
||||
this.loadContents();
|
||||
}
|
||||
dojo.widget.html.ContentPane.superclass.show.call(this);
|
||||
},
|
||||
|
||||
refresh: function(){
|
||||
this.isLoaded=false;
|
||||
this.loadContents();
|
||||
},
|
||||
|
||||
loadContents: function() {
|
||||
if ( this.isLoaded ){
|
||||
return;
|
||||
}
|
||||
this.isLoaded=true;
|
||||
if ( dojo.lang.isFunction(this.handler)) {
|
||||
this._runHandler();
|
||||
} else if ( this.href != "" ) {
|
||||
this._downloadExternalContent(this.href, this.cacheContent);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
setUrl: function(/*String*/ url) {
|
||||
// summary:
|
||||
// Reset the (external defined) content of this pane and replace with new url
|
||||
this.href = url;
|
||||
this.isLoaded = false;
|
||||
if ( this.preload || this.isShowing() ){
|
||||
this.loadContents();
|
||||
}
|
||||
},
|
||||
|
||||
_downloadExternalContent: function(url, useCache) {
|
||||
this._handleDefaults("Loading...", "onDownloadStart");
|
||||
var self = this;
|
||||
dojo.io.bind({
|
||||
url: url,
|
||||
useCache: useCache,
|
||||
preventCache: !useCache,
|
||||
mimetype: "text/html",
|
||||
handler: function(type, data, e) {
|
||||
if(type == "load") {
|
||||
self.onDownloadEnd.call(self, url, data);
|
||||
} else {
|
||||
// works best when from a live server instead of from file system
|
||||
self._handleDefaults.call(self, "Error loading '" + url + "' (" + e.status + " "+ e.statusText + ")", "onDownloadError");
|
||||
self.onLoad();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// called when setContent is finished
|
||||
onLoad: function(e){
|
||||
this._runStack("_onLoadStack");
|
||||
},
|
||||
|
||||
// called before old content is cleared
|
||||
onUnLoad: function(e){
|
||||
this._runStack("_onUnLoadStack");
|
||||
this.scriptScope = null;
|
||||
},
|
||||
|
||||
_runStack: function(stName){
|
||||
var st = this[stName]; var err = "";
|
||||
for(var i = 0;i < st.length; i++){
|
||||
try{
|
||||
st[i].call(this.scriptScope);
|
||||
}catch(e){
|
||||
err += "\n"+st[i]+" failed: "+e.description;
|
||||
}
|
||||
}
|
||||
this[stName] = [];
|
||||
|
||||
if(err.length){
|
||||
var name = (stName== "_onLoadStack") ? "addOnLoad" : "addOnUnLoad";
|
||||
this._handleDefaults(name+" failure\n "+err, "onExecError", true);
|
||||
}
|
||||
},
|
||||
|
||||
addOnLoad: function(obj, func){
|
||||
// summary
|
||||
// same as to dojo.addOnLoad but does not take "function_name" as a string
|
||||
this._pushOnStack(this._onLoadStack, obj, func);
|
||||
},
|
||||
|
||||
addOnUnLoad: function(obj, func){
|
||||
// summary
|
||||
// same as to dojo.addUnOnLoad but does not take "function_name" as a string
|
||||
this._pushOnStack(this._onUnLoadStack, obj, func);
|
||||
},
|
||||
|
||||
_pushOnStack: function(stack, obj, func){
|
||||
if(typeof func == 'undefined') {
|
||||
stack.push(obj);
|
||||
}else{
|
||||
stack.push(function(){ obj[func](); });
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function(){
|
||||
// make sure we call onUnLoad
|
||||
this.onUnLoad();
|
||||
dojo.widget.html.ContentPane.superclass.destroy.call(this);
|
||||
},
|
||||
|
||||
// called when content script eval error or Java error occurs, preventDefault-able
|
||||
onExecError: function(e){ /*stub*/ },
|
||||
|
||||
// called on DOM faults, require fault etc in content, preventDefault-able
|
||||
onContentError: function(e){ /*stub*/ },
|
||||
|
||||
// called when download error occurs, preventDefault-able
|
||||
onDownloadError: function(e){ /*stub*/ },
|
||||
|
||||
// called before download starts, preventDefault-able
|
||||
onDownloadStart: function(e){ /*stub*/ },
|
||||
|
||||
// called when download is finished
|
||||
onDownloadEnd: function(url, data){
|
||||
data = this.splitAndFixPaths(data, url);
|
||||
this.setContent(data);
|
||||
},
|
||||
|
||||
// usefull if user wants to prevent default behaviour ie: _setContent("Error...")
|
||||
_handleDefaults: function(e, handler, useAlert){
|
||||
if(!handler){ handler = "onContentError"; }
|
||||
if(dojo.lang.isString(e)){
|
||||
e = {
|
||||
"text": e,
|
||||
"toString": function(){ return this.text; }
|
||||
}
|
||||
}
|
||||
if(typeof e.returnValue != "boolean"){
|
||||
e.returnValue = true;
|
||||
}
|
||||
if(typeof e.preventDefault != "function"){
|
||||
e.preventDefault = function(){
|
||||
this.returnValue = false;
|
||||
}
|
||||
}
|
||||
// call our handler
|
||||
this[handler](e);
|
||||
if(e.returnValue){
|
||||
if(useAlert){
|
||||
alert(e.toString());
|
||||
}else{
|
||||
if(this._callOnUnLoad){
|
||||
this.onUnLoad(); // makes sure scripts can clean up after themselves, before we setContent
|
||||
}
|
||||
this._callOnUnLoad = false; // makes sure we dont try to call onUnLoad again on this event,
|
||||
// ie onUnLoad before 'Loading...' but not before clearing 'Loading...'
|
||||
this._setContent(e.toString());
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
splitAndFixPaths: function(/*String*/s, /*dojo.uri.Uri?*/url){
|
||||
// summary:
|
||||
// fixes all remote paths in (hopefully) all cases for example images, remote scripts, links etc.
|
||||
// splits up content in different pieces, scripts, title, style, link and whats left becomes .xml
|
||||
|
||||
if(!url) { url = "./"; } // point to this page if not set
|
||||
if(!s) { return ""; }
|
||||
|
||||
// fix up paths in data
|
||||
var titles = []; var scripts = []; var linkStyles = [];
|
||||
var styles = []; var remoteScripts = []; var requires = [];
|
||||
|
||||
// khtml is much more picky about dom faults, you can't for example attach a style node under body of document
|
||||
// must go into head, as does a title node, so we need to cut out those tags
|
||||
// cut out title tags
|
||||
var match = [];
|
||||
while(match){
|
||||
match = s.match(/<title[^>]*>([\s\S]*?)<\/title>/i); // can't match with dot as that
|
||||
if(!match){ break;} //doesnt match newline in js
|
||||
titles.push(match[1]);
|
||||
s = s.replace(/<title[^>]*>[\s\S]*?<\/title>/i, "");
|
||||
}
|
||||
|
||||
// cut out <style> url(...) </style>, as that bails out in khtml
|
||||
var match = [];
|
||||
while(match){
|
||||
match = s.match(/<style[^>]*>([\s\S]*?)<\/style>/i);
|
||||
if(!match){ break; }
|
||||
styles.push(dojo.style.fixPathsInCssText(match[1], url));
|
||||
s = s.replace(/<style[^>]*?>[\s\S]*?<\/style>/i, "");
|
||||
}
|
||||
|
||||
// attributepaths one tag can have multiple paths example:
|
||||
// <input src="..." style="url(..)"/> or <a style="url(..)" href="..">
|
||||
// strip out the tag and run fix on that.
|
||||
// this guarantees that we won't run replace another tag's attribute + it was easier do
|
||||
var pos = 0; var pos2 = 0; var stop = 0 ;var str = ""; var fixedPath = "";
|
||||
var attr = []; var fix = ""; var tagFix = ""; var tag = ""; var regex = "";
|
||||
while(pos>-1){
|
||||
pos = s.search(/<[a-z][a-z0-9]*[^>]*\s(?:(?:src|href|style)=[^>])+[^>]*>/i);
|
||||
if(pos==-1){ break; }
|
||||
str += s.substring(0, pos);
|
||||
s = s.substring(pos, s.length);
|
||||
tag = s.match(/^<[a-z][a-z0-9]*[^>]*>/i)[0];
|
||||
s = s.substring(tag.length, s.length);
|
||||
|
||||
// loop through attributes
|
||||
pos2 = 0; tagFix = ""; fix = ""; regex = ""; var regexlen = 0;
|
||||
while(pos2!=-1){
|
||||
// slices up before next attribute check, values from previous loop
|
||||
tagFix += tag.substring(0, pos2) + fix;
|
||||
tag = tag.substring(pos2+regexlen, tag.length);
|
||||
|
||||
// fix next attribute or bail out when done
|
||||
// hopefully this charclass covers most urls
|
||||
attr = tag.match(/ (src|href|style)=(['"]?)([\w()\[\]\/.,\\'"-:;#=&?\s@]+?)\2/i);
|
||||
if(!attr){ break; }
|
||||
|
||||
switch(attr[1].toLowerCase()){
|
||||
case "src":// falltrough
|
||||
case "href":
|
||||
// this hopefully covers most common protocols
|
||||
if(attr[3].search(/^(?:[#]|(?:(?:https?|ftps?|file|javascript|mailto|news):))/)==-1){
|
||||
fixedPath = (new dojo.uri.Uri(url, attr[3]).toString());
|
||||
} else {
|
||||
pos2 = pos2 + attr[3].length;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case "style":// style
|
||||
fixedPath = dojo.style.fixPathsInCssText(attr[3], url);
|
||||
break;
|
||||
default:
|
||||
pos2 = pos2 + attr[3].length;
|
||||
continue;
|
||||
}
|
||||
|
||||
regex = " " + attr[1] + "=" + attr[2] + attr[3] + attr[2];
|
||||
regexlen = regex.length;
|
||||
fix = " " + attr[1] + "=" + attr[2] + fixedPath + attr[2];
|
||||
pos2 = tag.search(new RegExp(dojo.string.escapeRegExp(regex)));
|
||||
}
|
||||
str += tagFix + tag;
|
||||
pos = 0; // reset for next mainloop
|
||||
}
|
||||
s = str+s;
|
||||
|
||||
// cut out all script tags, push them into scripts array
|
||||
match = []; var tmp = [];
|
||||
while(match){
|
||||
match = s.match(/<script([^>]*)>([\s\S]*?)<\/script>/i);
|
||||
if(!match){ break; }
|
||||
if(match[1]){
|
||||
attr = match[1].match(/src=(['"]?)([^"']*)\1/i);
|
||||
if(attr){
|
||||
// remove a dojo.js or dojo.js.uncompressed.js from remoteScripts
|
||||
// we declare all files with dojo.js as bad, regardless of folder
|
||||
var tmp = attr[2].search(/.*(\bdojo\b(?:\.uncompressed)?\.js)$/);
|
||||
if(tmp > -1){
|
||||
dojo.debug("Security note! inhibit:"+attr[2]+" from beeing loaded again.");
|
||||
}else{
|
||||
remoteScripts.push(attr[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(match[2]){
|
||||
// strip out all djConfig variables from script tags nodeValue
|
||||
// this is ABSOLUTLY needed as reinitialize djConfig after dojo is initialised
|
||||
// makes a dissaster greater than Titanic, update remove writeIncludes() to
|
||||
var sc = match[2].replace(/(?:var )?\bdjConfig\b(?:[\s]*=[\s]*\{[^}]+\}|\.[\w]*[\s]*=[\s]*[^;\n]*)?;?|dojo\.hostenv\.writeIncludes\(\s*\);?/g, "");
|
||||
if(!sc){ continue; }
|
||||
|
||||
// cut out all dojo.require (...) calls, if we have execute
|
||||
// scripts false widgets dont get there require calls
|
||||
// does suck out possible widgetpackage registration as well
|
||||
tmp = [];
|
||||
while(tmp && requires.length<100){
|
||||
tmp = sc.match(/dojo\.(?:(?:require(?:After)?(?:If)?)|(?:widget\.(?:manager\.)?registerWidgetPackage)|(?:(?:hostenv\.)?setModulePrefix))\((['"]).*?\1\)\s*;?/);
|
||||
if(!tmp){ break;}
|
||||
requires.push(tmp[0]);
|
||||
sc = sc.replace(tmp[0], "");
|
||||
}
|
||||
scripts.push(sc);
|
||||
}
|
||||
s = s.replace(/<script[^>]*>[\s\S]*?<\/script>/i, "");
|
||||
}
|
||||
|
||||
// scan for scriptScope in html eventHandlers and replace with link to this pane
|
||||
if(this.executeScripts){
|
||||
var regex = /(<[a-zA-Z][a-zA-Z0-9]*\s[^>]*\S=(['"])[^>]*[^\.\]])scriptScope([^>]*>)/;
|
||||
var pos = 0;var str = "";match = [];var cit = "";
|
||||
while(pos > -1){
|
||||
pos = s.search(regex);
|
||||
if(pos > -1){
|
||||
cit = ((RegExp.$2=="'") ? '"': "'");
|
||||
str += s.substring(0, pos);
|
||||
s = s.substr(pos).replace(regex, "$1dojo.widget.byId("+ cit + this.widgetId + cit + ").scriptScope$3");
|
||||
}
|
||||
}
|
||||
s = str + s;
|
||||
}
|
||||
|
||||
// cut out all <link rel="stylesheet" href="..">
|
||||
match = [];
|
||||
while(match){
|
||||
match = s.match(/<link ([^>]*rel=['"]?stylesheet['"]?[^>]*)>/i);
|
||||
if(!match){ break; }
|
||||
attr = match[1].match(/href=(['"]?)([^'">]*)\1/i);
|
||||
if(attr){
|
||||
linkStyles.push(attr[2]);
|
||||
}
|
||||
s = s.replace(new RegExp(match[0]), "");
|
||||
}
|
||||
|
||||
return {"xml": s, // Object
|
||||
"styles": styles,
|
||||
"linkStyles": linkStyles,
|
||||
"titles": titles,
|
||||
"requires": requires,
|
||||
"scripts": scripts,
|
||||
"remoteScripts": remoteScripts,
|
||||
"url": url};
|
||||
},
|
||||
|
||||
|
||||
_setContent: function(/*String*/ xml){
|
||||
// summary:
|
||||
// private internal function without path regExpCheck and no onLoad calls aftervards
|
||||
|
||||
// remove old children from current content
|
||||
this.destroyChildren();
|
||||
|
||||
// remove old stylenodes from HEAD
|
||||
if(this._remoteStyles){
|
||||
for(var i = 0; i < this._remoteStyles.length; i++){
|
||||
if(this._remoteStyles[i] && this._remoteStyles.parentNode){
|
||||
this._remoteStyles[i].parentNode.removeChild(this._remoteStyles[i]);
|
||||
}
|
||||
}
|
||||
this._remoteStyles = null;
|
||||
}
|
||||
|
||||
var node = this.containerNode || this.domNode;
|
||||
try{
|
||||
if(typeof xml != "string"){
|
||||
node.innerHTML = "";
|
||||
node.appendChild(xml);
|
||||
}else{
|
||||
node.innerHTML = xml;
|
||||
}
|
||||
} catch(e){
|
||||
e = "Could'nt load content:"+e;
|
||||
this._handleDefaults(e, "onContentError");
|
||||
}
|
||||
},
|
||||
|
||||
setContent: function(/*String*/ data){
|
||||
// summary:
|
||||
// Destroys old content and setting new content, and possibly initialize any widgets within 'data'
|
||||
|
||||
if(this._callOnUnLoad){ // this tells a remote script clean up after itself
|
||||
this.onUnLoad();
|
||||
}
|
||||
this._callOnUnLoad = true;
|
||||
|
||||
if(!data || dojo.dom.isNode(data)){
|
||||
// if we do a clean using setContent(""); or setContent(#node) bypass all parseing, extractContent etc
|
||||
this._setContent(data);
|
||||
this.onResized();
|
||||
this.onLoad();
|
||||
}else{
|
||||
// need to run splitAndFixPaths? ie. manually setting content
|
||||
if((!data.xml)&&(this.adjustPaths)){
|
||||
data = this.splitAndFixPaths(data);
|
||||
}
|
||||
if(this.extractContent) {
|
||||
var matches = data.xml.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
|
||||
if(matches) { data.xml = matches[1]; }
|
||||
}
|
||||
// insert styleNodes, from <style>....
|
||||
for(var i = 0; i < data.styles.length; i++){
|
||||
if(i==0){
|
||||
this._remoteStyles = [];
|
||||
}
|
||||
this._remoteStyles.push(dojo.style.insertCssText(data.styles[i]));
|
||||
}
|
||||
// insert styleNodes, from <link href="...">
|
||||
for(var i = 0; i < data.linkStyles.length; i++){
|
||||
if(i==0){
|
||||
this._remoteStyles = [];
|
||||
}
|
||||
this._remoteStyles.push(dojo.style.insertCssFile(data.linkStyles[i]));
|
||||
}
|
||||
this._setContent(data.xml);
|
||||
|
||||
if(this.parseContent){
|
||||
for(var i = 0; i < data.requires.length; i++){
|
||||
try{
|
||||
eval(data.requires[i]);
|
||||
} catch(e){
|
||||
this._handleDefaults(e, "onContentError", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
// need to allow async load, Xdomain uses it
|
||||
// is inline function because we cant send args to addOnLoad function
|
||||
var _self = this;
|
||||
function asyncParse(){
|
||||
if(_self.executeScripts){
|
||||
_self._executeScripts(data);
|
||||
}
|
||||
|
||||
if(_self.parseContent){
|
||||
var node = _self.containerNode || _self.domNode;
|
||||
var parser = new dojo.xml.Parse();
|
||||
var frag = parser.parseElement(node, null, true);
|
||||
// createSubComponents not createComponents because frag has already been created
|
||||
dojo.widget.getParser().createSubComponents(frag, _self);
|
||||
}
|
||||
|
||||
_self.onResized();
|
||||
_self.onLoad();
|
||||
}
|
||||
// try as long as possible to make setContent sync call
|
||||
if(dojo.hostenv.isXDomain && data.requires.length){
|
||||
dojo.addOnLoad(asyncParse);
|
||||
}else{
|
||||
asyncParse();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Generate pane content from given java function
|
||||
setHandler: function(handler) {
|
||||
var fcn = dojo.lang.isFunction(handler) ? handler : window[handler];
|
||||
if(!dojo.lang.isFunction(fcn)) {
|
||||
// FIXME: needs testing! somebody with java knowledge needs to try this
|
||||
this._handleDefaults("Unable to set handler, '" + handler + "' not a function.", "onExecError", true);
|
||||
return;
|
||||
}
|
||||
this.handler = function() {
|
||||
return fcn.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
|
||||
_runHandler: function() {
|
||||
if(dojo.lang.isFunction(this.handler)) {
|
||||
this.handler(this, this.domNode);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
_executeScripts: function(data) {
|
||||
// do remoteScripts first
|
||||
var self = this;
|
||||
for(var i = 0; i < data.remoteScripts.length; i++){
|
||||
dojo.io.bind({
|
||||
"url": data.remoteScripts[i],
|
||||
"useCash": this.cacheContent,
|
||||
"load": function(type, scriptStr){
|
||||
dojo.lang.hitch(self, data.scripts.push(scriptStr));
|
||||
},
|
||||
"error": function(type, error){
|
||||
self._handleDefaults.call(self, type + " downloading remote script", "onExecError", true);
|
||||
},
|
||||
"mimetype": "text/plain",
|
||||
"sync": true
|
||||
});
|
||||
}
|
||||
|
||||
var scripts = "";
|
||||
for(var i = 0; i < data.scripts.length; i++){
|
||||
scripts += data.scripts[i];
|
||||
}
|
||||
|
||||
try{
|
||||
// initialize a new anonymous container for our script, dont make it part of this widgets scope chain
|
||||
// instead send in a variable that points to this widget, usefull to connect events to onLoad, onUnLoad etc..
|
||||
this.scriptScope = null;
|
||||
this.scriptScope = new (new Function('_container_', scripts+'; return this;'))(self);
|
||||
}catch(e){
|
||||
this._handleDefaults("Error running scripts from content:\n"+e, "onExecError", true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:ContentPane");
|
166
webapp/web/src/widget/html/ContextMenu.js
Normal file
166
webapp/web/src/widget/html/ContextMenu.js
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.ContextMenu");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.widget.ContextMenu");
|
||||
dojo.require("dojo.lang");
|
||||
|
||||
dojo.widget.html.ContextMenu = function(){
|
||||
dojo.widget.ContextMenu.call(this);
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
|
||||
this.isShowing = 0;
|
||||
this.templatePath = dojo.uri.dojoUri("src/widget/templates/HtmlContextMenuTemplate.html");
|
||||
this.templateCssPath = dojo.uri.dojoUri("src/widget/templates/Menu.css");
|
||||
|
||||
this.targetNodeIds = []; // fill this with nodeIds upon widget creation and it only responds to those nodes
|
||||
|
||||
// default event detection method
|
||||
var eventType = "oncontextmenu";
|
||||
|
||||
var doc = document.documentElement || document.body;
|
||||
|
||||
var _blockHide = false;
|
||||
|
||||
this.fillInTemplate = function(args, frag){
|
||||
|
||||
var func = "onOpen";
|
||||
var attached = false;
|
||||
|
||||
// connect with rightclick if oncontextmenu is not around
|
||||
// NOTE: It would be very nice to have a dojo.event.browser.supportsEvent here
|
||||
// NOTE: Opera does not have rightclick events, it is listed here only because
|
||||
// it bails out when connecting with oncontextmenu event
|
||||
|
||||
if((dojo.render.html.khtml && !dojo.render.html.safari) || (dojo.render.html.opera)){
|
||||
eventType = "onmousedown";
|
||||
func = "_checkRightClick";
|
||||
}
|
||||
|
||||
// attach event listeners to our selected nodes
|
||||
for(var i=0; i<this.targetNodeIds.length; i++){
|
||||
var node = document.getElementById(this.targetNodeIds[i]);
|
||||
if(node){
|
||||
dojo.event.connect(node, eventType, this, func);
|
||||
attached = true;
|
||||
}else{
|
||||
// remove this nodeId
|
||||
dojo.debug("Couldent find "+this.targetNodeIds[i]+", cant do ContextMenu on this node");
|
||||
this.targetNodeIds.splice(i,1);
|
||||
}
|
||||
}
|
||||
|
||||
// if we got attached to a node, hide on all non node contextevents
|
||||
if(attached){ func = "_canHide"; }
|
||||
|
||||
dojo.event.connect(doc, eventType, this, func);
|
||||
}
|
||||
|
||||
this.onOpen = function(evt){
|
||||
// if (this.isShowing){ this.onHide(evt); } // propably not needed
|
||||
this.isShowing = 1;
|
||||
|
||||
// if I do this, I cant preventDefault in khtml
|
||||
//evt = dojo.event.browser.fixEvent(evt);
|
||||
|
||||
// stop default contextmenu, needed in khtml
|
||||
if (evt.preventDefault){ evt.preventDefault(); }
|
||||
|
||||
// need to light up this one before we check width and height
|
||||
this.domNode.style.left = "-9999px";
|
||||
this.domNode.style.top = "-9999px";
|
||||
this.domNode.style.display = "block";
|
||||
|
||||
// calculate if menu is going to apear within window
|
||||
// or if its partially out of visable area
|
||||
with(dojo.html){
|
||||
|
||||
var menuW = getInnerWidth(this.domNode);
|
||||
var menuH = getInnerHeight(this.domNode);
|
||||
|
||||
var viewport = getViewportSize();
|
||||
var scrolloffset = getScrollOffset();
|
||||
}
|
||||
|
||||
var minX = viewport[0];
|
||||
var minY = viewport[1];
|
||||
|
||||
var maxX = (viewport[0] + scrolloffset[0]) - menuW;
|
||||
var maxY = (viewport[1] + scrolloffset[1]) - menuH;
|
||||
|
||||
var posX = evt.clientX + scrolloffset[0];
|
||||
var posY = evt.clientY + scrolloffset[1];
|
||||
|
||||
if (posX > maxX){ posX = posX - menuW; }
|
||||
if (posY > maxY){ posY = posY - menuH; }
|
||||
|
||||
this.domNode.style.left = posX + "px";
|
||||
this.domNode.style.top = posY + "px";
|
||||
|
||||
|
||||
// block the onclick that follows this particular right click
|
||||
// not if the eventtrigger is documentElement and always when
|
||||
// we use onmousedown hack
|
||||
_blockHide = (evt.currentTarget!=doc || eventType=='onmousedown');
|
||||
|
||||
//return false; // we propably doesnt need to return false as we dont stop the event as we did before
|
||||
}
|
||||
|
||||
/*
|
||||
* _canHide is meant to block the onHide call that follows the event that triggered
|
||||
* onOpen. This is (hopefully) faster that event.connect and event.disconnect every
|
||||
* time the code executes and it makes connecting with onmousedown event possible
|
||||
* and we dont have to stop the event from bubbling further.
|
||||
*
|
||||
* this code is moved into a separete function because it makes it possible for the
|
||||
* user to connect to a onHide event, if anyone would like that.
|
||||
*/
|
||||
|
||||
this._canHide = function(evt){
|
||||
// block the onclick that follows the same event that turn on contextmenu
|
||||
if(_blockHide){
|
||||
// the onclick check is needed to prevent displaying multiple
|
||||
// menus when we have 2 or more contextmenus loaded and are using
|
||||
// the onmousedown hack
|
||||
if(evt.type=='click' || eventType=='oncontextmenu'){
|
||||
_blockHide = false;
|
||||
return;
|
||||
}else{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.onHide(evt);
|
||||
}
|
||||
|
||||
this.onHide = function(evt){
|
||||
// FIXME: use whatever we use to do more general style setting?
|
||||
this.domNode.style.display = "none";
|
||||
//dojo.event.disconnect(doc, "onclick", this, "onHide");
|
||||
this.isShowing = 0;
|
||||
}
|
||||
|
||||
// callback for rightclicks, needed for browsers that doesnt implement oncontextmenu, konqueror and more?
|
||||
this._checkRightClick = function(evt){
|
||||
|
||||
// for some reason konq comes here even when we are not clicking on the attached nodes
|
||||
// added check for targetnode
|
||||
if (evt.button==2 && (this.targetNodeIds.length==0 || (evt.currentTarget.id!="" && dojo.lang.inArray(this.targetNodeIds, evt.currentTarget.id)))){
|
||||
|
||||
return this.onOpen(evt);
|
||||
}
|
||||
}
|
||||
|
||||
dojo.event.connect(doc, "onclick", this, "_canHide");
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.ContextMenu, dojo.widget.HtmlWidget);
|
346
webapp/web/src/widget/html/DatePicker.js
Normal file
346
webapp/web/src/widget/html/DatePicker.js
Normal file
|
@ -0,0 +1,346 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.DatePicker");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.widget.DatePicker");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.date");
|
||||
|
||||
/*
|
||||
Some assumptions:
|
||||
- I'm planning on always showing 42 days at a time, and we can scroll by week,
|
||||
not just by month or year
|
||||
- To get a sense of what month to highlight, I basically initialize on the
|
||||
first Saturday of each month, since that will be either the first of two or
|
||||
the second of three months being partially displayed, and then I work forwards
|
||||
and backwards from that point.
|
||||
Currently, I assume that dates are stored in the RFC 3339 format,
|
||||
because I find it to be most human readable and easy to parse
|
||||
http://www.faqs.org/rfcs/rfc3339.html: 2005-06-30T08:05:00-07:00
|
||||
*/
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.DatePicker",
|
||||
dojo.widget.HtmlWidget,
|
||||
{
|
||||
classConstructor: function() {
|
||||
// mixin dojo.widget.DatePicker non-demoninational code
|
||||
dojo.widget.DatePicker.call(this);
|
||||
// today's date, JS Date object
|
||||
this.today = "";
|
||||
// selected date, JS Date object
|
||||
this.date = "";
|
||||
// rfc 3339 date
|
||||
this.storedDate = "";
|
||||
// date currently selected in the UI, stored in year, month, date in the format that will be actually displayed
|
||||
this.currentDate = {};
|
||||
// stored in year, month, date in the format that will be actually displayed
|
||||
this.firstSaturday = {};
|
||||
},
|
||||
classNames: {
|
||||
previous: "previousMonth",
|
||||
current: "currentMonth",
|
||||
next: "nextMonth",
|
||||
currentDate: "currentDate",
|
||||
selectedDate: "selectedItem"
|
||||
},
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlDatePicker.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlDatePicker.css"),
|
||||
|
||||
fillInTemplate: function(){
|
||||
dojo.widget.DatePicker.call(this);
|
||||
this.initData();
|
||||
this.initUI();
|
||||
},
|
||||
initData: function() {
|
||||
this.today = new Date();
|
||||
if(this.storedDate && (this.storedDate.split("-").length > 2)) {
|
||||
this.date = dojo.widget.DatePicker.util.fromRfcDate(this.storedDate);
|
||||
} else {
|
||||
this.date = this.today;
|
||||
}
|
||||
// calendar math is simplified if time is set to 0
|
||||
this.today.setHours(0);
|
||||
this.date.setHours(0);
|
||||
var month = this.date.getMonth();
|
||||
var tempSaturday = dojo.widget.DatePicker.util.initFirstSaturday(this.date.getMonth().toString(), this.date.getFullYear());
|
||||
this.firstSaturday.year = tempSaturday.year;
|
||||
this.firstSaturday.month = tempSaturday.month;
|
||||
this.firstSaturday.date = tempSaturday.date;
|
||||
},
|
||||
|
||||
setDate: function(rfcDate) {
|
||||
this.storedDate = rfcDate;
|
||||
},
|
||||
|
||||
initUI: function() {
|
||||
this.selectedIsUsed = false;
|
||||
this.currentIsUsed = false;
|
||||
var currentClassName = "";
|
||||
var previousDate = new Date();
|
||||
var calendarNodes = this.calendarDatesContainerNode.getElementsByTagName("td");
|
||||
var currentCalendarNode;
|
||||
// set hours of date such that there is no chance of rounding error due to
|
||||
// time change in local time zones
|
||||
previousDate.setHours(8);
|
||||
var nextDate = new Date(this.firstSaturday.year, this.firstSaturday.month, this.firstSaturday.date, 8);
|
||||
|
||||
if(this.firstSaturday.date < 7) {
|
||||
// this means there are days to show from the previous month
|
||||
var dayInWeek = 6;
|
||||
for (var i=this.firstSaturday.date; i>0; i--) {
|
||||
currentCalendarNode = calendarNodes.item(dayInWeek);
|
||||
currentCalendarNode.innerHTML = nextDate.getDate();
|
||||
dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "current"));
|
||||
dayInWeek--;
|
||||
previousDate = nextDate;
|
||||
nextDate = this.incrementDate(nextDate, false);
|
||||
}
|
||||
for(var i=dayInWeek; i>-1; i--) {
|
||||
currentCalendarNode = calendarNodes.item(i);
|
||||
currentCalendarNode.innerHTML = nextDate.getDate();
|
||||
dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "previous"));
|
||||
previousDate = nextDate;
|
||||
nextDate = this.incrementDate(nextDate, false);
|
||||
}
|
||||
} else {
|
||||
nextDate.setDate(this.firstSaturday.date-6);
|
||||
for(var i=0; i<7; i++) {
|
||||
currentCalendarNode = calendarNodes.item(i);
|
||||
currentCalendarNode.innerHTML = nextDate.getDate();
|
||||
dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "current"));
|
||||
previousDate = nextDate;
|
||||
nextDate = this.incrementDate(nextDate, true);
|
||||
}
|
||||
}
|
||||
previousDate.setDate(this.firstSaturday.date);
|
||||
previousDate.setMonth(this.firstSaturday.month);
|
||||
previousDate.setFullYear(this.firstSaturday.year);
|
||||
nextDate = this.incrementDate(previousDate, true);
|
||||
var count = 7;
|
||||
currentCalendarNode = calendarNodes.item(count);
|
||||
while((nextDate.getMonth() == previousDate.getMonth()) && (count<42)) {
|
||||
currentCalendarNode.innerHTML = nextDate.getDate();
|
||||
dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "current"));
|
||||
currentCalendarNode = calendarNodes.item(++count);
|
||||
previousDate = nextDate;
|
||||
nextDate = this.incrementDate(nextDate, true);
|
||||
}
|
||||
|
||||
while(count < 42) {
|
||||
currentCalendarNode.innerHTML = nextDate.getDate();
|
||||
dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "next"));
|
||||
currentCalendarNode = calendarNodes.item(++count);
|
||||
previousDate = nextDate;
|
||||
nextDate = this.incrementDate(nextDate, true);
|
||||
}
|
||||
this.setMonthLabel(this.firstSaturday.month);
|
||||
this.setYearLabels(this.firstSaturday.year);
|
||||
},
|
||||
|
||||
incrementDate: function(date, bool) {
|
||||
// bool: true to increase, false to decrease
|
||||
var time = date.getTime();
|
||||
var increment = 1000 * 60 * 60 * 24;
|
||||
time = (bool) ? (time + increment) : (time - increment);
|
||||
var returnDate = new Date();
|
||||
returnDate.setTime(time);
|
||||
return returnDate;
|
||||
},
|
||||
|
||||
incrementWeek: function(evt) {
|
||||
var date = this.firstSaturday.date;
|
||||
var month = this.firstSaturday.month;
|
||||
var year = this.firstSaturday.year;
|
||||
switch(evt.target) {
|
||||
case this.increaseWeekNode.getElementsByTagName("img").item(0):
|
||||
case this.increaseWeekNode:
|
||||
date = date + 7;
|
||||
if (date>this._daysIn(month,year)) {
|
||||
date = date - this._daysIn(month,year);
|
||||
if (month < 11) {
|
||||
month++;
|
||||
} else {
|
||||
month=0;
|
||||
year++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case this.decreaseWeekNode.getElementsByTagName("img").item(0):
|
||||
case this.decreaseWeekNode:
|
||||
if (date > 7) {
|
||||
date = date - 7;
|
||||
} else {
|
||||
var diff = 7 - date;
|
||||
if (month > 0) {
|
||||
month--;
|
||||
date = this._daysIn(month,year) - diff;
|
||||
}else {
|
||||
year--;
|
||||
month=11;
|
||||
date = 31 - diff;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
this.firstSaturday.date=date;
|
||||
this.firstSaturday.month=month;
|
||||
this.firstSaturday.year=year;
|
||||
this.initUI();
|
||||
},
|
||||
|
||||
incrementMonth: function(evt) {
|
||||
var month = this.firstSaturday.month;
|
||||
var year = this.firstSaturday.year;
|
||||
switch(evt.currentTarget) {
|
||||
case this.increaseMonthNode:
|
||||
if(month < 11) {
|
||||
month++;
|
||||
} else {
|
||||
month = 0;
|
||||
year++;
|
||||
|
||||
this.setYearLabels(year);
|
||||
}
|
||||
break;
|
||||
case this.decreaseMonthNode:
|
||||
if(month > 0) {
|
||||
month--;
|
||||
} else {
|
||||
month = 11;
|
||||
year--;
|
||||
this.setYearLabels(year);
|
||||
}
|
||||
break;
|
||||
case this.increaseMonthNode.getElementsByTagName("img").item(0):
|
||||
if(month < 11) {
|
||||
month++;
|
||||
} else {
|
||||
month = 0;
|
||||
year++;
|
||||
this.setYearLabels(year);
|
||||
}
|
||||
break;
|
||||
case this.decreaseMonthNode.getElementsByTagName("img").item(0):
|
||||
if(month > 0) {
|
||||
month--;
|
||||
} else {
|
||||
month = 11;
|
||||
year--;
|
||||
this.setYearLabels(year);
|
||||
}
|
||||
break;
|
||||
}
|
||||
var tempSaturday = dojo.widget.DatePicker.util.initFirstSaturday(month.toString(), year);
|
||||
this.firstSaturday.year = tempSaturday.year;
|
||||
this.firstSaturday.month = tempSaturday.month;
|
||||
this.firstSaturday.date = tempSaturday.date;
|
||||
this.initUI();
|
||||
},
|
||||
|
||||
incrementYear: function(evt) {
|
||||
var year = this.firstSaturday.year;
|
||||
switch(evt.target) {
|
||||
case this.nextYearLabelNode:
|
||||
year++;
|
||||
break;
|
||||
case this.previousYearLabelNode:
|
||||
year--;
|
||||
break;
|
||||
}
|
||||
var tempSaturday = dojo.widget.DatePicker.util.initFirstSaturday(this.firstSaturday.month.toString(), year);
|
||||
this.firstSaturday.year = tempSaturday.year;
|
||||
this.firstSaturday.month = tempSaturday.month;
|
||||
this.firstSaturday.date = tempSaturday.date;
|
||||
this.initUI();
|
||||
},
|
||||
|
||||
_daysIn: function(month,year) {
|
||||
var daysIn = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
||||
|
||||
if (month==1) {
|
||||
return (year%400 == 0) ? 29: (year%100 == 0) ? 28: (year%4 == 0) ? 29: 28;
|
||||
} else {
|
||||
return daysIn[month];
|
||||
}
|
||||
},
|
||||
|
||||
onIncrementDate: function(evt) {
|
||||
dojo.unimplemented('dojo.widget.html.DatePicker.onIncrementDate');
|
||||
},
|
||||
|
||||
onIncrementWeek: function(evt) {
|
||||
evt.stopPropagation();
|
||||
this.incrementWeek(evt);
|
||||
},
|
||||
|
||||
onIncrementMonth: function(evt) {
|
||||
evt.stopPropagation();
|
||||
this.incrementMonth(evt);
|
||||
},
|
||||
|
||||
onIncrementYear: function(evt) {
|
||||
evt.stopPropagation();
|
||||
this.incrementYear(evt);
|
||||
},
|
||||
|
||||
setMonthLabel: function(monthIndex) {
|
||||
this.monthLabelNode.innerHTML = dojo.date.months[monthIndex];
|
||||
},
|
||||
|
||||
setYearLabels: function(year) {
|
||||
this.previousYearLabelNode.innerHTML = year - 1;
|
||||
this.currentYearLabelNode.innerHTML = year;
|
||||
this.nextYearLabelNode.innerHTML = year + 1;
|
||||
},
|
||||
|
||||
getDateClassName: function(date, monthState) {
|
||||
var currentClassName = this.classNames[monthState];
|
||||
if ((!this.selectedIsUsed) && (date.getDate() == this.date.getDate()) && (date.getMonth() == this.date.getMonth()) && (date.getFullYear() == this.date.getFullYear())) {
|
||||
currentClassName = this.classNames.selectedDate + " " + currentClassName;
|
||||
this.selectedIsUsed = 1;
|
||||
}
|
||||
if((!this.currentIsUsed) && (date.getDate() == this.today.getDate()) && (date.getMonth() == this.today.getMonth()) && (date.getFullYear() == this.today.getFullYear())) {
|
||||
currentClassName = currentClassName + " " + this.classNames.currentDate;
|
||||
this.currentIsUsed = 1;
|
||||
}
|
||||
return currentClassName;
|
||||
},
|
||||
|
||||
onClick: function(evt) {
|
||||
dojo.event.browser.stopEvent(evt)
|
||||
},
|
||||
|
||||
onSetDate: function(evt) {
|
||||
dojo.event.browser.stopEvent(evt);
|
||||
this.selectedIsUsed = 0;
|
||||
this.todayIsUsed = 0;
|
||||
var month = this.firstSaturday.month;
|
||||
var year = this.firstSaturday.year;
|
||||
if (dojo.html.hasClass(evt.target, this.classNames["next"])) {
|
||||
month = ++month % 12;
|
||||
// if month is now == 0, add a year
|
||||
year = (month==0) ? ++year : year;
|
||||
} else if (dojo.html.hasClass(evt.target, this.classNames["previous"])) {
|
||||
month = --month % 12;
|
||||
// if month is now == 0, add a year
|
||||
year = (month==11) ? --year : year;
|
||||
}
|
||||
this.date = new Date(year, month, evt.target.innerHTML);
|
||||
this.setDate(dojo.widget.DatePicker.util.toRfcDate(this.date));
|
||||
this.initUI();
|
||||
}
|
||||
}
|
||||
);
|
31
webapp/web/src/widget/html/DebugConsole.js
Normal file
31
webapp/web/src/widget/html/DebugConsole.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.DebugConsole");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.FloatingPane");
|
||||
|
||||
dojo.widget.html.DebugConsole= function(){
|
||||
|
||||
dojo.widget.html.FloatingPane.call(this);
|
||||
dojo.widget.DebugConsole.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.DebugConsole, dojo.widget.html.FloatingPane);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.DebugConsole, {
|
||||
fillInTemplate: function() {
|
||||
dojo.widget.html.DebugConsole.superclass.fillInTemplate.apply(this, arguments);
|
||||
this.containerNode.id = "debugConsoleClientPane";
|
||||
djConfig.isDebug = true;
|
||||
djConfig.debugContainerId = this.containerNode.id;
|
||||
}
|
||||
});
|
210
webapp/web/src/widget/html/DocPane.js
Normal file
210
webapp/web/src/widget/html/DocPane.js
Normal file
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.DocPane");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.io.*");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
|
||||
dojo.widget.html.DocPane = function(){
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
|
||||
this.templatePath = dojo.uri.dojoUri("src/widget/templates/HtmlDocPane.html");
|
||||
this.templateCssPath = dojo.uri.dojoUri("src/widget/templates/HtmlDocPane.css");
|
||||
this.widgetType = "DocPane";
|
||||
this.isContainer = true;
|
||||
|
||||
this.select;
|
||||
this.result;
|
||||
this.fn;
|
||||
this.fnLink;
|
||||
this.count;
|
||||
this.row;
|
||||
this.summary;
|
||||
this.description;
|
||||
this.variables;
|
||||
this.vRow;
|
||||
this.vLink;
|
||||
this.vDesc;
|
||||
this.parameters;
|
||||
this.pRow;
|
||||
this.pLink;
|
||||
this.pDesc;
|
||||
this.pOpt;
|
||||
this.pType;
|
||||
this.source;
|
||||
this.sType;
|
||||
this.sName;
|
||||
this.sParams;
|
||||
this.sPType;
|
||||
this.sPTypeSave;
|
||||
this.sPName;
|
||||
this.sPNameSave;
|
||||
|
||||
dojo.event.topic.subscribe("/doc/results", this, "onDocResults");
|
||||
dojo.event.topic.subscribe("/doc/functionDetail", this, "onDocSelectFunction");
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.DocPane, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.DocPane, {
|
||||
fillInTemplate: function(){
|
||||
this.homeSave = this.containerNode.cloneNode(true);
|
||||
this.selectSave = dojo.dom.removeNode(this.select);
|
||||
this.resultSave = dojo.dom.removeNode(this.result);
|
||||
this.rowParent = this.row.parentNode;
|
||||
this.rowSave = dojo.dom.removeNode(this.row);
|
||||
this.vParent = this.vRow.parentNode;
|
||||
this.vSave = dojo.dom.removeNode(this.vRow);
|
||||
this.pParent = this.pRow.parentNode;
|
||||
this.pSave = dojo.dom.removeNode(this.pRow);
|
||||
this.sPTypeSave = dojo.dom.removeNode(this.sPType);
|
||||
this.sPNameSave = dojo.dom.removeNode(this.sPName);
|
||||
},
|
||||
|
||||
onDocSelectFunction: function(message){
|
||||
var meta = message.meta;
|
||||
if(meta){
|
||||
var variables = meta.variables;
|
||||
var this_variables = meta.this_variables;
|
||||
var child_variables = meta.child_variables;
|
||||
var parameters = meta.parameters;
|
||||
}
|
||||
var doc = message.doc;
|
||||
|
||||
var appends = [];
|
||||
dojo.dom.removeChildren(this.domNode);
|
||||
this.fn.innerHTML = message.name;
|
||||
this.description.innerHTML = doc.description;
|
||||
|
||||
this.variables.style.display = "block";
|
||||
var all = [];
|
||||
if(variables){
|
||||
all = variables;
|
||||
}
|
||||
if(this_variables){
|
||||
all = all.concat(this_variables);
|
||||
}
|
||||
if(child_variables){
|
||||
all = all.concat(child_variables);
|
||||
}
|
||||
if(!all.length){
|
||||
this.variables.style.display = "none";
|
||||
}else{
|
||||
for(var i = 0, one; one = all[i]; i++){
|
||||
this.vLink.innerHTML = one;
|
||||
this.vDesc.parentNode.style.display = "none";
|
||||
appends.push(this.vParent.appendChild(this.vSave.cloneNode(true)));
|
||||
}
|
||||
}
|
||||
|
||||
this.sParams.innerHTML = "";
|
||||
for(var param in parameters){
|
||||
var paramType = parameters[param][0];
|
||||
var paramName = parameters[param][1];
|
||||
this.parameters.style.display = "block";
|
||||
this.pLink.innerHTML = paramName;
|
||||
this.pOpt.style.display = "none";
|
||||
if(parameters[param].opt){
|
||||
this.pOpt.style.display = "inline";
|
||||
}
|
||||
this.pType.parentNode.style.display = "none";
|
||||
if(parameters[param][0]){
|
||||
this.pType.parentNode.style.display = "inline";
|
||||
this.pType.innerHTML = paramType;
|
||||
}
|
||||
this.pDesc.parentNode.style.display = "none";
|
||||
if(doc.parameters[paramName] && doc.parameters[paramName].description){
|
||||
this.pDesc.parentNode.style.display = "inline";
|
||||
this.pDesc.innerHTML = doc.parameters[paramName].description;
|
||||
}
|
||||
appends.push(this.pParent.appendChild(this.pSave.cloneNode(true)));
|
||||
|
||||
if(param > 0) {
|
||||
this.sParams.appendChild(document.createTextNode(", "));
|
||||
}
|
||||
if(paramType){
|
||||
dojo.debug(this.sPTypeSave);
|
||||
this.sPTypeSave.innerHTML = paramType;
|
||||
this.sParams.appendChild(this.sPTypeSave.cloneNode(true));
|
||||
this.sParams.appendChild(document.createTextNode(" "));
|
||||
}
|
||||
dojo.debug(this.sPNameSave);
|
||||
this.sPNameSave.innerHTML = paramName;
|
||||
this.sParams.appendChild(this.sPNameSave.cloneNode(true))
|
||||
}
|
||||
|
||||
if(message.returns){
|
||||
this.sType.innerHTML = message.returns;
|
||||
}else{
|
||||
this.sType.innerHTML = "void";
|
||||
}
|
||||
|
||||
this.sName.innerHTML = message.name;
|
||||
|
||||
dojo.dom.removeChildren(this.source);
|
||||
this.source.appendChild(document.createTextNode("\n\r"));
|
||||
this.source.appendChild(document.createTextNode(message.src.replace(/\n/g, "\r\n\t")));
|
||||
this.source.appendChild(document.createTextNode("\n\r"));
|
||||
|
||||
this.domNode.appendChild(this.selectSave.cloneNode(true));
|
||||
|
||||
for(var i = 0, append; append = appends[i]; i++){
|
||||
dojo.dom.removeNode(append);
|
||||
}
|
||||
},
|
||||
|
||||
onDocResults: function(message){
|
||||
var results = message.docResults;
|
||||
|
||||
if(results.length == 1){
|
||||
dojo.event.topic.publish("/doc/selectFunction", results[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
dojo.dom.removeChildren(this.domNode);
|
||||
|
||||
this.count.innerHTML = results.length;
|
||||
var appends = [];
|
||||
for(var i = 0, row; row = results[i]; i++){
|
||||
this.fnLink.innerHTML = row.name;
|
||||
this.fnLink.href = "#" + row.name;
|
||||
if(row.id){
|
||||
this.fnLink.href = this.fnLink.href + "," + row.id;
|
||||
}
|
||||
this.summary.parentNode.style.display = "none";
|
||||
if(row.summary){
|
||||
this.summary.parentNode.style.display = "inline";
|
||||
this.summary.innerHTML = row.summary;
|
||||
}
|
||||
appends.push(this.rowParent.appendChild(this.rowSave.cloneNode(true)));
|
||||
}
|
||||
|
||||
function makeSelect(x){
|
||||
return function(e) {
|
||||
dojo.event.topic.publish("/doc/selectFunction", x);
|
||||
}
|
||||
}
|
||||
|
||||
this.domNode.appendChild(this.resultSave.cloneNode(true));
|
||||
var as = this.domNode.getElementsByTagName("a");
|
||||
for(var i = 0, a; a = as[i]; i++){
|
||||
dojo.event.connect(a, "onclick", makeSelect(results[i]));
|
||||
}
|
||||
|
||||
for(var i = 0, append; append = appends[i]; i++){
|
||||
this.rowParent.removeChild(append);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:DocPane");
|
188
webapp/web/src/widget/html/DropdownButton.js
Normal file
188
webapp/web/src/widget/html/DropdownButton.js
Normal file
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
/* TODO:
|
||||
* - make the dropdown "smart" so it can't get cutoff on bottom of page, sides of page, etc.
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.DropdownButton");
|
||||
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.uri.Uri");
|
||||
dojo.require("dojo.dom");
|
||||
dojo.require("dojo.style");
|
||||
dojo.require("dojo.html");
|
||||
|
||||
dojo.widget.html.DropdownButton = function() {
|
||||
// mix in the button properties
|
||||
dojo.widget.DropdownButton.call(this);
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.DropdownButton, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.DropdownButton, {
|
||||
|
||||
// In IE, event handlers on objects inside buttons don't work correctly, so
|
||||
// we just set onClick on the button itself.
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlDropDownButtonTemplate.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlButtonTemplate.css"),
|
||||
|
||||
// attach points
|
||||
button: null,
|
||||
table: null,
|
||||
labelCell: null,
|
||||
borderCell: null,
|
||||
arrowCell: null,
|
||||
arrow: null,
|
||||
|
||||
fillInTemplate: function(args, frag) {
|
||||
// input data (containing the anchor for the button itself, plus the
|
||||
// thing to display when you push the down arrow)
|
||||
var input = frag["dojo:"+this.widgetType.toLowerCase()]["nodeRef"];
|
||||
|
||||
// Recursively expand widgets inside of the <dojo:dropdownButton>
|
||||
var parser = new dojo.xml.Parse();
|
||||
var frag = parser.parseElement(input, null, true);
|
||||
var ary = dojo.widget.getParser().createComponents(frag);
|
||||
|
||||
this.a = dojo.dom.getFirstChildElement(input); // the button contents
|
||||
this.menu = dojo.dom.getNextSiblingElement(this.a); // the menu under the button
|
||||
|
||||
this.disabled = dojo.html.hasClass(this.a, "disabled");
|
||||
if( this.disabled ) {
|
||||
dojo.html.addClass(this.button, "dojoDisabled");
|
||||
this.domNode.setAttribute("disabled", "true");
|
||||
}
|
||||
|
||||
dojo.html.disableSelection(this.a);
|
||||
this.a.style["text-decoration"]="none";
|
||||
this.labelCell.appendChild(this.a);
|
||||
|
||||
this.arrow.src =
|
||||
dojo.uri.dojoUri("src/widget/templates/images/dropdownButtonsArrow" +
|
||||
(this.disabled ? "-disabled" : "") + ".gif");
|
||||
|
||||
// Attach menu to body so that it appears above other buttons
|
||||
this.menu.style.position="absolute";
|
||||
this.menu.style.display="none";
|
||||
this.menu.style["z-index"] = 99;
|
||||
document.body.appendChild(this.menu);
|
||||
},
|
||||
|
||||
postCreate: function() {
|
||||
if ( dojo.render.html.ie ) {
|
||||
// Compensate for IE's weird padding of button content, which seems to be relative
|
||||
// to the length of the content
|
||||
var contentWidth = dojo.style.getOuterWidth(this.table);
|
||||
this.labelCell.style["left"] = "-" + (contentWidth / 10) + "px";
|
||||
this.arrowCell.style["left"] = (contentWidth / 10) + "px";
|
||||
}
|
||||
|
||||
// Make menu at least as wide as the button
|
||||
var buttonWidth = dojo.style.getOuterWidth(this.button);
|
||||
var menuWidth = dojo.style.getOuterWidth(this.menu);
|
||||
if ( buttonWidth > menuWidth ) {
|
||||
dojo.style.setOuterWidth(this.menu, buttonWidth);
|
||||
}
|
||||
},
|
||||
|
||||
// If someone clicks anywhere else on the screen (including another menu),
|
||||
// then close this menu.
|
||||
onCanvasMouseDown: function(e) {
|
||||
if( !dojo.dom.isDescendantOf(e.target, this.button) &&
|
||||
!dojo.dom.isDescendantOf(e.target, this.menu) ) {
|
||||
this.hideMenu();
|
||||
}
|
||||
},
|
||||
|
||||
eventWasOverArrow: function(e) {
|
||||
// want to use dojo.html.overElement() but also need to detect clicks
|
||||
// on the area between the arrow and the edge of the button
|
||||
var eventX = e.clientX;
|
||||
var borderX = dojo.style.totalOffsetLeft(this.borderCell);
|
||||
return (eventX > borderX );
|
||||
},
|
||||
|
||||
onMouseOver: function(e) {
|
||||
dojo.html.addClass(this.button, "dojoButtonHover");
|
||||
dojo.html.removeClass(this.button, "dojoButtonNoHover");
|
||||
},
|
||||
|
||||
onMouseOut: function(e) {
|
||||
dojo.html.removeClass(this.button, "dojoButtonHover");
|
||||
dojo.html.addClass(this.button, "dojoButtonNoHover");
|
||||
},
|
||||
|
||||
onClick: function(e) {
|
||||
if ( this.eventWasOverArrow(e) ) {
|
||||
this._onClickArrow();
|
||||
} else {
|
||||
this._onClickButton();
|
||||
}
|
||||
},
|
||||
|
||||
// Action when the user presses the button
|
||||
_onClickButton: function(e) {
|
||||
if ( this.a ) {
|
||||
if ( this.a.click ) {
|
||||
this.a.click();
|
||||
} else if ( this.a.href ) {
|
||||
location.href = this.a.href;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Action when user presses the arrow
|
||||
_onClickArrow: function() {
|
||||
if ( this.menu.style.display == "none" ) {
|
||||
this.showMenu();
|
||||
} else {
|
||||
this.hideMenu();
|
||||
}
|
||||
},
|
||||
|
||||
showMenu: function() {
|
||||
if ( this.disabled )
|
||||
return;
|
||||
|
||||
// Position it accordingly, relative to screen root (since
|
||||
// it's attached to document.body)
|
||||
this.menu.style.left = dojo.style.totalOffsetLeft(this.button) + "px";
|
||||
this.menu.style.top = dojo.style.totalOffsetTop(this.button) + dojo.style.getOuterHeight(this.button) + "px";
|
||||
|
||||
// Display the menu; do this funky code below to stop the menu from extending
|
||||
// all the way to the right edge of the screen.
|
||||
// TODO: retest simple display="" to confirm that it doesn't work.
|
||||
try {
|
||||
this.menu.style.display="table"; // mozilla
|
||||
} catch(e) {
|
||||
this.menu.style.display="block"; // IE
|
||||
}
|
||||
|
||||
// If someone clicks somewhere else on the screen then close the menu
|
||||
dojo.event.connect(document.documentElement, "onmousedown", this, "onCanvasMouseDown");
|
||||
|
||||
// When someone clicks the menu, after the menu handles the event,
|
||||
// close the menu (be careful not to close the menu too early or else
|
||||
// the menu will never receive the event.)
|
||||
dojo.event.connect(this.menu, "onclick", this, "hideMenu");
|
||||
},
|
||||
|
||||
hideMenu: function() {
|
||||
this.menu.style.display = "none";
|
||||
dojo.event.disconnect(document.documentElement, "onmousedown", this, "onCanvasMouseDown");
|
||||
dojo.event.disconnect(this.menu, "onclick", this, "hideMenu");
|
||||
}
|
||||
});
|
||||
|
||||
|
198
webapp/web/src/widget/html/GoogleMap.js
Normal file
198
webapp/web/src/widget/html/GoogleMap.js
Normal file
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
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.GoogleMap");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.math");
|
||||
dojo.require("dojo.uri.Uri");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.widget.GoogleMap");
|
||||
|
||||
(function(){
|
||||
var gkey = djConfig["gMapKey"]||djConfig["googleMapKey"];
|
||||
|
||||
// the Google API key mechanism sucks. We're hardcoding here for love and affection but I don't like it.
|
||||
var uri=new dojo.uri.Uri(window.location.href);
|
||||
if(uri.host=="www.dojotoolkit.org"){
|
||||
gkey="ABQIAAAACUNdgv_7FGOmUslbm9l6_hRqjp7ri2mNiOEYqetD3xnFHpt5rBSjszDd1sdufPyQKUTyCf_YxoIxvw";
|
||||
}
|
||||
else if(uri.host=="blog.dojotoolkit.org"){
|
||||
gkey="ABQIAAAACUNdgv_7FGOmUslbm9l6_hSkep6Av1xaMhVn3yCLkorJeXeLARQ6fammI_P3qSGleTJhoI5_1JmP_Q";
|
||||
}
|
||||
else if(uri.host=="archive.dojotoolkit.org"){
|
||||
gkey="ABQIAAAACUNdgv_7FGOmUslbm9l6_hTaQpDt0dyGLIHbXMPTzg1kWeAfwRTwZNyrUfbfxYE9yIvRivEjcXoDTg";
|
||||
}
|
||||
else if(uri.host=="dojotoolkit.org"){
|
||||
gkey="ABQIAAAACUNdgv_7FGOmUslbm9l6_hSaOaO_TgJ5c3mtQFnk5JO2zD5dZBRZk-ieqVs7BORREYNzAERmcJoEjQ";
|
||||
}
|
||||
|
||||
if(!dojo.hostenv.post_load_){
|
||||
var tag = "<scr"+"ipt src='http://maps.google.com/maps?file=api&v=2&key="+gkey+"'></scri"+"pt>";
|
||||
if(!dj_global["GMap2"]){ // prevent multi-inclusion
|
||||
document.write(tag);
|
||||
}
|
||||
}else{
|
||||
dojo.debug("cannot initialize map system after the page has been loaded! Please either manually include the script block provided by Google in your page or require() the GoogleMap widget before onload has fired");
|
||||
}
|
||||
})();
|
||||
|
||||
dojo.widget.html.GoogleMap=function(){
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
dojo.widget.GoogleMap.call(this);
|
||||
|
||||
var gm=dojo.widget.GoogleMap;
|
||||
|
||||
this.map=null;
|
||||
this.data=[];
|
||||
this.datasrc="";
|
||||
// FIXME: this is pehraps the stupidest way to specify this enum I can think of
|
||||
this.controls=[gm.Controls.LargeMap,gm.Controls.Scale,gm.Controls.MapType];
|
||||
};
|
||||
dojo.inherits(dojo.widget.html.GoogleMap, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.GoogleMap, {
|
||||
templatePath:null,
|
||||
templateCssPath:null,
|
||||
|
||||
setControls:function(){
|
||||
var c=dojo.widget.GoogleMap.Controls;
|
||||
for(var i=0; i<this.controls.length; i++){
|
||||
var type=this.controls[i];
|
||||
switch(type){
|
||||
case c.LargeMap:{
|
||||
this.map.addControl(new GLargeMapControl());
|
||||
break;
|
||||
}
|
||||
case c.SmallMap:{
|
||||
this.map.addControl(new GSmallMapControl());
|
||||
break;
|
||||
}
|
||||
case c.SmallZoom:{
|
||||
this.map.addControl(new GSmallZoomControl());
|
||||
break;
|
||||
}
|
||||
case c.Scale:{
|
||||
this.map.addControl(new GScaleControl());
|
||||
break;
|
||||
}
|
||||
case c.MapType:{
|
||||
this.map.addControl(new GMapTypeControl());
|
||||
break;
|
||||
}
|
||||
case c.Overview:{
|
||||
this.map.addControl(new GOverviewMapControl());
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
findCenter:function(bounds){
|
||||
var clat=(bounds.getNorthEast().lat()+bounds.getSouthWest().lat())/2;
|
||||
var clng=(bounds.getNorthEast().lng()+bounds.getSouthWest().lng())/2;
|
||||
return (new GLatLng(clat,clng));
|
||||
},
|
||||
|
||||
createPinpoint:function(pt,overlay){
|
||||
var m=new GMarker(pt);
|
||||
if(overlay){
|
||||
GEvent.addListener(m,"click",function(){
|
||||
m.openInfoWindowHtml("<div>"+overlay+"</div>");
|
||||
});
|
||||
}
|
||||
return m;
|
||||
},
|
||||
|
||||
parse:function(table){
|
||||
this.data=[];
|
||||
|
||||
// get the column indices
|
||||
var h=table.getElementsByTagName("thead")[0];
|
||||
if(!h){
|
||||
return;
|
||||
}
|
||||
|
||||
var a=[];
|
||||
var cols=h.getElementsByTagName("td");
|
||||
if(cols.length==0){
|
||||
cols=h.getElementsByTagName("th");
|
||||
}
|
||||
for(var i=0; i<cols.length; i++){
|
||||
var c=cols[i].innerHTML.toLowerCase();
|
||||
if(c=="long") c="lng";
|
||||
a.push(c);
|
||||
}
|
||||
|
||||
// parse the data
|
||||
var b=table.getElementsByTagName("tbody")[0];
|
||||
if(!b){
|
||||
return;
|
||||
}
|
||||
for(var i=0; i<b.childNodes.length; i++){
|
||||
if(!(b.childNodes[i].nodeName&&b.childNodes[i].nodeName.toLowerCase()=="tr")){
|
||||
continue;
|
||||
}
|
||||
var cells=b.childNodes[i].getElementsByTagName("td");
|
||||
var o={};
|
||||
for(var j=0; j<a.length; j++){
|
||||
var col=a[j];
|
||||
if(col=="lat"||col=="lng"){
|
||||
o[col]=parseFloat(cells[j].innerHTML);
|
||||
}else{
|
||||
o[col]=cells[j].innerHTML;
|
||||
}
|
||||
}
|
||||
this.data.push(o);
|
||||
}
|
||||
},
|
||||
render:function(){
|
||||
var bounds=new GLatLngBounds();
|
||||
var d=this.data;
|
||||
var pts=[];
|
||||
for(var i=0; i<d.length; i++){
|
||||
bounds.extend(new GLatLng(d[i].lat,d[i].lng));
|
||||
}
|
||||
|
||||
this.map.setCenter(this.findCenter(bounds), this.map.getBoundsZoomLevel(bounds));
|
||||
|
||||
for(var i=0; i<this.data.length; i++){
|
||||
var p=new GLatLng(this.data[i].lat,this.data[i].lng);
|
||||
var d=this.data[i].description||null;
|
||||
var m=this.createPinpoint(p,d);
|
||||
this.map.addOverlay(m);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
initialize:function(args, frag){
|
||||
if(!GMap2){
|
||||
dojo.raise("dojo.widget.GoogleMap: The Google Map script must be included (with a proper API key) in order to use this widget.");
|
||||
}
|
||||
if(this.datasrc){
|
||||
this.parse(dojo.byId(this.datasrc));
|
||||
}
|
||||
else if(this.domNode.getElementsByTagName("table")[0]){
|
||||
this.parse(this.domNode.getElementsByTagName("table")[0]);
|
||||
}
|
||||
},
|
||||
postCreate:function(){
|
||||
// clean the domNode before creating the map.
|
||||
while(this.domNode.childNodes.length>0){
|
||||
this.domNode.removeChild(this.domNode.childNodes[0]);
|
||||
}
|
||||
this.map=new GMap2(this.domNode);
|
||||
this.render();
|
||||
this.setControls();
|
||||
}
|
||||
});
|
54
webapp/web/src/widget/html/LinkPane.js
Normal file
54
webapp/web/src/widget/html/LinkPane.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
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.provide("dojo.widget.html.LinkPane");
|
||||
|
||||
//
|
||||
// a div that loads from a URL. (Similar to an iframe, but
|
||||
// it's in the same environment as the main window)
|
||||
//
|
||||
|
||||
dojo.require("dojo.widget.LinkPane");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.io.*");
|
||||
dojo.require("dojo.widget.ContentPane");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.style");
|
||||
dojo.require("dojo.dom");
|
||||
dojo.require("dojo.string");
|
||||
|
||||
|
||||
dojo.widget.html.LinkPane = function(){
|
||||
dojo.widget.html.ContentPane.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.LinkPane, dojo.widget.html.ContentPane);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.LinkPane, {
|
||||
widgetType: "LinkPane",
|
||||
|
||||
// I'm using a template because the user may specify the input as
|
||||
// <a href="foo.html">label</a>, in which case we need to get rid of the
|
||||
// <a> because we don't want a link.
|
||||
templateString: '<div class="dojoLinkPane"></div>',
|
||||
|
||||
fillInTemplate: function(args, frag){
|
||||
var source = this.getFragNodeRef(frag);
|
||||
|
||||
// If user has specified node contents, they become the label
|
||||
// (the link must be plain text)
|
||||
this.label += source.innerHTML;
|
||||
|
||||
var source = this.getFragNodeRef(frag);
|
||||
dojo.html.copyStyle(this.domNode, source);
|
||||
}
|
||||
});
|
51
webapp/web/src/widget/html/Menu.js
Normal file
51
webapp/web/src/widget/html/Menu.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
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.Menu");
|
||||
dojo.provide("dojo.widget.html.Menu");
|
||||
|
||||
/* HtmlMenu
|
||||
***********/
|
||||
|
||||
dojo.widget.html.Menu = function(){
|
||||
dojo.widget.html.Menu.superclass.constructor.call(this);
|
||||
this.items = [];
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.Menu, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.Menu, {
|
||||
widgetType: "Menu",
|
||||
isContainer: true,
|
||||
|
||||
// copy children widgets output directly to parent (this node), to avoid
|
||||
// errors trying to insert an <li> under a <div>
|
||||
snarfChildDomOutput: true,
|
||||
|
||||
templateString: '<ul></ul>',
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/Menu.css"),
|
||||
|
||||
fillInTemplate: function (args, frag){
|
||||
//dojo.widget.HtmlMenu.superclass.fillInTemplate.apply(this, arguments);
|
||||
this.domNode.className = "dojoMenu";
|
||||
},
|
||||
|
||||
|
||||
_register: function (item ) {
|
||||
dojo.event.connect(item, "onSelect", this, "onSelect");
|
||||
this.items.push(item);
|
||||
},
|
||||
|
||||
push: function (item) {
|
||||
this.domNode.appendChild(item.domNode);
|
||||
this._register(item);
|
||||
}
|
||||
|
||||
});
|
||||
|
60
webapp/web/src/widget/html/MenuItem.js
Normal file
60
webapp/web/src/widget/html/MenuItem.js
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
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.MenuItem");
|
||||
|
||||
/* HtmlMenuItem
|
||||
***************/
|
||||
|
||||
dojo.widget.html.MenuItem = function(){
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.MenuItem, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.MenuItem, {
|
||||
widgetType: "MenuItem",
|
||||
templateString: '<li class="dojoMenuItem" dojoAttachEvent="onMouseOver; onMouseOut; onMouseDown; onMouseUp; onClick;"></li>',
|
||||
title: "",
|
||||
|
||||
fillInTemplate: function(args, frag){
|
||||
dojo.html.disableSelection(this.domNode);
|
||||
|
||||
if(!dojo.string.isBlank(this.title)){
|
||||
this.domNode.appendChild(document.createTextNode(this.title));
|
||||
}else{
|
||||
this.domNode.appendChild(frag["dojo:"+this.widgetType.toLowerCase()]["nodeRef"]);
|
||||
}
|
||||
},
|
||||
|
||||
onMouseOver: function(e){
|
||||
dojo.html.addClass(this.domNode, "dojoMenuItemHover");
|
||||
},
|
||||
|
||||
onMouseOut: function(e){
|
||||
dojo.html.removeClass(this.domNode, "dojoMenuItemHover");
|
||||
},
|
||||
|
||||
onClick: function(e){ this.onSelect(this, e); },
|
||||
onMouseDown: function(e){},
|
||||
onMouseUp: function(e){},
|
||||
|
||||
// By default, when I am clicked, click the item inside of me
|
||||
onSelect: function (item, e) {
|
||||
var child = dojo.dom.getFirstChildElement(this.domNode);
|
||||
if(child){
|
||||
if(child.click){
|
||||
child.click();
|
||||
}else if(child.href){
|
||||
location.href = child.href;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
134
webapp/web/src/widget/html/MonthlyCalendar.js
Normal file
134
webapp/web/src/widget/html/MonthlyCalendar.js
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
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.MonthlyCalendar");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.html.DatePicker");
|
||||
dojo.require("dojo.widget.MonthlyCalendar");
|
||||
//dojo.require("dojo.widget.MonthlyCalendar.util");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.html");
|
||||
|
||||
dojo.widget.html.MonthlyCalendar= function(){
|
||||
dojo.widget.MonthlyCalendar.call(this);
|
||||
//dojo.widget.html.DatePicker.call(this);
|
||||
this.widgetType = "MonthlyCalendar";
|
||||
this.templatePath = dojo.uri.dojoUri("src/widget/templates/HtmlMonthlyCalendar.html");
|
||||
this.templateCssPath = dojo.uri.dojoUri("src/widget/templates/HtmlMonthlyCalendar.css");
|
||||
|
||||
this.iCalendars = [];
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.MonthlyCalendar, dojo.widget.html.DatePicker);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.MonthlyCalendar, {
|
||||
cache: function() {
|
||||
},
|
||||
|
||||
addCalendar: function(/* dojo.iCalendar */ cal) {
|
||||
dojo.debug("Adding Calendar");
|
||||
this.iCalendars.push(cal);
|
||||
dojo.debug("Starting init");
|
||||
this.initUI()
|
||||
dojo.debug("done init");
|
||||
},
|
||||
|
||||
createDayContents: function(node,mydate) {
|
||||
dojo.dom.removeChildren(node);
|
||||
node.appendChild(document.createTextNode(mydate.getDate()));
|
||||
for(var x=0; x<this.iCalendars.length; x++) {
|
||||
var evts = this.iCalendars[x].getEvents(mydate);
|
||||
if ((dojo.lang.isArray(evts)) && (evts.length>0)) {
|
||||
for(var y=0;y<evts.length;y++) {
|
||||
var el = document.createElement("div");
|
||||
dojo.html.addClass(el, "dojoMonthlyCalendarEvent");
|
||||
el.appendChild(document.createTextNode(evts[y].summary.value));
|
||||
el.width = dojo.style.getContentWidth(node);
|
||||
node.appendChild(el);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
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);
|
||||
var lastDay = new Date(this.firstSaturday.year, this.firstSaturday.month, this.firstSaturday.date + 42, 8);
|
||||
|
||||
if (this.iCalendars.length > 0) {
|
||||
for (var x=0; x<this.iCalendars.length;x++) {
|
||||
this.iCalendars[x].preComputeRecurringEvents(lastDay);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
this.createDayContents(currentCalendarNode, nextDate);
|
||||
|
||||
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);
|
||||
|
||||
this.createDayContents(currentCalendarNode, nextDate);
|
||||
|
||||
dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "previous"));
|
||||
previousDate = nextDate;
|
||||
nextDate = this.incrementDate(nextDate, false);
|
||||
}
|
||||
} else {
|
||||
nextDate.setDate(1);
|
||||
for(var i=0; i<7; i++) {
|
||||
currentCalendarNode = calendarNodes.item(i);
|
||||
this.createDayContents(currentCalendarNode, nextDate);
|
||||
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)) {
|
||||
this.createDayContents(currentCalendarNode, nextDate);
|
||||
dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "current"));
|
||||
currentCalendarNode = calendarNodes.item(++count);
|
||||
previousDate = nextDate;
|
||||
nextDate = this.incrementDate(nextDate, true);
|
||||
}
|
||||
|
||||
while(count < 42) {
|
||||
this.createDayContents(currentCalendarNode, nextDate);
|
||||
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);
|
||||
}
|
||||
});
|
177
webapp/web/src/widget/html/Show.js
Normal file
177
webapp/web/src/widget/html/Show.js
Normal file
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
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.Show");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.widget.Show");
|
||||
dojo.require("dojo.uri.Uri");
|
||||
dojo.require("dojo.event");
|
||||
dojo.require("dojo.animation.Animation");
|
||||
dojo.require("dojo.math.curves");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.lang.common");
|
||||
dojo.require("dojo.lang.func");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.Show",
|
||||
dojo.widget.HtmlWidget,
|
||||
null,
|
||||
"html",
|
||||
function(){
|
||||
dojo.widget.Show.call(this);
|
||||
}
|
||||
);
|
||||
dojo.lang.extend(dojo.widget.html.Show, dojo.widget.Show.prototype);
|
||||
dojo.lang.extend(dojo.widget.html.Show, {
|
||||
body: null,
|
||||
nav: null,
|
||||
hider: null,
|
||||
select: null,
|
||||
option: null,
|
||||
inNav: false,
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlShow.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlShow.css"),
|
||||
fillInTemplate: function(args, frag){
|
||||
var source = this.getFragNodeRef(frag);
|
||||
this.sourceNode = document.body.appendChild(source.cloneNode(true));
|
||||
for(var i = 0, child; child = this.sourceNode.childNodes[i]; i++){
|
||||
if(child.tagName && child.getAttribute("dojotype").toLowerCase() == "showslide"){
|
||||
child.className = "dojoShowPrintSlide";
|
||||
child.innerHTML = "<h1>" + child.title + "</h1>" + child.innerHTML;
|
||||
}
|
||||
}
|
||||
this.sourceNode.className = "dojoShowPrint";
|
||||
this.sourceNode.style.display = "none";
|
||||
|
||||
dojo.event.connect(document, "onclick", this, "gotoSlideByEvent");
|
||||
dojo.event.connect(document, "onkeypress", this, "gotoSlideByEvent");
|
||||
dojo.event.connect(window, "onresize", this, "resizeWindow");
|
||||
dojo.event.connect(this.nav, "onmousemove", this, "popUpNav");
|
||||
},
|
||||
postCreate: function(){
|
||||
this._slides = [];
|
||||
for(var i = 0, child; child = this.children[i]; i++){
|
||||
if(child.widgetType == "ShowSlide"){
|
||||
this._slides.push(child);
|
||||
this.option.text = child.title;
|
||||
this.option.parentNode.insertBefore(this.option.cloneNode(true), this.option);
|
||||
}
|
||||
}
|
||||
this.option.parentNode.removeChild(this.option);
|
||||
|
||||
document.body.style.display = "block";
|
||||
this.resizeWindow();
|
||||
this.gotoSlide(0);
|
||||
},
|
||||
gotoSlide: function(/*int*/ slide){
|
||||
if(slide == this._slide){
|
||||
return;
|
||||
}
|
||||
|
||||
if(!this._slides[slide]){
|
||||
// slide: string
|
||||
for(var i = 0, child; child = this._slides[i]; i++){
|
||||
if(child.title == slide){
|
||||
slide = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!this._slides[slide]){
|
||||
return;
|
||||
}
|
||||
|
||||
if(this._slide != -1){
|
||||
while(this._slides[this._slide].previousAction()){}
|
||||
}
|
||||
|
||||
this._slide = slide;
|
||||
this.select.selectedIndex = slide;
|
||||
while(this.contentNode.hasChildNodes()){ this.contentNode.removeChild(this.contentNode.firstChild); }
|
||||
this.contentNode.appendChild(this._slides[slide].domNode);
|
||||
},
|
||||
gotoSlideByEvent: function(/*Event*/ event){
|
||||
var node = event.target;
|
||||
var type = event.type;
|
||||
if(type == "click"){
|
||||
if(node.tagName == "OPTION"){
|
||||
this.gotoSlide(node.index);
|
||||
}else if(node.tagName == "SELECT"){
|
||||
this.gotoSlide(node.selectedIndex);
|
||||
}else if(node.tagName != "A"){
|
||||
this.nextSlide(event);
|
||||
}
|
||||
}else if(type == "keypress"){
|
||||
var key = event.keyCode;
|
||||
var ch = event.charCode;
|
||||
if(key == 63234 || key == 37){
|
||||
this.previousSlide(event);
|
||||
}else if(key == 63235 || key == 39 || ch == 32){
|
||||
this.nextSlide(event);
|
||||
}
|
||||
}
|
||||
},
|
||||
nextSlide: function(/*Event?*/ event){
|
||||
this.stopEvent(event);
|
||||
return dojo.widget.Show.prototype.nextSlide.call(this, event);
|
||||
},
|
||||
previousSlide: function(/*Event?*/ event){
|
||||
this.stopEvent(event);
|
||||
return dojo.widget.Show.prototype.previousSlide.call(this, event);
|
||||
},
|
||||
stopEvent: function(/*Event*/ ev){
|
||||
if(window.event){
|
||||
ev.returnValue = false;
|
||||
ev.cancelBubble = true;
|
||||
}else{
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
}
|
||||
},
|
||||
popUpNav: function(){
|
||||
if(!this.inNav){
|
||||
dojo.widget.Show.node = this.nav;
|
||||
var anim = new dojo.animation.Animation(new dojo.math.curves.Line([5], [30]), 250, -1);
|
||||
dojo.event.connect(anim, "onAnimate", function(e) {
|
||||
dojo.widget.Show.node.style.height = e.x + "px";
|
||||
});
|
||||
dojo.event.connect(anim, "onEnd", function(e) {
|
||||
dojo.widget.Show.node.style.height = e.x + "px";
|
||||
});
|
||||
anim.play(true);
|
||||
}
|
||||
clearTimeout(this.inNav);
|
||||
this.inNav = setTimeout(dojo.lang.hitch(this, "hideNav"), 2000);
|
||||
},
|
||||
hideNav: function(){
|
||||
clearTimeout(this.inNav);
|
||||
this.inNav = false;
|
||||
|
||||
dojo.widget.Show.node = this.nav;
|
||||
var anim = new dojo.animation.Animation(new dojo.math.curves.Line([30], [5]), 250, 1);
|
||||
dojo.event.connect(anim, "onAnimate", function(e) {
|
||||
dojo.widget.Show.node.style.height = e.x + "px";
|
||||
});
|
||||
dojo.event.connect(anim, "onEnd", function(e) {
|
||||
dojo.widget.Show.node.style.height = e.x + "px";
|
||||
});
|
||||
anim.play(true);
|
||||
},
|
||||
resizeWindow: function(/*Event*/ ev){
|
||||
document.body.style.height = "auto";
|
||||
var h = Math.max(
|
||||
document.documentElement.scrollHeight || document.body.scrollHeight,
|
||||
dojo.html.getViewportHeight());
|
||||
document.body.style.height = h + "px";
|
||||
}
|
||||
});
|
28
webapp/web/src/widget/html/ShowAction.js
Normal file
28
webapp/web/src/widget/html/ShowAction.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
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.ShowAction");
|
||||
|
||||
dojo.require("dojo.widget.ShowAction");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.lang.common");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.ShowAction",
|
||||
dojo.widget.HtmlWidget,
|
||||
null,
|
||||
"html",
|
||||
function(){
|
||||
dojo.widget.ShowAction.call(this);
|
||||
}
|
||||
);
|
||||
dojo.lang.extend(dojo.widget.html.ShowAction, dojo.widget.ShowAction.prototype);
|
||||
dojo.lang.extend(dojo.widget.html.ShowAction, {
|
||||
});
|
189
webapp/web/src/widget/html/ShowSlide.js
Normal file
189
webapp/web/src/widget/html/ShowSlide.js
Normal file
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
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.ShowSlide");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.lang.common");
|
||||
dojo.require("dojo.widget.ShowSlide");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.lfx.html");
|
||||
dojo.require("dojo.animation.Animation");
|
||||
dojo.require("dojo.graphics.color");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.ShowSlide",
|
||||
dojo.widget.HtmlWidget,
|
||||
null,
|
||||
"html",
|
||||
function(){
|
||||
dojo.widget.ShowSlide.call(this);
|
||||
}
|
||||
);
|
||||
dojo.lang.extend(dojo.widget.html.ShowSlide, dojo.widget.ShowSlide.prototype);
|
||||
dojo.lang.extend(dojo.widget.html.ShowSlide, {
|
||||
htmlTitle: null,
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlShowSlide.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlShowSlide.css"),
|
||||
fillInTemplate: function(){
|
||||
this.htmlTitle.innerHTML = this.title;
|
||||
|
||||
this._components = {};
|
||||
var nodes = this.containerNode.all ? this.containerNode.all : this.containerNode.getElementsByTagName('*');
|
||||
for(var i = 0, node; node = nodes[i]; i++){
|
||||
var as = node.getAttribute("as");
|
||||
if(as){
|
||||
if(!this._components[as]){
|
||||
this._components[as] = [];
|
||||
}
|
||||
this._components[as].push(node);
|
||||
}
|
||||
}
|
||||
},
|
||||
postCreate: function(){
|
||||
this._actions = [];
|
||||
for(var i = 0, child; child = this.children[i]; i++){
|
||||
if(child.widgetType == "ShowAction"){
|
||||
this._actions.push(child);
|
||||
var components = this._components[child.on];
|
||||
for(var j = 0, component; component = components[j]; j++){
|
||||
if(child.action && child.action != "remove"){
|
||||
this.hideComponent(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
previousAction: function(/*Event?*/ event){
|
||||
this.stopEvent(event);
|
||||
|
||||
var action = this._actions[this._action];
|
||||
if(!action){
|
||||
return false;
|
||||
}
|
||||
|
||||
var on = action.on;
|
||||
while(action.on == on){
|
||||
var components = this._components[on];
|
||||
for(var i = 0, component; component = components[i]; i++){
|
||||
if(action.action == "remove"){
|
||||
if(component.style.display == "none"){
|
||||
component.style.display = "";
|
||||
component.style.visibility = "visible";
|
||||
var exits = true;
|
||||
}
|
||||
}else if(action.action){
|
||||
this.hideComponent(component);
|
||||
}
|
||||
}
|
||||
|
||||
--this._action;
|
||||
|
||||
if(exits){
|
||||
return true;
|
||||
}
|
||||
|
||||
if(action.auto == "true"){
|
||||
on = this._actions[this._action].on;
|
||||
}
|
||||
|
||||
action = this._actions[this._action];
|
||||
if(!action){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
hideComponent: function(/*Node*/ component){
|
||||
component.style.visibility = "hidden";
|
||||
component.style.backgroundColor = "transparent";
|
||||
var parent = component.parentNode;
|
||||
if((parent)&&(parent.tagName == "LI")){
|
||||
parent.oldType = parent.style.listStyleType;
|
||||
parent.style.listStyleType = "none";
|
||||
}
|
||||
},
|
||||
nextAction: function(/*Event?*/ event){
|
||||
this.stopEvent(event);
|
||||
|
||||
if(!dojo.widget.ShowSlide.prototype.nextAction.call(this, event)){
|
||||
return false;
|
||||
}
|
||||
|
||||
var action = this._actions[this._action];
|
||||
if(!action){
|
||||
return false;
|
||||
}
|
||||
|
||||
var components = this._components[action.on];
|
||||
for(var i = 0, component; component = components[i]; i++){
|
||||
if(action.action){
|
||||
var duration = action.duration || 1000;
|
||||
if(action.action == "fade"){
|
||||
dojo.style.setOpacity(component, 0);
|
||||
dojo.lfx.html.fadeIn(component, duration).play(true);
|
||||
}else if(action.action == "fly"){
|
||||
var width = dojo.style.getMarginBoxWidth(component);
|
||||
var position = dojo.style.getAbsolutePosition(component);
|
||||
// alert(position);
|
||||
component.style.position = "relative";
|
||||
component.style.left = -(width + position.x) + "px";
|
||||
dojo.lfx.html.slideBy(component, [0, (width + position.x)], duration, -1, this.callWith).play(true);
|
||||
}else if(action.action == "wipe"){
|
||||
dojo.lfx.html.wipeIn(component, duration).play();
|
||||
}else if(action.action == "color"){
|
||||
var from = new dojo.graphics.color.Color(action.from).toRgb();
|
||||
var to = new dojo.graphics.color.Color(action.to).toRgb();
|
||||
var anim = new dojo.animation.Animation(new dojo.math.curves.Line(from, to), duration, 0);
|
||||
node = component;
|
||||
dojo.event.connect(anim, "onAnimate", function(e) {
|
||||
node.style.color = "rgb(" + e.coordsAsInts().join(",") + ")";
|
||||
});
|
||||
anim.play(true);
|
||||
}else if(action.action == "bgcolor"){
|
||||
dojo.lfx.html.unhighlight(component, action.to, duration).play();
|
||||
}else if(action.action == "remove"){
|
||||
component.style.display = "none";
|
||||
}
|
||||
component.style.visibility = "visible";
|
||||
}
|
||||
}
|
||||
|
||||
action = this._actions[this._action + 1];
|
||||
if(action && action.auto == "true"){
|
||||
this.nextAction();
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
callWith: function(/*Node*/ node){
|
||||
if(!node){ return; }
|
||||
if(dojo.lang.isArray(node)){
|
||||
dojo.lang.forEach(node, arguments.callee);
|
||||
return;
|
||||
}
|
||||
var parent = node.parentNode;
|
||||
if((parent)&&(parent.tagName.toLowerCase() == "li")){
|
||||
parent.style.listStyleType = parent.oldType;
|
||||
}
|
||||
},
|
||||
stopEvent: function(/*Event*/ ev){
|
||||
if(!ev){
|
||||
return;
|
||||
}
|
||||
if(window.event){
|
||||
ev.returnValue = false;
|
||||
ev.cancelBubble = true;
|
||||
}else{
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
}
|
||||
}
|
||||
});
|
500
webapp/web/src/widget/html/Slider.js
Normal file
500
webapp/web/src/widget/html/Slider.js
Normal file
|
@ -0,0 +1,500 @@
|
|||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
/**
|
||||
* Slider Widget.
|
||||
*
|
||||
* The slider widget comes in three forms:
|
||||
* 1. Base Slider widget which supports movement in x and y dimensions
|
||||
* 2. Vertical Slider (SliderVertical) widget which supports movement
|
||||
* only in the y dimension.
|
||||
* 3. Horizontal Slider (SliderHorizontal) widget which supports movement
|
||||
* only in the x dimension.
|
||||
*
|
||||
* The key objects in the widget are:
|
||||
* - a container div which displays a bar in the background (Slider object)
|
||||
* - a handle inside the container div, which represents the value
|
||||
* (sliderHandle DOM node)
|
||||
* - the object which moves the handle (handleMove is of type
|
||||
* SliderDragMoveSource)
|
||||
*
|
||||
* The values for the slider are calculated by grouping pixels together,
|
||||
* based on the number of values to be represented by the slider.
|
||||
* The number of pixels in a group is called the valueSize
|
||||
* e.g. if slider is 150 pixels long, and is representing the values
|
||||
* 0,1,...10 then pixels are grouped into lots of 15 (valueSize), where:
|
||||
* value 0 maps to pixels 0 - 7
|
||||
* 1 8 - 22
|
||||
* 2 23 - 37 etc.
|
||||
* The accuracy of the slider is limited to the number of pixels
|
||||
* (i.e tiles > pixels will result in the slider not being able to
|
||||
* represent some values).
|
||||
*
|
||||
* Technical Notes:
|
||||
* - 3 widgets exist because the framework caches the template in
|
||||
* dojo.widget.fillFromTemplateCache (which ignores the changed URI)
|
||||
*
|
||||
* Todo:
|
||||
* - Setting of initial value currently doesn't work, because the one or
|
||||
* more of the offsets, constraints or containing block are not set and
|
||||
* are required to set the valueSize is not set before fillInTemplate
|
||||
* is called.
|
||||
* - Issues with dragging handle when page has been scrolled
|
||||
* -
|
||||
*
|
||||
* References (aka sources of inspiration):
|
||||
* - http://dojotoolkit.org/docs/fast_widget_authoring.html
|
||||
* - http://dojotoolkit.org/docs/dojo_event_system.html
|
||||
*
|
||||
* @author Marcel Linnenfelser (m.linnen@synflag.de)
|
||||
* @author Mathew Pole (mathew.pole@ebor.com)
|
||||
*
|
||||
* $Id: $
|
||||
*/
|
||||
|
||||
// tell the package system what functionality is provided in this module (file)
|
||||
// (note that the package system works on modules, not the classes)
|
||||
dojo.provide("dojo.widget.html.Slider");
|
||||
|
||||
// load dependencies
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.dnd.*");
|
||||
// dojo.dnd.* doesn't include this package, because it's not in __package__.js
|
||||
dojo.require("dojo.dnd.HtmlDragMove");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.style");
|
||||
|
||||
|
||||
/**
|
||||
* Define the two dimensional slider widget class.
|
||||
*/
|
||||
dojo.widget.defineWidget (
|
||||
"dojo.widget.html.Slider",
|
||||
dojo.widget.HtmlWidget,
|
||||
{
|
||||
// over-ride some defaults
|
||||
isContainer: false,
|
||||
widgetType: "Slider",
|
||||
|
||||
// useful properties (specified as attributes in the html tag)
|
||||
// number of values to be represented by slider in the horizontal direction
|
||||
valuesX: 10,
|
||||
// number of values to be represented by slider in the vertical direction
|
||||
valuesY: 10,
|
||||
// can values be changed on the x (horizontal) axis?
|
||||
isEnableX: true,
|
||||
// can values be changed on the y (vertical) axis?
|
||||
isEnableY: true,
|
||||
// value size (pixels) in the x dimension
|
||||
valueSizeX: 0.0,
|
||||
// value size (pixels) in the y dimension
|
||||
valueSizeY: 0.0,
|
||||
// initial value in the x dimension
|
||||
initialValueX: 0,
|
||||
// initial value in the y dimension
|
||||
initialValueY: 0,
|
||||
|
||||
// do we allow the user to click on the slider to set the position?
|
||||
// (note: dojo's infrastructor will convert attribute to a boolean)
|
||||
clickSelect: true,
|
||||
// should the handle snap to the grid or remain where it was dragged to?
|
||||
// (note: dojo's infrastructor will convert attribute to a boolean)
|
||||
snapToGrid: false,
|
||||
// should the value change while you are dragging, or just after drag finishes?
|
||||
activeDrag: false,
|
||||
|
||||
templateCssPath: dojo.uri.dojoUri ("src/widget/templates/HtmlSlider.css"),
|
||||
templatePath: dojo.uri.dojoUri ("src/widget/templates/HtmlSlider.html"),
|
||||
|
||||
// our DOM nodes
|
||||
sliderHandle: null,
|
||||
|
||||
// private attributes
|
||||
// This is set to true when a drag is started, so that it is not confused
|
||||
// with a click
|
||||
isDragInProgress: false,
|
||||
|
||||
|
||||
// This function is called when the template is loaded
|
||||
fillInTemplate: function ()
|
||||
{
|
||||
// dojo.debug ("fillInTemplate - className = " + this.domNode.className);
|
||||
|
||||
// setup drag-n-drop for the sliderHandle
|
||||
this.handleMove = new dojo.widget.html.SliderDragMoveSource (this.sliderHandle);
|
||||
this.handleMove.setParent (this);
|
||||
dojo.event.connect(this.handleMove, "onDragMove", this, "onDragMove");
|
||||
dojo.event.connect(this.handleMove, "onDragEnd", this, "onDragEnd");
|
||||
dojo.event.connect(this.handleMove, "onClick", this, "onClick");
|
||||
|
||||
// keep the slider handle inside it's parent container
|
||||
this.handleMove.constrainToContainer = true;
|
||||
|
||||
if (this.clickSelect) {
|
||||
dojo.event.connect (this.domNode, "onclick", this, "setPosition");
|
||||
}
|
||||
|
||||
if (this.isEnableX && this.initialValueX > 0) {
|
||||
alert("setting x to " + this.initialValueX);
|
||||
this.setValueX (this.initialValueX);
|
||||
}
|
||||
if (this.isEnableY && this.initialValueY > 0) {
|
||||
this.setValueY (this.initialValueY);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// Move the handle (in the x dimension) to the specified value
|
||||
setValueX: function (value) {
|
||||
if (0.0 == this.valueSizeX) {
|
||||
this.valueSizeX = this.handleMove.calcValueSizeX ();
|
||||
}
|
||||
if (value > this.valuesX) {
|
||||
value = this.valuesX;
|
||||
}
|
||||
else if (value < 0) {
|
||||
value = 0;
|
||||
}
|
||||
//dojo.debug ("value = " + value, ", valueSizeX = " + this.valueSizeX);
|
||||
this.handleMove.domNode.style.left = (value * this.valueSizeX) + "px";
|
||||
},
|
||||
|
||||
|
||||
// Get the number of the value that matches the position of the handle
|
||||
getValueX: function () {
|
||||
if (0.0 == this.valueSizeX) {
|
||||
this.valueSizeX = this.handleMove.calcValueSizeX ();
|
||||
}
|
||||
return Math.round (dojo.style.getPixelValue (this.handleMove.domNode, "left") / this.valueSizeX);
|
||||
},
|
||||
|
||||
|
||||
// set the slider to a particular value
|
||||
setValueY: function (value) {
|
||||
if (0.0 == this.valueSizeY) {
|
||||
this.valueSizeY = this.handleMove.calcValueSizeY ();
|
||||
}
|
||||
if (value > this.valuesY) {
|
||||
value = this.valuesY;
|
||||
}
|
||||
else if (value < 0) {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
this.handleMove.domNode.style.top = (value * this.valueSizeY) + "px";
|
||||
},
|
||||
|
||||
|
||||
// Get the number of the value that the matches the position of the handle
|
||||
getValueY: function () {
|
||||
if (0.0 == this.valueSizeY) {
|
||||
this.valueSizeY = this.handleMove.calcValueSizeY ();
|
||||
}
|
||||
return Math.round (dojo.style.getPixelValue (this.handleMove.domNode, "top") / this.valueSizeY);
|
||||
},
|
||||
|
||||
|
||||
// set the position of the handle
|
||||
setPosition: function (e) {
|
||||
//dojo.debug ("Slider#setPosition - e.clientX = " + e.clientX
|
||||
// + ", e.clientY = " + e.clientY);
|
||||
if (this.isDragInProgress) {
|
||||
this.isDragInProgress = false;
|
||||
}
|
||||
|
||||
var offset = dojo.html.getScrollOffset();
|
||||
var parent = dojo.style.getAbsolutePosition(this.domNode, true);
|
||||
|
||||
if (this.isEnableX) {
|
||||
var x = offset.x + e.clientX - parent.x;
|
||||
if (x > this.domNode.offsetWidth) {
|
||||
x = this.domNode.offsetWidth;
|
||||
}
|
||||
if (this.snapToGrid && x > 0) {
|
||||
if (0.0 == this.valueSizeX) {
|
||||
this.valueSizeX = this.handleMove.calcValueSizeX ();
|
||||
}
|
||||
x = this.valueSizeX * (Math.round (x / this.valueSizeX));
|
||||
}
|
||||
this.handleMove.domNode.style.left = x + "px";
|
||||
}
|
||||
if (this.isEnableY) {
|
||||
var y = offset.y + e.clientY - parent.y;
|
||||
if (y > this.domNode.offsetHeight) {
|
||||
y = this.domNode.offsetHeight;
|
||||
}
|
||||
if (this.snapToGrid && y > 0) {
|
||||
if (0.0 == this.valueSizeY) {
|
||||
this.valueSizeY = this.handleMove.calcValueSizeY ();
|
||||
}
|
||||
y = this.valueSizeY * (Math.round (y / this.valueSizeY));
|
||||
}
|
||||
this.handleMove.domNode.style.top = y + "px";
|
||||
}
|
||||
},
|
||||
|
||||
onDragMove: function(){
|
||||
this.onValueChanged(this.getValueX(), this.getValueY());
|
||||
},
|
||||
|
||||
onClick: function(){
|
||||
this.onValueChanged(this.getValueX(), this.getValueY());
|
||||
},
|
||||
|
||||
onValueChanged: function(x, y){
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
* Define the horizontal slider widget class.
|
||||
*/
|
||||
dojo.widget.defineWidget (
|
||||
"dojo.widget.html.SliderHorizontal",
|
||||
dojo.widget.html.Slider,
|
||||
{
|
||||
widgetType: "SliderHorizontal",
|
||||
|
||||
value: 0,
|
||||
|
||||
isEnableY: false,
|
||||
templatePath: dojo.uri.dojoUri ("src/widget/templates/HtmlSliderHorizontal.html"),
|
||||
|
||||
postMixInProperties: function(){
|
||||
this.initialValue = this.value;
|
||||
},
|
||||
|
||||
// wrapper for getValueX
|
||||
getValue: function () {
|
||||
return this.getValueX ();
|
||||
},
|
||||
|
||||
// wrapper for setValueX
|
||||
setValue: function (value) {
|
||||
this.setValueX (value);
|
||||
this.onValueChanged(value);
|
||||
},
|
||||
|
||||
onDragMove: function(){
|
||||
if(this.activeDrag){
|
||||
this.onValueChanged(this.getValue());
|
||||
}
|
||||
},
|
||||
|
||||
onDragEnd: function(){
|
||||
if(!this.activeDrag){
|
||||
this.onValueChanged(this.getValue());
|
||||
}
|
||||
},
|
||||
|
||||
onClick: function(){
|
||||
this.onValueChanged(this.getValue());
|
||||
},
|
||||
|
||||
onValueChanged: function(value){
|
||||
this.value=value;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
* Define the vertical slider widget class.
|
||||
*/
|
||||
dojo.widget.defineWidget (
|
||||
"dojo.widget.html.SliderVertical",
|
||||
dojo.widget.html.Slider,
|
||||
{
|
||||
widgetType: "SliderVertical",
|
||||
|
||||
value: 0,
|
||||
|
||||
isEnableX: false,
|
||||
templatePath: dojo.uri.dojoUri ("src/widget/templates/HtmlSliderVertical.html"),
|
||||
|
||||
postMixInProperties: function(){
|
||||
this.initialValueY = this.value;
|
||||
},
|
||||
|
||||
// wrapper for getValueY
|
||||
getValue: function () {
|
||||
return this.getValueY ();
|
||||
},
|
||||
|
||||
// wrapper for setValueY
|
||||
setValue: function (value) {
|
||||
this.setValueY (value);
|
||||
},
|
||||
|
||||
onDragMove: function(){
|
||||
if(this.activeDrag){
|
||||
this.onValueChanged(this.getValue());
|
||||
}
|
||||
},
|
||||
|
||||
onDragEnd: function(){
|
||||
if(!this.activeDrag){
|
||||
this.onValueChanged(this.getValue());
|
||||
}
|
||||
},
|
||||
|
||||
onClick: function(){
|
||||
this.onValueChanged(this.getValue());
|
||||
},
|
||||
|
||||
onValueChanged: function(value){
|
||||
this.value=value;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
* This class extends the HtmlDragMoveSource class to provide
|
||||
* features for the slider handle.
|
||||
*/
|
||||
dojo.declare (
|
||||
"dojo.widget.html.SliderDragMoveSource",
|
||||
dojo.dnd.HtmlDragMoveSource,
|
||||
{
|
||||
isDragInProgress: false,
|
||||
slider: null,
|
||||
|
||||
|
||||
/** Setup the handle for drag
|
||||
* Extends dojo.dnd.HtmlDragMoveSource by creating a SliderDragMoveSource */
|
||||
onDragStart: function (e) {
|
||||
this.isDragInProgress = true;
|
||||
this.constrainToContainer = true;
|
||||
|
||||
var dragObj = this.createDragMoveObject ();
|
||||
var constraints = null;
|
||||
|
||||
|
||||
dojo.event.connect (dragObj, "onDragMove", this, "onDragMove");
|
||||
|
||||
return dragObj;
|
||||
},
|
||||
|
||||
|
||||
onDragMove: function (e) {
|
||||
// placeholder to enable event connection
|
||||
},
|
||||
|
||||
|
||||
createDragMoveObject: function () {
|
||||
//dojo.debug ("SliderDragMoveSource#createDragMoveObject - " + this.slider);
|
||||
var dragObj = new dojo.widget.html.SliderDragMoveObject (this.dragObject, this.type);
|
||||
dragObj.slider = this.slider;
|
||||
|
||||
// this code copied from dojo.dnd.HtmlDragSource#onDragStart
|
||||
if (this.dragClass) {
|
||||
dragObj.dragClass = this.dragClass;
|
||||
}
|
||||
if (this.constrainToContainer) {
|
||||
dragObj.constrainTo(this.constrainingContainer || this.domNode.parentNode);
|
||||
}
|
||||
return dragObj;
|
||||
},
|
||||
|
||||
|
||||
setParent: function (slider) {
|
||||
this.slider = slider;
|
||||
},
|
||||
|
||||
|
||||
calcValueSizeX: function () {
|
||||
var dragObj = this.createDragMoveObject ();
|
||||
dragObj.containingBlockPosition = dragObj.domNode.offsetParent ?
|
||||
dojo.style.getAbsolutePosition(dragObj.domNode.offsetParent) : {x:0, y:0};
|
||||
|
||||
var constraints = dragObj.getConstraints ();
|
||||
return (constraints.maxX - constraints.minX) / this.slider.valuesX;
|
||||
},
|
||||
|
||||
|
||||
calcValueSizeY: function () {
|
||||
var dragObj = this.createDragMoveObject ();
|
||||
dragObj.containingBlockPosition = dragObj.domNode.offsetParent ?
|
||||
dojo.style.getAbsolutePosition(dragObj.domNode.offsetParent) : {x:0, y:0};
|
||||
var constraints = dragObj.getConstraints ();
|
||||
return (constraints.maxY - constraints.minY) / this.slider.valuesY;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
* This class extends the HtmlDragMoveObject class to provide
|
||||
* features for the slider handle.
|
||||
*/
|
||||
dojo.declare (
|
||||
"dojo.widget.html.SliderDragMoveObject",
|
||||
dojo.dnd.HtmlDragMoveObject,
|
||||
{
|
||||
// reference to dojo.widget.html.Slider
|
||||
slider: null,
|
||||
|
||||
/** Moves the node to follow the mouse.
|
||||
* Extends functon HtmlDragObject by adding functionality to snap handle
|
||||
* to a discrete value */
|
||||
onDragMove: function (e) {
|
||||
if (this.slider.isEnableX && 0.0 == this.slider.valueSizeX) {
|
||||
this.slider.valueSizeX = (this.constraints.maxX - this.constraints.minX) / this.slider.valuesX;
|
||||
}
|
||||
if (this.slider.isEnableY && 0.0 == this.slider.valueSizeY) {
|
||||
this.slider.valueSizeY = (this.constraints.maxY - this.constraints.minY) / this.slider.valuesY;
|
||||
}
|
||||
|
||||
this.updateDragOffset ();
|
||||
|
||||
var x = this.dragOffset.x + e.pageX;
|
||||
var y = this.dragOffset.y + e.pageY;
|
||||
|
||||
if (this.constrainToContainer) {
|
||||
if (x < this.constraints.minX) { x = this.constraints.minX; }
|
||||
if (y < this.constraints.minY) { y = this.constraints.minY; }
|
||||
if (x > this.constraints.maxX) { x = this.constraints.maxX; }
|
||||
if (y > this.constraints.maxY) { y = this.constraints.maxY; }
|
||||
}
|
||||
|
||||
if (this.slider.isEnableX) {
|
||||
var selectedValue = 0;
|
||||
if (x > 0) {
|
||||
selectedValue = Math.round (x / this.slider.valueSizeX);
|
||||
}
|
||||
// dojo.debug ("x = " + x + ", valueSize = " + valueSize
|
||||
// + ", selectedValue = " + selectedValue);
|
||||
x = (selectedValue * this.slider.valueSizeX);
|
||||
}
|
||||
|
||||
if (this.slider.isEnableY) {
|
||||
var selectedValue = 0;
|
||||
if (y > 0) {
|
||||
selectedValue = Math.round (y / this.slider.valueSizeY);
|
||||
}
|
||||
y = (selectedValue * this.slider.valueSizeY);
|
||||
}
|
||||
|
||||
this.setAbsolutePosition (x, y);
|
||||
}
|
||||
});
|
582
webapp/web/src/widget/html/SortableTable.js
Normal file
582
webapp/web/src/widget/html/SortableTable.js
Normal file
|
@ -0,0 +1,582 @@
|
|||
/*
|
||||
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.SortableTable");
|
||||
dojo.require("dojo.lang");
|
||||
dojo.require("dojo.date");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.widget.SortableTable");
|
||||
|
||||
dojo.widget.html.SortableTable=function(){
|
||||
// summary
|
||||
// Constructor for the SortableTable widget
|
||||
dojo.widget.SortableTable.call(this);
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
|
||||
this.headClass="";
|
||||
this.tbodyClass="";
|
||||
this.headerClass="";
|
||||
this.headerSortUpClass="selected";
|
||||
this.headerSortDownClass="selected";
|
||||
this.rowClass="";
|
||||
this.rowAlternateClass="alt";
|
||||
this.rowSelectedClass="selected";
|
||||
this.columnSelected="sorted-column";
|
||||
};
|
||||
dojo.inherits(dojo.widget.html.SortableTable, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.SortableTable, {
|
||||
templatePath:null,
|
||||
templateCssPath:null,
|
||||
|
||||
getTypeFromString:function(/* string */ s){
|
||||
// summary
|
||||
// Find the constructor that matches param s by searching through the entire object tree.
|
||||
var parts=s.split("."),i=0,obj=dj_global;
|
||||
do{obj=obj[parts[i++]];}while(i<parts.length&&obj);
|
||||
return(obj!=dj_global)?obj:null; // function
|
||||
},
|
||||
compare:function(/* object */ o1, /* object */ o2){
|
||||
// summary
|
||||
// Compare two objects using a shallow property compare
|
||||
for(var p in o1){
|
||||
if(!(p in o2)) return false; // boolean
|
||||
if(o1[p].valueOf()!=o2[p].valueOf()) return false; // boolean
|
||||
}
|
||||
return true; // boolean
|
||||
},
|
||||
isSelected:function(/* object */ o){
|
||||
// summary
|
||||
// checked to see if the passed object is in the current selection.
|
||||
for(var i=0;i<this.selected.length;i++){
|
||||
if(this.compare(this.selected[i],o)){
|
||||
return true; // boolean
|
||||
}
|
||||
}
|
||||
return false; // boolean
|
||||
},
|
||||
removeFromSelected:function(/* object */ o){
|
||||
// summary
|
||||
// remove the passed object from the current selection.
|
||||
var idx=-1;
|
||||
for(var i=0;i<this.selected.length;i++){
|
||||
if(this.compare(this.selected[i],o)){
|
||||
idx=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(idx>=0){
|
||||
this.selected.splice(idx,1);
|
||||
}
|
||||
},
|
||||
getSelection:function(){
|
||||
// summary
|
||||
// return the array of currently selected objects (JSON format)
|
||||
return this.selected; // array
|
||||
},
|
||||
getValue:function(){
|
||||
// summary
|
||||
// return a comma-delimited list of selected valueFields.
|
||||
var a=[];
|
||||
for(var i=0;i<this.selected.length;i++){
|
||||
if (this.selected[i][this.valueField]){
|
||||
a.push(this.selected[i][this.valueField]);
|
||||
}
|
||||
}
|
||||
return a.join(); // string
|
||||
},
|
||||
reset:function(){
|
||||
// summary
|
||||
// completely resets the internal representations.
|
||||
this.columns=[];
|
||||
this.data=[];
|
||||
this.resetSelections(this.domNode.getElementsByTagName("tbody")[0]);
|
||||
},
|
||||
resetSelections:function(/* HTMLTableBodyElement */ body){
|
||||
this.selected=[];
|
||||
var idx=0;
|
||||
var rows=body.getElementsByTagName("tr");
|
||||
for(var i=0; i<rows.length; i++){
|
||||
if(rows[i].parentNode==body){
|
||||
rows[i].removeAttribute("selected");
|
||||
if(this.enableAlternateRows&&idx%2==1){
|
||||
rows[i].className=this.rowAlternateClass;
|
||||
}else{
|
||||
rows[i].className="";
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getObjectFromRow:function(/* HTMLTableRowElement */ row){
|
||||
// summary
|
||||
// creates a JSON object based on the passed row
|
||||
var cells=row.getElementsByTagName("td");
|
||||
var o={};
|
||||
for(var i=0; i<this.columns.length;i++){
|
||||
if(this.columns[i].sortType=="__markup__"){
|
||||
// FIXME: should we parse this instead? Because if the user may not get back the markup they put in...
|
||||
o[this.columns[i].getField()]=cells[i].innerHTML;
|
||||
}else{
|
||||
var text=dojo.html.renderedTextContent(cells[i]);
|
||||
var val=new (this.columns[i].getType())(text);
|
||||
o[this.columns[i].getField()]=val;
|
||||
}
|
||||
}
|
||||
if(dojo.html.hasAttribute(row,"value")){
|
||||
o[this.valueField]=dojo.html.getAttribute(row,"value");
|
||||
}
|
||||
return o; // object
|
||||
},
|
||||
setSelectionByRow:function(/* HTMLTableElementRow */ row){
|
||||
// summary
|
||||
// create the selection object based on the passed row, makes sure it's unique.
|
||||
// note that you need to call render manually (because of multi-select operations)
|
||||
var o=this.getObjectFromRow(row);
|
||||
var b=false;
|
||||
for(var i=0;i<this.selected.length;i++){
|
||||
if(this.compare(this.selected[i], o)){
|
||||
b=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!b){
|
||||
this.selected.push(o);
|
||||
}
|
||||
},
|
||||
|
||||
parseColumns:function(/* HTMLTableHeadElement */ node){
|
||||
// summary
|
||||
// parses the passed element to create column objects
|
||||
this.reset();
|
||||
var row=node.getElementsByTagName("tr")[0];
|
||||
var cells=row.getElementsByTagName("td");
|
||||
if (cells.length==0) cells=row.getElementsByTagName("th");
|
||||
for(var i=0; i<cells.length; i++){
|
||||
var o={
|
||||
field:null,
|
||||
format:null,
|
||||
noSort:false,
|
||||
sortType:"String",
|
||||
dataType:String,
|
||||
sortFunction:null,
|
||||
label:null,
|
||||
align:"left",
|
||||
valign:"middle",
|
||||
getField:function(){ return this.field||this.label; },
|
||||
getType:function(){ return this.dataType; }
|
||||
};
|
||||
// presentation attributes
|
||||
if(dojo.html.hasAttribute(cells[i], "align")){
|
||||
o.align=dojo.html.getAttribute(cells[i],"align");
|
||||
}
|
||||
if(dojo.html.hasAttribute(cells[i], "valign")){
|
||||
o.valign=dojo.html.getAttribute(cells[i],"valign");
|
||||
}
|
||||
|
||||
// sorting features.
|
||||
if(dojo.html.hasAttribute(cells[i], "nosort")){
|
||||
o.noSort=dojo.html.getAttribute(cells[i],"nosort")=="true";
|
||||
}
|
||||
if(dojo.html.hasAttribute(cells[i], "sortusing")){
|
||||
var trans=dojo.html.getAttribute(cells[i],"sortusing");
|
||||
var f=this.getTypeFromString(trans);
|
||||
if (f!=null && f!=window && typeof(f)=="function")
|
||||
o.sortFunction=f;
|
||||
}
|
||||
|
||||
if(dojo.html.hasAttribute(cells[i], "field")){
|
||||
o.field=dojo.html.getAttribute(cells[i],"field");
|
||||
}
|
||||
if(dojo.html.hasAttribute(cells[i], "format")){
|
||||
o.format=dojo.html.getAttribute(cells[i],"format");
|
||||
}
|
||||
if(dojo.html.hasAttribute(cells[i], "dataType")){
|
||||
var sortType=dojo.html.getAttribute(cells[i],"dataType");
|
||||
if(sortType.toLowerCase()=="html"||sortType.toLowerCase()=="markup"){
|
||||
o.sortType="__markup__"; // always convert to "__markup__"
|
||||
o.noSort=true;
|
||||
}else{
|
||||
var type=this.getTypeFromString(sortType);
|
||||
if(type){
|
||||
o.sortType=sortType;
|
||||
o.dataType=type;
|
||||
}
|
||||
}
|
||||
}
|
||||
o.label=dojo.html.renderedTextContent(cells[i]);
|
||||
this.columns.push(o);
|
||||
|
||||
// check to see if there's a default sort, and set the properties necessary
|
||||
if(dojo.html.hasAttribute(cells[i], "sort")){
|
||||
this.sortIndex=i;
|
||||
var dir=dojo.html.getAttribute(cells[i], "sort");
|
||||
if(!isNaN(parseInt(dir))){
|
||||
dir=parseInt(dir);
|
||||
this.sortDirection=(dir!=0)?1:0;
|
||||
}else{
|
||||
this.sortDirection=(dir.toLowerCase()=="desc")?1:0;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
parseData:function(/* array */ data){
|
||||
// summary
|
||||
// Parse the passed JSON data structure, and cast based on columns.
|
||||
this.data=[];
|
||||
this.selected=[];
|
||||
for(var i=0; i<data.length; i++){
|
||||
var o={}; // new data object.
|
||||
for(var j=0; j<this.columns.length; j++){
|
||||
var field=this.columns[j].getField();
|
||||
if(this.columns[j].sortType=="__markup__"){
|
||||
o[field]=String(data[i][field]);
|
||||
}else{
|
||||
var type=this.columns[j].getType();
|
||||
var val=data[i][field];
|
||||
var t=this.columns[j].sortType.toLowerCase();
|
||||
if(val){
|
||||
o[field]=new type(val);
|
||||
}else{
|
||||
o[field]=new type(); // let it use the default.
|
||||
}
|
||||
}
|
||||
}
|
||||
// check for the valueField if not already parsed.
|
||||
if(data[i][this.valueField]&&!o[this.valueField]){
|
||||
o[this.valueField]=data[i][this.valueField];
|
||||
}
|
||||
this.data.push(o);
|
||||
}
|
||||
},
|
||||
|
||||
parseDataFromTable:function(/* HTMLTableBodyElement */ tbody){
|
||||
// summary
|
||||
// parses the data in the tbody of a table to create a set of objects.
|
||||
// Will add objects to this.selected if an attribute 'selected="true"' is present on the row.
|
||||
this.data=[];
|
||||
this.selected=[];
|
||||
var rows=tbody.getElementsByTagName("tr");
|
||||
for(var i=0; i<rows.length; i++){
|
||||
if(dojo.html.getAttribute(rows[i],"ignoreIfParsed")=="true"){
|
||||
continue;
|
||||
}
|
||||
var o={}; // new data object.
|
||||
var cells=rows[i].getElementsByTagName("td");
|
||||
for(var j=0; j<this.columns.length; j++){
|
||||
var field=this.columns[j].getField();
|
||||
if(this.columns[j].sortType=="__markup__"){
|
||||
// FIXME: parse this?
|
||||
o[field]=cells[j].innerHTML;
|
||||
}else{
|
||||
var type=this.columns[j].getType();
|
||||
var val=dojo.html.renderedTextContent(cells[j]); // should be the same index as the column.
|
||||
if (val) o[field]=new type(val);
|
||||
else o[field]=new type(); // let it use the default.
|
||||
}
|
||||
}
|
||||
if(dojo.html.hasAttribute(rows[i],"value")&&!o[this.valueField]){
|
||||
o[this.valueField]=dojo.html.getAttribute(rows[i],"value");
|
||||
}
|
||||
// FIXME: add code to preserve row attributes in __metadata__ field?
|
||||
this.data.push(o);
|
||||
|
||||
// add it to the selections if selected="true" is present.
|
||||
if(dojo.html.getAttribute(rows[i],"selected")=="true"){
|
||||
this.selected.push(o);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
showSelections:function(){
|
||||
var body=this.domNode.getElementsByTagName("tbody")[0];
|
||||
var rows=body.getElementsByTagName("tr");
|
||||
var idx=0;
|
||||
for(var i=0; i<rows.length; i++){
|
||||
if(rows[i].parentNode==body){
|
||||
if(dojo.html.getAttribute(rows[i],"selected")=="true"){
|
||||
rows[i].className=this.rowSelectedClass;
|
||||
} else {
|
||||
if(this.enableAlternateRows&&idx%2==1){
|
||||
rows[i].className=this.rowAlternateClass;
|
||||
}else{
|
||||
rows[i].className="";
|
||||
}
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
},
|
||||
render:function(bDontPreserve){
|
||||
// summary
|
||||
// renders the table to the browser
|
||||
var data=[];
|
||||
var body=this.domNode.getElementsByTagName("tbody")[0];
|
||||
|
||||
if(!bDontPreserve){
|
||||
// rebuild data and selection
|
||||
this.parseDataFromTable(body);
|
||||
}
|
||||
|
||||
// clone this.data for sorting purposes.
|
||||
for(var i=0; i<this.data.length; i++){
|
||||
data.push(this.data[i]);
|
||||
}
|
||||
|
||||
var col=this.columns[this.sortIndex];
|
||||
if(!col.noSort){
|
||||
var field=col.getField();
|
||||
if(col.sortFunction){
|
||||
var sort=col.sortFunction;
|
||||
}else{
|
||||
var sort=function(a,b){
|
||||
if (a[field]>b[field]) return 1;
|
||||
if (a[field]<b[field]) return -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
data.sort(sort);
|
||||
if(this.sortDirection!=0) data.reverse();
|
||||
}
|
||||
|
||||
// build the table and pop it in.
|
||||
while(body.childNodes.length>0) body.removeChild(body.childNodes[0]);
|
||||
for(var i=0; i<data.length;i++){
|
||||
var row=document.createElement("tr");
|
||||
dojo.html.disableSelection(row);
|
||||
if (data[i][this.valueField]){
|
||||
row.setAttribute("value",data[i][this.valueField]);
|
||||
}
|
||||
if(this.isSelected(data[i])){
|
||||
row.className=this.rowSelectedClass;
|
||||
row.setAttribute("selected","true");
|
||||
} else {
|
||||
if(this.enableAlternateRows&&i%2==1){
|
||||
row.className=this.rowAlternateClass;
|
||||
}
|
||||
}
|
||||
for(var j=0;j<this.columns.length;j++){
|
||||
var cell=document.createElement("td");
|
||||
cell.setAttribute("align", this.columns[j].align);
|
||||
cell.setAttribute("valign", this.columns[j].valign);
|
||||
dojo.html.disableSelection(cell);
|
||||
if(this.sortIndex==j){
|
||||
cell.className=this.columnSelected;
|
||||
}
|
||||
if(this.columns[j].sortType=="__markup__"){
|
||||
cell.innerHTML=data[i][this.columns[j].getField()];
|
||||
for(var k=0; k<cell.childNodes.length; k++){
|
||||
var node=cell.childNodes[k];
|
||||
if(node&&node.nodeType==dojo.html.ELEMENT_NODE){
|
||||
dojo.html.disableSelection(node);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(this.columns[j].getType()==Date){
|
||||
var format=this.defaultDateFormat;
|
||||
if(this.columns[j].format) format=this.columns[j].format;
|
||||
cell.appendChild(document.createTextNode(dojo.date.format(data[i][this.columns[j].getField()], format)));
|
||||
}else{
|
||||
cell.appendChild(document.createTextNode(data[i][this.columns[j].getField()]));
|
||||
}
|
||||
}
|
||||
row.appendChild(cell);
|
||||
}
|
||||
body.appendChild(row);
|
||||
dojo.event.connect(row, "onclick", this, "onUISelect");
|
||||
}
|
||||
|
||||
// if minRows exist.
|
||||
var minRows=parseInt(this.minRows);
|
||||
if (!isNaN(minRows) && minRows>0 && data.length<minRows){
|
||||
var mod=0;
|
||||
if(data.length%2==0) mod=1;
|
||||
var nRows=minRows-data.length;
|
||||
for(var i=0; i<nRows; i++){
|
||||
var row=document.createElement("tr");
|
||||
row.setAttribute("ignoreIfParsed","true");
|
||||
if(this.enableAlternateRows&&i%2==mod){
|
||||
row.className=this.rowAlternateClass;
|
||||
}
|
||||
for(var j=0;j<this.columns.length;j++){
|
||||
var cell=document.createElement("td");
|
||||
cell.appendChild(document.createTextNode("\u00A0"));
|
||||
row.appendChild(cell);
|
||||
}
|
||||
body.appendChild(row);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// the following the user can override.
|
||||
onSelect:function(/* DomEvent */ e){
|
||||
// summary
|
||||
// empty function for the user to attach code to, fired by onUISelect
|
||||
},
|
||||
onUISelect:function(/* DomEvent */ e){
|
||||
// summary
|
||||
// fired when a user selects a row
|
||||
var row=dojo.html.getParentByType(e.target,"tr");
|
||||
var body=dojo.html.getParentByType(row,"tbody");
|
||||
if(this.enableMultipleSelect){
|
||||
if(e.metaKey||e.ctrlKey){
|
||||
if(this.isSelected(this.getObjectFromRow(row))){
|
||||
this.removeFromSelected(this.getObjectFromRow(row));
|
||||
row.removeAttribute("selected");
|
||||
}else{
|
||||
// push onto the selection stack.
|
||||
this.setSelectionByRow(row);
|
||||
row.setAttribute("selected","true");
|
||||
}
|
||||
}else if(e.shiftKey){
|
||||
// the tricky one. We need to figure out the *last* selected row above,
|
||||
// and select all the rows in between.
|
||||
var startRow;
|
||||
var rows=body.getElementsByTagName("tr");
|
||||
// if there's a selection above, we go with that first.
|
||||
for(var i=0;i<rows.length;i++){
|
||||
if(rows[i].parentNode==body){
|
||||
if(rows[i]==row) break;
|
||||
if(dojo.html.getAttribute(rows[i],"selected")=="true"){
|
||||
startRow=rows[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// if there isn't a selection above, we continue with a selection below.
|
||||
if(!startRow){
|
||||
startRow=row;
|
||||
for(;i<rows.length;i++){
|
||||
if(dojo.html.getAttribute(rows[i],"selected")=="true"){
|
||||
row=rows[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.resetSelections(body);
|
||||
if(startRow==row){
|
||||
// this is the only selection
|
||||
row.setAttribute("selected","true");
|
||||
this.setSelectionByRow(row);
|
||||
}else{
|
||||
var doSelect=false;
|
||||
for(var i=0; i<rows.length; i++){
|
||||
if(rows[i].parentNode==body){
|
||||
rows[i].removeAttribute("selected");
|
||||
if(rows[i]==startRow){
|
||||
doSelect=true;
|
||||
}
|
||||
if(doSelect){
|
||||
this.setSelectionByRow(rows[i]);
|
||||
rows[i].setAttribute("selected","true");
|
||||
}
|
||||
if(rows[i]==row){
|
||||
doSelect=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
// reset the selection
|
||||
this.resetSelections(body);
|
||||
row.setAttribute("selected","true");
|
||||
this.setSelectionByRow(row);
|
||||
}
|
||||
}else{
|
||||
// reset the data selection and go.
|
||||
this.resetSelections(body);
|
||||
row.setAttribute("selected","true");
|
||||
this.setSelectionByRow(row);
|
||||
}
|
||||
this.showSelections();
|
||||
this.onSelect(e);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
},
|
||||
onHeaderClick:function(/* DomEvent */ e){
|
||||
// summary
|
||||
// Main handler function for each header column click.
|
||||
var oldIndex=this.sortIndex;
|
||||
var oldDirection=this.sortDirection;
|
||||
var source=e.target;
|
||||
var row=dojo.html.getParentByType(source,"tr");
|
||||
var cellTag="td";
|
||||
if(row.getElementsByTagName(cellTag).length==0) cellTag="th";
|
||||
|
||||
var headers=row.getElementsByTagName(cellTag);
|
||||
var header=dojo.html.getParentByType(source,cellTag);
|
||||
|
||||
for(var i=0; i<headers.length; i++){
|
||||
if(headers[i]==header){
|
||||
if(i!=oldIndex){
|
||||
// new col.
|
||||
this.sortIndex=i;
|
||||
this.sortDirection=0;
|
||||
headers[i].className=this.headerSortDownClass
|
||||
}else{
|
||||
this.sortDirection=(oldDirection==0)?1:0;
|
||||
if(this.sortDirection==0){
|
||||
headers[i].className=this.headerSortDownClass;
|
||||
}else{
|
||||
headers[i].className=this.headerSortUpClass;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
// reset the header class.
|
||||
headers[i].className=this.headerClass;
|
||||
}
|
||||
}
|
||||
this.render();
|
||||
},
|
||||
|
||||
postCreate:function(){
|
||||
// summary
|
||||
// overridden from HtmlWidget, initializes and renders the widget.
|
||||
var thead=this.domNode.getElementsByTagName("thead")[0];
|
||||
if(this.headClass.length>0){
|
||||
thead.className=this.headClass;
|
||||
}
|
||||
|
||||
// disable selections
|
||||
dojo.html.disableSelection(this.domNode);
|
||||
|
||||
// parse the columns.
|
||||
this.parseColumns(thead);
|
||||
|
||||
// attach header handlers.
|
||||
var header="td";
|
||||
if(thead.getElementsByTagName(header).length==0) header="th";
|
||||
var headers=thead.getElementsByTagName(header);
|
||||
for(var i=0; i<headers.length; i++){
|
||||
if(!this.columns[i].noSort){
|
||||
dojo.event.connect(headers[i], "onclick", this, "onHeaderClick");
|
||||
}
|
||||
if(this.sortIndex==i){
|
||||
if(this.sortDirection==0){
|
||||
headers[i].className=this.headerSortDownClass;
|
||||
}else{
|
||||
headers[i].className=this.headerSortUpClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parse the tbody element and re-render it.
|
||||
var tbody=this.domNode.getElementsByTagName("tbody")[0];
|
||||
if (this.tbodyClass.length>0) {
|
||||
tbody.className=this.tbodyClass;
|
||||
}
|
||||
|
||||
this.parseDataFromTable(tbody);
|
||||
this.render(true);
|
||||
}
|
||||
});
|
383
webapp/web/src/widget/html/Spinner.js
Normal file
383
webapp/web/src/widget/html/Spinner.js
Normal file
|
@ -0,0 +1,383 @@
|
|||
/*
|
||||
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.Spinner");
|
||||
dojo.require("dojo.widget.Spinner");
|
||||
dojo.require("dojo.widget.Manager.*");
|
||||
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.html.Spinner = function(){
|
||||
dojo.widget.Spinner.call(this);
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.Spinner, dojo.widget.HtmlWidget);
|
||||
|
||||
// copied from superclass since we can't really over-ride via prototype
|
||||
dojo.lang.extend(dojo.widget.html.Spinner, dojo.widget.Spinner.defaults);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.Spinner, {
|
||||
|
||||
name: "", // clone in the name from the DOM node
|
||||
inputNode: null,
|
||||
upArrowNode: null,
|
||||
downArrowNode: null,
|
||||
absNode: null,
|
||||
relNode: null,
|
||||
innerRelNode: null,
|
||||
spacerNode: null,
|
||||
inputWidgetId: "",
|
||||
inputWidget: null,
|
||||
typamaticTimer: null,
|
||||
typamaticFunction: null,
|
||||
defaultTimeout: 500,
|
||||
currentTimeout: this.defaultTimeout,
|
||||
eventCount: 0,
|
||||
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlSpinner.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlSpinner.css"),
|
||||
|
||||
setValue: function(value){
|
||||
this.inputWidget.setValue(value);
|
||||
this.inputWidget.adjustValue(0);
|
||||
dojo.widget.html.stabile.setState(this.widgetId, this.getState(), true);
|
||||
},
|
||||
|
||||
getValue: function(){
|
||||
return this.inputWidget.getValue();
|
||||
},
|
||||
|
||||
getState: function(){
|
||||
return {value: this.getValue()};
|
||||
},
|
||||
|
||||
setState: function(state){
|
||||
this.setValue(state.value);
|
||||
},
|
||||
|
||||
// does the keyboard related stuff
|
||||
_handleKeyEvents: function(evt){
|
||||
var k = dojo.event.browser.keys;
|
||||
var keyCode = evt.keyCode;
|
||||
|
||||
switch(keyCode){
|
||||
case k.KEY_DOWN_ARROW:
|
||||
dojo.event.browser.stopEvent(evt);
|
||||
this.downArrowPressed(evt);
|
||||
return;
|
||||
case k.KEY_UP_ARROW:
|
||||
dojo.event.browser.stopEvent(evt);
|
||||
this.upArrowPressed(evt);
|
||||
return;
|
||||
}
|
||||
this.eventCount++;
|
||||
|
||||
},
|
||||
|
||||
onKeyDown: function(evt){
|
||||
// IE needs to stop keyDown others need to stop keyPress
|
||||
if(!document.createEvent){ // only IE
|
||||
this._handleKeyEvents(evt);
|
||||
}
|
||||
},
|
||||
|
||||
onKeyPress: function(evt){
|
||||
if(document.createEvent){ // never IE
|
||||
this._handleKeyEvents(evt);
|
||||
}
|
||||
},
|
||||
|
||||
fillInTemplate: function(args, frag){
|
||||
var source = this.getFragNodeRef(frag);
|
||||
dojo.html.copyStyle(this.domNode, source);
|
||||
},
|
||||
|
||||
|
||||
resizeUpArrow: function(){
|
||||
var newh = dojo.style.getContentBoxHeight(this.inputNode) >> 1;
|
||||
if(newh==0){
|
||||
// need more time to calculate size
|
||||
dojo.lang.setTimeout(this, "resizeUpArrow", 100);
|
||||
return;
|
||||
}
|
||||
var oldh = this.upArrowNode.height;
|
||||
if(oldh==0){
|
||||
// need more time to calculate size
|
||||
dojo.lang.setTimeout(this, "resizeUpArrow", 100);
|
||||
return;
|
||||
}
|
||||
var ratio = newh / oldh;
|
||||
this.upArrowNode.width=Math.floor(this.upArrowNode.width * ratio);
|
||||
this.upArrowNode.height=newh;
|
||||
},
|
||||
|
||||
resizeDownArrow: function(){
|
||||
var newh = dojo.style.getContentBoxHeight(this.inputNode) >> 1;
|
||||
if(newh==0){
|
||||
// need more time to calculate size
|
||||
dojo.lang.setTimeout(this, "resizeDownArrow", 100);
|
||||
return;
|
||||
}
|
||||
var oldh = this.downArrowNode.height;
|
||||
if(oldh==0){
|
||||
// need more time to calculate size
|
||||
dojo.lang.setTimeout(this, "resizeDownArrow", 100);
|
||||
return;
|
||||
}
|
||||
var ratio = newh / oldh;
|
||||
this.downArrowNode.width=Math.floor(this.downArrowNode.width * ratio);
|
||||
this.downArrowNode.height=newh;
|
||||
},
|
||||
|
||||
resizeSpacer: function(){
|
||||
var newh = dojo.style.getContentBoxHeight(this.inputNode) >> 1;
|
||||
if( newh==0 ){
|
||||
// need more time to calculate size
|
||||
dojo.lang.setTimeout(this, "resizeSpacer", 100);
|
||||
return;
|
||||
}
|
||||
var oldh = this.downArrowNode.height;
|
||||
if( oldh==0 ){
|
||||
// need more time to calculate size
|
||||
dojo.lang.setTimeout(this, "resizeSpacer", 100);
|
||||
return;
|
||||
}
|
||||
var ratio = newh / oldh;
|
||||
this.spacerNode.width=Math.floor(this.spacerNode.width * ratio);
|
||||
this.spacerNode.height=newh;
|
||||
},
|
||||
|
||||
_pressButton: function(node){
|
||||
with(node.style){
|
||||
borderRight = "0px";
|
||||
borderBottom = "0px";
|
||||
borderLeft = "1px solid black";
|
||||
borderTop = "1px solid black";
|
||||
}
|
||||
},
|
||||
|
||||
_releaseButton: function(node){
|
||||
with(node.style){
|
||||
borderLeft = "0px";
|
||||
borderTop = "0px";
|
||||
borderRight = "1px solid gray";
|
||||
borderBottom = "1px solid gray";
|
||||
}
|
||||
},
|
||||
|
||||
downArrowPressed: function(evt){
|
||||
if(typeof evt != "number"){
|
||||
if(this.typamaticTimer != null){
|
||||
if(this.typamaticFunction == this.downArrowPressed){
|
||||
return;
|
||||
}
|
||||
clearTimeout(this.typamaticTimer);
|
||||
}
|
||||
this._releaseButton(this.upArrowNode);
|
||||
this.eventCount++;
|
||||
this.typamaticTimer = null;
|
||||
this.currentTimeout = this.defaultTimeout;
|
||||
|
||||
}else if (evt != this.eventCount){
|
||||
this._releaseButton(this.downArrowNode);
|
||||
return;
|
||||
}
|
||||
this._pressButton(this.downArrowNode);
|
||||
this.setCursorX(this.inputWidget.adjustValue(-1,this.getCursorX()));
|
||||
this.typamaticFunction = this.downArrowPressed;
|
||||
this.typamaticTimer = setTimeout( dojo.lang.hitch(this,function(){this.downArrowPressed(this.eventCount);}), this.currentTimeout);
|
||||
this.currentTimeout = Math.round(this.currentTimeout * 90 / 100);
|
||||
},
|
||||
|
||||
upArrowPressed: function(evt){
|
||||
if(typeof evt != "number"){
|
||||
if(this.typamaticTimer != null){
|
||||
if(this.typamaticFunction == this.upArrowPressed){
|
||||
return;
|
||||
}
|
||||
clearTimeout(this.typamaticTimer);
|
||||
}
|
||||
this._releaseButton(this.downArrowNode);
|
||||
this.eventCount++;
|
||||
this.typamaticTimer = null;
|
||||
this.currentTimeout = this.defaultTimeout;
|
||||
}else if(evt != this.eventCount) {
|
||||
this._releaseButton(this.upArrowNode);
|
||||
return;
|
||||
}
|
||||
this._pressButton(this.upArrowNode);
|
||||
this.setCursorX(this.inputWidget.adjustValue(+1,this.getCursorX()));
|
||||
this.typamaticFunction = this.upArrowPressed;
|
||||
this.typamaticTimer = setTimeout( dojo.lang.hitch(this,function(){this.upArrowPressed(this.eventCount);}), this.currentTimeout);
|
||||
this.currentTimeout = Math.round(this.currentTimeout * 90 / 100);
|
||||
},
|
||||
|
||||
arrowReleased: function(evt){
|
||||
this.inputNode.focus();
|
||||
if(evt.keyCode && evt.keyCode != null){
|
||||
var keyCode = evt.keyCode;
|
||||
var k = dojo.event.browser.keys;
|
||||
|
||||
switch(keyCode){
|
||||
case k.KEY_DOWN_ARROW:
|
||||
case k.KEY_UP_ARROW:
|
||||
dojo.event.browser.stopEvent(evt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this._releaseButton(this.upArrowNode);
|
||||
this._releaseButton(this.downArrowNode);
|
||||
this.eventCount++;
|
||||
if(this.typamaticTimer != null){
|
||||
clearTimeout(this.typamaticTimer);
|
||||
}
|
||||
this.typamaticTimer = null;
|
||||
this.currentTimeout = this.defaultTimeout;
|
||||
},
|
||||
|
||||
mouseWheeled: function(evt) {
|
||||
var scrollAmount = 0;
|
||||
if(typeof evt.wheelDelta == 'number'){ // IE
|
||||
scrollAmount = evt.wheelDelta;
|
||||
}else if (typeof evt.detail == 'number'){ // Mozilla+Firefox
|
||||
scrollAmount = -evt.detail;
|
||||
}
|
||||
if(scrollAmount > 0){
|
||||
this.upArrowPressed(evt);
|
||||
this.arrowReleased(evt);
|
||||
}else if (scrollAmount < 0){
|
||||
this.downArrowPressed(evt);
|
||||
this.arrowReleased(evt);
|
||||
}
|
||||
},
|
||||
|
||||
getCursorX: function(){
|
||||
var x = -1;
|
||||
try{
|
||||
this.inputNode.focus();
|
||||
if (typeof this.inputNode.selectionEnd == "number"){
|
||||
x = this.inputNode.selectionEnd;
|
||||
}else if (document.selection && document.selection.createRange) {
|
||||
var range = document.selection.createRange().duplicate();
|
||||
if(range.parentElement() == this.inputNode){
|
||||
range.moveStart('textedit', -1);
|
||||
x = range.text.length;
|
||||
}
|
||||
}
|
||||
}catch(e){ /* squelch! */ }
|
||||
return x;
|
||||
},
|
||||
|
||||
setCursorX: function(x){
|
||||
try{
|
||||
this.inputNode.focus();
|
||||
if(!x){ x = 0 }
|
||||
if(typeof this.inputNode.selectionEnd == "number"){
|
||||
this.inputNode.selectionEnd = x;
|
||||
}else if(this.inputNode.createTextRange){
|
||||
var range = this.inputNode.createTextRange();
|
||||
range.collapse(true);
|
||||
range.moveEnd('character', x);
|
||||
range.moveStart('character', x);
|
||||
range.select();
|
||||
}
|
||||
}catch(e){ /* squelch! */ }
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
this.domNode.style.display="none";
|
||||
|
||||
if((typeof this.inputWidgetId != 'string')||(this.inputWidgetId.length == 0)){
|
||||
var w=dojo.widget.manager.getAllWidgets();
|
||||
for(var i=w.length-1; i>=0; i--){
|
||||
if(w[i].adjustValue){
|
||||
this.inputWidget = w[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
this.inputWidget = dojo.widget.getWidgetById(this.inputWidgetId);
|
||||
}
|
||||
|
||||
if(typeof this.inputWidget != 'object'){
|
||||
dojo.lang.setTimeout(this, "postCreate", 100);
|
||||
return;
|
||||
}
|
||||
var widgetNode = this.inputWidget.domNode;
|
||||
var inputNodes = widgetNode.getElementsByTagName('INPUT');
|
||||
this.inputNode = inputNodes[0];
|
||||
|
||||
/*
|
||||
// unlink existing dom nodes from domNode
|
||||
this.downArrowNode = dojo.dom.removeNode(this.downArrowNode);
|
||||
this.upArrowNode = dojo.dom.removeNode(this.upArrowNode);
|
||||
this.spacerNode = dojo.dom.removeNode(this.spacerNode);
|
||||
this.innerRelNode = dojo.dom.removeNode(this.innerRelNode);
|
||||
this.absNode = dojo.dom.removeNode(this.absNode);
|
||||
this.relNode = dojo.dom.removeNode(this.relNode);
|
||||
*/
|
||||
|
||||
// create a disconnected node
|
||||
this.innerRelNode.appendChild(this.upArrowNode);
|
||||
this.innerRelNode.appendChild(this.downArrowNode);
|
||||
this.absNode.appendChild(this.innerRelNode);
|
||||
this.relNode.appendChild(this.absNode);
|
||||
this.relNode.appendChild(this.spacerNode);
|
||||
|
||||
dojo.event.connect(this.inputNode, "onkeypress", this, "onKeyPress");
|
||||
dojo.event.connect(this.inputNode, "onkeydown", this, "onKeyDown");
|
||||
dojo.event.connect(this.inputNode, "onkeyup", this, "arrowReleased");
|
||||
dojo.event.connect(this.downArrowNode, "onmousedown", this, "downArrowPressed");
|
||||
dojo.event.connect(this.downArrowNode, "onmouseup", this, "arrowReleased");
|
||||
dojo.event.connect(this.upArrowNode, "onmousedown", this, "upArrowPressed");
|
||||
dojo.event.connect(this.upArrowNode, "onmouseup", this, "arrowReleased");
|
||||
if(this.inputNode.addEventListener){
|
||||
// FIXME: why not use dojo.event.connect() to DOMMouseScroll here?
|
||||
this.inputNode.addEventListener('DOMMouseScroll', dojo.lang.hitch(this, "mouseWheeled"), false); // Mozilla + Firefox + Netscape
|
||||
}else{
|
||||
dojo.event.connect(this.inputNode, "onmousewheel", this, "mouseWheeled"); // IE + Safari
|
||||
}
|
||||
|
||||
this.resizeDownArrow();
|
||||
this.resizeUpArrow();
|
||||
this.resizeSpacer();
|
||||
|
||||
// make sure the disconnected node will fit right next to the INPUT tag w/o any interference
|
||||
dojo.html.copyStyle(this.relNode, this.inputNode);
|
||||
with(this.relNode.style){
|
||||
display = "inline";
|
||||
position = "relative";
|
||||
backgroundColor = "";
|
||||
marginLeft = "-1px";
|
||||
paddingLeft = "0";
|
||||
}
|
||||
this.inputNode.style.marginRight = "0px";
|
||||
this.inputNode.style.paddingRight = "0px";
|
||||
|
||||
// add the disconnected node right after the INPUT tag
|
||||
dojo.dom.insertAfter(this.relNode, this.inputNode, false);
|
||||
this.domNode = dojo.dom.removeNode(this.domNode);
|
||||
// realign the spinner vertically in case there's a slight difference
|
||||
var absOffset = dojo.html.getAbsoluteY(this.relNode,true)-dojo.html.getAbsoluteY(this.absNode,true);
|
||||
this.absNode.style.top = absOffset-dojo.style.getBorderExtent(this.inputNode, "top")+"px";
|
||||
|
||||
var s = dojo.widget.html.stabile.getState(this.widgetId);
|
||||
this.setValue(this.getValue());
|
||||
if(s){
|
||||
this.setState(s);
|
||||
}
|
||||
}
|
||||
});
|
85
webapp/web/src/widget/html/TaskBar.js
Normal file
85
webapp/web/src/widget/html/TaskBar.js
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
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.TaskBar");
|
||||
dojo.provide("dojo.widget.html.TaskBarItem");
|
||||
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.FloatingPane");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.event");
|
||||
|
||||
// Icon associated w/a floating pane
|
||||
dojo.widget.html.TaskBarItem = function(){
|
||||
dojo.widget.TaskBarItem.call(this);
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.TaskBarItem, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.TaskBarItem, {
|
||||
// constructor arguments
|
||||
iconSrc: '',
|
||||
caption: 'Untitled',
|
||||
window: null,
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlTaskBarItemTemplate.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlTaskBar.css"),
|
||||
|
||||
fillInTemplate: function() {
|
||||
if ( this.iconSrc != '' ) {
|
||||
var img = document.createElement("img");
|
||||
img.src = this.iconSrc;
|
||||
this.domNode.appendChild(img);
|
||||
}
|
||||
this.domNode.appendChild(document.createTextNode(this.caption));
|
||||
dojo.html.disableSelection(this.domNode);
|
||||
},
|
||||
|
||||
postCreate: function() {
|
||||
this.window=dojo.widget.getWidgetById(this.windowId);
|
||||
this.window.explodeSrc = this.domNode;
|
||||
dojo.event.connect(this.window, "destroy", this, "destroy")
|
||||
},
|
||||
|
||||
onClick: function() {
|
||||
this.window.show();
|
||||
}
|
||||
});
|
||||
|
||||
// Collection of widgets in a bar, like Windows task bar
|
||||
dojo.widget.html.TaskBar = function(){
|
||||
|
||||
dojo.widget.html.FloatingPane.call(this);
|
||||
dojo.widget.TaskBar.call(this);
|
||||
this._addChildStack = [];
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.TaskBar, dojo.widget.html.FloatingPane);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.TaskBar, {
|
||||
|
||||
resizable: false,
|
||||
titleBarDisplay: "none",
|
||||
|
||||
addChild: function(child) {
|
||||
if(!this.containerNode){
|
||||
this._addChildStack.push(child);
|
||||
}else if(this._addChildStack.length > 0){
|
||||
var oarr = this._addChildStack;
|
||||
this._addChildStack = [];
|
||||
dojo.lang.forEach(oarr, this.addChild, this);
|
||||
}
|
||||
var tbi = dojo.widget.createWidget("TaskBarItem",
|
||||
{ windowId: child.widgetId,
|
||||
caption: child.title,
|
||||
iconSrc: child.iconSrc
|
||||
});
|
||||
dojo.widget.html.TaskBar.superclass.addChild.call(this,tbi);
|
||||
}
|
||||
});
|
249
webapp/web/src/widget/html/TimePicker.js
Normal file
249
webapp/web/src/widget/html/TimePicker.js
Normal file
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
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.TimePicker");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.widget.TimePicker");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.date");
|
||||
dojo.require("dojo.html");
|
||||
|
||||
dojo.widget.html.TimePicker = function(){
|
||||
dojo.widget.TimePicker.call(this);
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
|
||||
|
||||
var _this = this;
|
||||
// selected time, JS Date object
|
||||
this.time = "";
|
||||
// set following flag to true if a default time should be set
|
||||
this.useDefaultTime = false;
|
||||
// set the following to true to set default minutes to current time, false to // use zero
|
||||
this.useDefaultMinutes = false;
|
||||
// rfc 3339 date
|
||||
this.storedTime = "";
|
||||
// time currently selected in the UI, stored in hours, minutes, seconds in the format that will be actually displayed
|
||||
this.currentTime = {};
|
||||
this.classNames = {
|
||||
selectedTime: "selectedItem"
|
||||
}
|
||||
this.any = "any"
|
||||
// dom node indecies for selected hour, minute, amPm, and "any time option"
|
||||
this.selectedTime = {
|
||||
hour: "",
|
||||
minute: "",
|
||||
amPm: "",
|
||||
anyTime: false
|
||||
}
|
||||
|
||||
// minutes are ordered as follows: ["12", "6", "1", "7", "2", "8", "3", "9", "4", "10", "5", "11"]
|
||||
this.hourIndexMap = ["", 2, 4, 6, 8, 10, 1, 3, 5, 7, 9, 11, 0];
|
||||
// minutes are ordered as follows: ["00", "30", "05", "35", "10", "40", "15", "45", "20", "50", "25", "55"]
|
||||
this.minuteIndexMap = [0, 2, 4, 6, 8, 10, 1, 3, 5, 7, 9, 11];
|
||||
|
||||
this.templatePath = dojo.uri.dojoUri("src/widget/templates/HtmlTimePicker.html");
|
||||
this.templateCssPath = dojo.uri.dojoUri("src/widget/templates/HtmlTimePicker.css");
|
||||
|
||||
this.fillInTemplate = function(){
|
||||
this.initData();
|
||||
this.initUI();
|
||||
}
|
||||
|
||||
this.initData = function() {
|
||||
// FIXME: doesn't currently validate the time before trying to set it
|
||||
// Determine the date/time from stored info, or by default don't
|
||||
// have a set time
|
||||
// FIXME: should normalize against whitespace on storedTime... for now
|
||||
// just a lame hack
|
||||
if(this.storedTime.indexOf("T")!=-1 && this.storedTime.split("T")[1] && this.storedTime!=" " && this.storedTime.split("T")[1]!="any") {
|
||||
this.time = dojo.widget.TimePicker.util.fromRfcDateTime(this.storedTime, this.useDefaultMinutes, this.selectedTime.anyTime);
|
||||
} else if (this.useDefaultTime) {
|
||||
this.time = dojo.widget.TimePicker.util.fromRfcDateTime("", this.useDefaultMinutes, this.selectedTime.anyTime);
|
||||
} else {
|
||||
this.selectedTime.anyTime = true;
|
||||
this.time = dojo.widget.TimePicker.util.fromRfcDateTime("", 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
this.initUI = function() {
|
||||
// set UI to match the currently selected time
|
||||
if(!this.selectedTime.anyTime && this.time) {
|
||||
var amPmHour = dojo.widget.TimePicker.util.toAmPmHour(this.time.getHours());
|
||||
var hour = amPmHour[0];
|
||||
var isAm = amPmHour[1];
|
||||
var minute = this.time.getMinutes();
|
||||
var minuteIndex = parseInt(minute/5);
|
||||
this.onSetSelectedHour(this.hourIndexMap[hour]);
|
||||
this.onSetSelectedMinute(this.minuteIndexMap[minuteIndex]);
|
||||
this.onSetSelectedAmPm(isAm);
|
||||
} else {
|
||||
this.onSetSelectedAnyTime();
|
||||
}
|
||||
}
|
||||
|
||||
this.setDateTime = function(rfcDate) {
|
||||
this.storedTime = rfcDate;
|
||||
}
|
||||
|
||||
this.onClearSelectedHour = function(evt) {
|
||||
this.clearSelectedHour();
|
||||
}
|
||||
|
||||
this.onClearSelectedMinute = function(evt) {
|
||||
this.clearSelectedMinute();
|
||||
}
|
||||
|
||||
this.onClearSelectedAmPm = function(evt) {
|
||||
this.clearSelectedAmPm();
|
||||
}
|
||||
|
||||
this.onClearSelectedAnyTime = function(evt) {
|
||||
this.clearSelectedAnyTime();
|
||||
if(this.selectedTime.anyTime) {
|
||||
this.selectedTime.anyTime = false;
|
||||
this.time = dojo.widget.TimePicker.util.fromRfcDateTime("", this.useDefaultMinutes);
|
||||
this.initUI();
|
||||
}
|
||||
}
|
||||
|
||||
this.clearSelectedHour = function() {
|
||||
var hourNodes = this.hourContainerNode.getElementsByTagName("td");
|
||||
for (var i=0; i<hourNodes.length; i++) {
|
||||
dojo.html.setClass(hourNodes.item(i), "");
|
||||
}
|
||||
}
|
||||
|
||||
this.clearSelectedMinute = function() {
|
||||
var minuteNodes = this.minuteContainerNode.getElementsByTagName("td");
|
||||
for (var i=0; i<minuteNodes.length; i++) {
|
||||
dojo.html.setClass(minuteNodes.item(i), "");
|
||||
}
|
||||
}
|
||||
|
||||
this.clearSelectedAmPm = function() {
|
||||
var amPmNodes = this.amPmContainerNode.getElementsByTagName("td");
|
||||
for (var i=0; i<amPmNodes.length; i++) {
|
||||
dojo.html.setClass(amPmNodes.item(i), "");
|
||||
}
|
||||
}
|
||||
|
||||
this.clearSelectedAnyTime = function() {
|
||||
dojo.html.setClass(this.anyTimeContainerNode, "anyTimeContainer");
|
||||
}
|
||||
|
||||
this.onSetSelectedHour = function(evt) {
|
||||
this.onClearSelectedAnyTime();
|
||||
this.onClearSelectedHour();
|
||||
this.setSelectedHour(evt);
|
||||
this.onSetTime();
|
||||
}
|
||||
|
||||
this.setSelectedHour = function(evt) {
|
||||
if(evt && evt.target) {
|
||||
dojo.html.setClass(evt.target, this.classNames.selectedTime);
|
||||
this.selectedTime["hour"] = evt.target.innerHTML;
|
||||
} else if (!isNaN(evt)) {
|
||||
var hourNodes = this.hourContainerNode.getElementsByTagName("td");
|
||||
if(hourNodes.item(evt)) {
|
||||
dojo.html.setClass(hourNodes.item(evt), this.classNames.selectedTime);
|
||||
this.selectedTime["hour"] = hourNodes.item(evt).innerHTML;
|
||||
}
|
||||
}
|
||||
this.selectedTime.anyTime = false;
|
||||
}
|
||||
|
||||
this.onSetSelectedMinute = function(evt) {
|
||||
this.onClearSelectedAnyTime();
|
||||
this.onClearSelectedMinute();
|
||||
this.setSelectedMinute(evt);
|
||||
this.selectedTime.anyTime = false;
|
||||
this.onSetTime();
|
||||
}
|
||||
|
||||
this.setSelectedMinute = function(evt) {
|
||||
if(evt && evt.target) {
|
||||
dojo.html.setClass(evt.target, this.classNames.selectedTime);
|
||||
this.selectedTime["minute"] = evt.target.innerHTML;
|
||||
} else if (!isNaN(evt)) {
|
||||
var minuteNodes = this.minuteContainerNode.getElementsByTagName("td");
|
||||
if(minuteNodes.item(evt)) {
|
||||
dojo.html.setClass(minuteNodes.item(evt), this.classNames.selectedTime);
|
||||
this.selectedTime["minute"] = minuteNodes.item(evt).innerHTML;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.onSetSelectedAmPm = function(evt) {
|
||||
this.onClearSelectedAnyTime();
|
||||
this.onClearSelectedAmPm();
|
||||
this.setSelectedAmPm(evt);
|
||||
this.selectedTime.anyTime = false;
|
||||
this.onSetTime();
|
||||
}
|
||||
|
||||
this.setSelectedAmPm = function(evt) {
|
||||
if(evt && evt.target) {
|
||||
dojo.html.setClass(evt.target, this.classNames.selectedTime);
|
||||
this.selectedTime["amPm"] = evt.target.innerHTML;
|
||||
} else {
|
||||
evt = evt ? 0 : 1;
|
||||
var amPmNodes = this.amPmContainerNode.getElementsByTagName("td");
|
||||
if(amPmNodes.item(evt)) {
|
||||
dojo.html.setClass(amPmNodes.item(evt), this.classNames.selectedTime);
|
||||
this.selectedTime["amPm"] = amPmNodes.item(evt).innerHTML;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.onSetSelectedAnyTime = function(evt) {
|
||||
this.onClearSelectedHour();
|
||||
this.onClearSelectedMinute();
|
||||
this.onClearSelectedAmPm();
|
||||
this.setSelectedAnyTime();
|
||||
this.onSetTime();
|
||||
}
|
||||
|
||||
this.setSelectedAnyTime = function(evt) {
|
||||
this.selectedTime.anyTime = true;
|
||||
dojo.html.setClass(this.anyTimeContainerNode, this.classNames.selectedTime + " " + "anyTimeContainer");
|
||||
}
|
||||
|
||||
this.onClick = function(evt) {
|
||||
dojo.event.browser.stopEvent(evt)
|
||||
}
|
||||
|
||||
this.onSetTime = function() {
|
||||
if(this.selectedTime.anyTime) {
|
||||
this.time = new Date();
|
||||
var tempDateTime = dojo.widget.TimePicker.util.toRfcDateTime(this.time);
|
||||
this.setDateTime(tempDateTime.split("T")[0]);
|
||||
} else {
|
||||
var hour = 12;
|
||||
var minute = 0;
|
||||
var isAm = false;
|
||||
if(this.selectedTime["hour"]) {
|
||||
hour = parseInt(this.selectedTime["hour"], 10);
|
||||
}
|
||||
if(this.selectedTime["minute"]) {
|
||||
minute = parseInt(this.selectedTime["minute"], 10);
|
||||
}
|
||||
if(this.selectedTime["amPm"]) {
|
||||
isAm = (this.selectedTime["amPm"].toLowerCase() == "am");
|
||||
}
|
||||
this.time = new Date();
|
||||
this.time.setHours(dojo.widget.TimePicker.util.fromAmPmHour(hour, isAm));
|
||||
this.time.setMinutes(minute);
|
||||
this.setDateTime(dojo.widget.TimePicker.util.toRfcDateTime(this.time));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
dojo.inherits(dojo.widget.html.TimePicker, dojo.widget.HtmlWidget);
|
70
webapp/web/src/widget/html/TitlePane.js
Normal file
70
webapp/web/src/widget/html/TitlePane.js
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.TitlePane");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.lfx.*");
|
||||
|
||||
dojo.widget.html.TitlePane = function(){
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
this.widgetType = "TitlePane";
|
||||
|
||||
this.labelNode="";
|
||||
this.labelNodeClass="";
|
||||
this.containerNodeClass="";
|
||||
this.label="";
|
||||
|
||||
this.open=true;
|
||||
this.templatePath = dojo.uri.dojoUri("src/widget/templates/TitlePane.html");
|
||||
}
|
||||
|
||||
dojo.inherits(dojo.widget.html.TitlePane, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.TitlePane, {
|
||||
isContainer: true,
|
||||
postCreate: function() {
|
||||
if (this.label) {
|
||||
this.labelNode.appendChild(document.createTextNode(this.label));
|
||||
}
|
||||
|
||||
if (this.labelNodeClass) {
|
||||
dojo.html.addClass(this.labelNode, this.labelNodeClass);
|
||||
}
|
||||
|
||||
if (this.containerNodeClass) {
|
||||
dojo.html.addClass(this.containerNode, this.containerNodeClass);
|
||||
}
|
||||
|
||||
if (!this.open) {
|
||||
dojo.lfx.wipeOut(this.containerNode,0).play();
|
||||
}
|
||||
},
|
||||
|
||||
onLabelClick: function() {
|
||||
if (this.open) {
|
||||
dojo.lfx.wipeOut(this.containerNode,250).play();
|
||||
this.open=false;
|
||||
}else {
|
||||
dojo.lfx.wipeIn(this.containerNode,250).play();
|
||||
this.open=true;
|
||||
}
|
||||
},
|
||||
|
||||
setContent: function(content) {
|
||||
this.containerNode.innerHTML=content;
|
||||
},
|
||||
|
||||
setLabel: function(label) {
|
||||
this.labelNode.innerHTML=label;
|
||||
}
|
||||
});
|
||||
|
||||
dojo.widget.tags.addParseTreeHandler("dojo:TitlePane");
|
183
webapp/web/src/widget/html/Tooltip.js
Normal file
183
webapp/web/src/widget/html/Tooltip.js
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.html.Tooltip");
|
||||
dojo.require("dojo.widget.html.ContentPane");
|
||||
dojo.require("dojo.widget.Tooltip");
|
||||
dojo.require("dojo.uri");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.event");
|
||||
dojo.require("dojo.style");
|
||||
dojo.require("dojo.html");
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.html.Tooltip",
|
||||
dojo.widget.html.ContentPane,
|
||||
{
|
||||
widgetType: "Tooltip",
|
||||
isContainer: true,
|
||||
|
||||
// Constructor arguments
|
||||
caption: "",
|
||||
showDelay: 500,
|
||||
hideDelay: 100,
|
||||
connectId: "",
|
||||
|
||||
templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlTooltipTemplate.html"),
|
||||
templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlTooltipTemplate.css"),
|
||||
|
||||
connectNode: null,
|
||||
|
||||
// Tooltip has the following possible states:
|
||||
// erased - nothing on screen
|
||||
// displaying - currently being faded in (partially displayed)
|
||||
// displayed - fully displayed
|
||||
// erasing - currently being faded out (partially erased)
|
||||
state: "erased",
|
||||
|
||||
fillInTemplate: function(args, frag){
|
||||
if(this.caption != ""){
|
||||
this.domNode.appendChild(document.createTextNode(this.caption));
|
||||
}
|
||||
this.connectNode = dojo.byId(this.connectId);
|
||||
dojo.widget.html.Tooltip.superclass.fillInTemplate.call(this, args, frag);
|
||||
},
|
||||
|
||||
postCreate: function(args, frag){
|
||||
// The domnode was appended to my parent widget's domnode, but the positioning
|
||||
// only works if the domnode is a child of document.body
|
||||
document.body.appendChild(this.domNode);
|
||||
|
||||
dojo.event.connect(this.connectNode, "onmouseover", this, "onMouseOver");
|
||||
dojo.widget.html.Tooltip.superclass.postCreate.call(this, args, frag);
|
||||
},
|
||||
|
||||
onMouseOver: function(e) {
|
||||
this.mouse = {x: e.pageX, y: e.pageY};
|
||||
|
||||
if(!this.showTimer){
|
||||
this.showTimer = setTimeout(dojo.lang.hitch(this, "show"), this.showDelay);
|
||||
dojo.event.connect(document.documentElement, "onmousemove", this, "onMouseMove");
|
||||
}
|
||||
},
|
||||
|
||||
onMouseMove: function(e) {
|
||||
this.mouse = {x: e.pageX, y: e.pageY};
|
||||
|
||||
if(dojo.html.overElement(this.connectNode, e) || dojo.html.overElement(this.domNode, e)) {
|
||||
// If the tooltip has been scheduled to be erased, cancel that timer
|
||||
// since we are hovering over element/tooltip again
|
||||
if(this.hideTimer) {
|
||||
clearTimeout(this.hideTimer);
|
||||
delete this.hideTimer;
|
||||
}
|
||||
} else {
|
||||
// mouse has been moved off the element/tooltip
|
||||
// note: can't use onMouseOut to detect this because the "explode" effect causes
|
||||
// spurious onMouseOut/onMouseOver events (due to interference from outline)
|
||||
if(this.showTimer){
|
||||
clearTimeout(this.showTimer);
|
||||
delete this.showTimer;
|
||||
}
|
||||
if((this.state=="displaying"||this.state=="displayed") && !this.hideTimer){
|
||||
this.hideTimer = setTimeout(dojo.lang.hitch(this, "hide"), this.hideDelay);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
show: function() {
|
||||
if(this.state=="erasing"){
|
||||
// we are in the process of erasing; when that is finished, display it.
|
||||
this.displayScheduled=true;
|
||||
return;
|
||||
}
|
||||
if ( this.state=="displaying" || this.state=="displayed" ) { return; }
|
||||
|
||||
// prevent IE bleed through (iframe creation is deferred until first show()
|
||||
// call because apparently it takes a long time)
|
||||
if(!this.bgIframe){
|
||||
this.bgIframe = new dojo.html.BackgroundIframe(this.domNode);
|
||||
}
|
||||
|
||||
this.position();
|
||||
|
||||
// if rendering using explosion effect, need to set explosion source
|
||||
this.explodeSrc = [this.mouse.x, this.mouse.y];
|
||||
|
||||
this.state="displaying";
|
||||
|
||||
dojo.widget.html.Tooltip.superclass.show.call(this);
|
||||
},
|
||||
|
||||
onShow: function() {
|
||||
dojo.widget.html.Tooltip.superclass.onShow.call(this);
|
||||
|
||||
this.state="displayed";
|
||||
|
||||
// in the corner case where the user has moved his mouse away
|
||||
// while the tip was fading in
|
||||
if(this.eraseScheduled){
|
||||
this.hide();
|
||||
this.eraseScheduled=false;
|
||||
}
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
if(this.state=="displaying"){
|
||||
// in the process of fading in. wait until that is finished and then fade out
|
||||
this.eraseScheduled=true;
|
||||
return;
|
||||
}
|
||||
if ( this.state=="displayed" ) {
|
||||
this.state="erasing";
|
||||
if ( this.showTimer ) {
|
||||
clearTimeout(this.showTimer);
|
||||
delete this.showTimer;
|
||||
}
|
||||
if ( this.hideTimer ) {
|
||||
clearTimeout(this.hideTimer);
|
||||
delete this.hideTimer;
|
||||
}
|
||||
dojo.event.disconnect(document.documentElement, "onmousemove", this, "onMouseMove");
|
||||
dojo.widget.html.Tooltip.superclass.hide.call(this);
|
||||
}
|
||||
},
|
||||
|
||||
onHide: function(){
|
||||
this.state="erased";
|
||||
|
||||
// in the corner case where the user has moved his mouse back
|
||||
// while the tip was fading out
|
||||
if(this.displayScheduled){
|
||||
this.display();
|
||||
this.displayScheduled=false;
|
||||
}
|
||||
},
|
||||
|
||||
position: function(){
|
||||
dojo.html.placeOnScreenPoint(this.domNode, this.mouse.x, this.mouse.y, [10,15], true);
|
||||
this.bgIframe.onResized();
|
||||
},
|
||||
|
||||
onLoad: function(){
|
||||
if(this.isShowing()){
|
||||
// the tooltip has changed size due to downloaded contents, so reposition it
|
||||
dojo.lang.setTimeout(this, this.position, 50);
|
||||
dojo.widget.html.Tooltip.superclass.onLoad.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
);
|
180
webapp/web/src/widget/html/YahooMap.js
Normal file
180
webapp/web/src/widget/html/YahooMap.js
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
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.YahooMap");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.html");
|
||||
dojo.require("dojo.math");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
dojo.require("dojo.widget.YahooMap");
|
||||
|
||||
(function(){
|
||||
var yappid = djConfig["yAppId"]||djConfig["yahooAppId"]||"dojotoolkit";
|
||||
if(!dojo.hostenv.post_load_){
|
||||
if(yappid == "dojotoolkit"){
|
||||
dojo.debug("please provide a unique Yahoo App ID in djConfig.yahooAppId when using the map widget");
|
||||
}
|
||||
var tag = "<scr"+"ipt src='http://api.maps.yahoo.com/ajaxymap?v=3.0&appid="+yappid+"'></scri"+"pt>";
|
||||
if(!dj_global["YMap"]){
|
||||
document.write(tag);
|
||||
}
|
||||
}else{
|
||||
dojo.debug("cannot initialize map system after the page has been loaded! Please either manually include the script block provided by Yahoo in your page or require() the YahooMap widget before onload has fired");
|
||||
}
|
||||
})();
|
||||
|
||||
dojo.widget.html.YahooMap=function(){
|
||||
dojo.widget.HtmlWidget.call(this);
|
||||
dojo.widget.YahooMap.call(this);
|
||||
|
||||
this.map=null;
|
||||
this.datasrc="";
|
||||
this.data=[];
|
||||
this.width=0;
|
||||
this.height=0;
|
||||
this.controls=["zoomlong","maptype","pan"];
|
||||
};
|
||||
dojo.inherits(dojo.widget.html.YahooMap, dojo.widget.HtmlWidget);
|
||||
|
||||
dojo.lang.extend(dojo.widget.html.YahooMap, {
|
||||
widgetType: "YahooMap",
|
||||
templatePath:null,
|
||||
templateCssPath:null,
|
||||
|
||||
findCenter:function(aPts){
|
||||
var start=new YGeoPoint(37,-90);
|
||||
if(aPts.length==0) return start;
|
||||
var minLat,maxLat, minLon, maxLon, cLat, cLon;
|
||||
minLat=maxLat=aPts[0].Lat;
|
||||
minLon=maxLon=aPts[0].Lon;
|
||||
for(var i=0; i<aPts.length; i++){
|
||||
minLat=Math.min(minLat,aPts[i].Lat);
|
||||
maxLat=Math.max(maxLat,aPts[i].Lat);
|
||||
minLon=Math.min(minLon,aPts[i].Lon);
|
||||
maxLon=Math.max(maxLon,aPts[i].Lon);
|
||||
}
|
||||
cLat=dojo.math.round((minLat+maxLat)/2,6);
|
||||
cLon=dojo.math.round((minLon+maxLon)/2,6);
|
||||
return new YGeoPoint(cLat,cLon);
|
||||
},
|
||||
setControls:function(){
|
||||
var c=this.controls;
|
||||
var t=dojo.widget.YahooMap.Controls;
|
||||
for(var i=0; i<c.length; i++){
|
||||
switch(c[i]){
|
||||
case t.MapType:{
|
||||
this.map.addTypeControl();
|
||||
break;
|
||||
}
|
||||
case t.Pan:{
|
||||
this.map.addPanControl();
|
||||
break;
|
||||
}
|
||||
case t.ZoomLong:{
|
||||
this.map.addZoomLong();
|
||||
break;
|
||||
}
|
||||
case t.ZoomShort:{
|
||||
this.map.addZoomShort();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
parse:function(table){
|
||||
this.data=[];
|
||||
|
||||
// get the column indices
|
||||
var h=table.getElementsByTagName("thead")[0];
|
||||
if(!h){
|
||||
return;
|
||||
}
|
||||
|
||||
var a=[];
|
||||
var cols=h.getElementsByTagName("td");
|
||||
if(cols.length==0){
|
||||
cols=h.getElementsByTagName("th");
|
||||
}
|
||||
for(var i=0; i<cols.length; i++){
|
||||
var c=cols[i].innerHTML.toLowerCase();
|
||||
if(c=="long") c="lng";
|
||||
a.push(c);
|
||||
}
|
||||
|
||||
// parse the data
|
||||
var b=table.getElementsByTagName("tbody")[0];
|
||||
if(!b){
|
||||
return;
|
||||
}
|
||||
for(var i=0; i<b.childNodes.length; i++){
|
||||
if(!(b.childNodes[i].nodeName&&b.childNodes[i].nodeName.toLowerCase()=="tr")){
|
||||
continue;
|
||||
}
|
||||
var cells=b.childNodes[i].getElementsByTagName("td");
|
||||
var o={};
|
||||
for(var j=0; j<a.length; j++){
|
||||
var col=a[j];
|
||||
if(col=="lat"||col=="lng"){
|
||||
o[col]=parseFloat(cells[j].innerHTML);
|
||||
}else{
|
||||
o[col]=cells[j].innerHTML;
|
||||
}
|
||||
}
|
||||
this.data.push(o);
|
||||
}
|
||||
},
|
||||
render:function(){
|
||||
var pts=[];
|
||||
var d=this.data;
|
||||
for(var i=0; i<d.length; i++){
|
||||
var pt=new YGeoPoint(d[i].lat, d[i].lng);
|
||||
pts.push(pt);
|
||||
var icon=d[i].icon||null;
|
||||
if(icon){
|
||||
icon=new YImage(icon);
|
||||
}
|
||||
var m=new YMarker(pt,icon);
|
||||
if(d[i].description){
|
||||
m.addAutoExpand("<div>"+d[i].description+"</div>");
|
||||
}
|
||||
this.map.addOverlay(m);
|
||||
}
|
||||
var c=this.findCenter(pts);
|
||||
var z=this.map.getZoomLevel(pts);
|
||||
this.map.drawZoomAndCenter(c,z);
|
||||
},
|
||||
|
||||
initialize:function(args, frag){
|
||||
if(!YMap || !YGeoPoint){
|
||||
dojo.raise("dojo.widget.YahooMap: The Yahoo Map script must be included in order to use this widget.");
|
||||
}
|
||||
if(this.datasrc){
|
||||
this.parse(dojo.byId(this.datasrc));
|
||||
}
|
||||
else if(this.domNode.getElementsByTagName("table")[0]){
|
||||
this.parse(this.domNode.getElementsByTagName("table")[0]);
|
||||
}
|
||||
},
|
||||
postCreate:function(){
|
||||
// clean the domNode before creating the map.
|
||||
while(this.domNode.childNodes.length>0){
|
||||
this.domNode.removeChild(this.domNode.childNodes[0]);
|
||||
}
|
||||
|
||||
if(this.width>0&&this.height>0){
|
||||
this.map=new YMap(this.domNode, YAHOO_MAP_REG, new YSize(this.width, this.height));
|
||||
}else{
|
||||
this.map=new YMap(this.domNode);
|
||||
}
|
||||
this.setControls();
|
||||
this.render();
|
||||
}
|
||||
});
|
213
webapp/web/src/widget/html/stabile.js
Normal file
213
webapp/web/src/widget/html/stabile.js
Normal file
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
// Maintain state of widgets when user hits back/forward button
|
||||
|
||||
dojo.provide("dojo.widget.html.stabile");
|
||||
|
||||
dojo.widget.html.stabile = {
|
||||
// Characters to quote in single-quoted regexprs
|
||||
_sqQuotables: new RegExp("([\\\\'])", "g"),
|
||||
|
||||
// Current depth.
|
||||
_depth: 0,
|
||||
|
||||
// Set to true when calling v.toString, to sniff for infinite
|
||||
// recursion.
|
||||
_recur: false,
|
||||
|
||||
// Levels of nesting of Array and object displays.
|
||||
// If when >= depth, no display or array or object internals.
|
||||
depthLimit: 2
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//// PUBLIC METHODS
|
||||
|
||||
// Get the state stored for the widget with the given ID, or undefined
|
||||
// if none.
|
||||
//
|
||||
dojo.widget.html.stabile.getState = function(id){
|
||||
dojo.widget.html.stabile.setup();
|
||||
return dojo.widget.html.stabile.widgetState[id];
|
||||
}
|
||||
|
||||
|
||||
// Set the state stored for the widget with the given ID. If isCommit
|
||||
// is true, commits all widget state to more stable storage.
|
||||
//
|
||||
dojo.widget.html.stabile.setState = function(id, state, isCommit){
|
||||
dojo.widget.html.stabile.setup();
|
||||
dojo.widget.html.stabile.widgetState[id] = state;
|
||||
if(isCommit){
|
||||
dojo.widget.html.stabile.commit(dojo.widget.html.stabile.widgetState);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sets up widgetState: a hash keyed by widgetId, maps to an object
|
||||
// or array writable with "describe". If there is data in the widget
|
||||
// storage area, use it, otherwise initialize an empty object.
|
||||
//
|
||||
dojo.widget.html.stabile.setup = function(){
|
||||
if(!dojo.widget.html.stabile.widgetState){
|
||||
var text = dojo.widget.html.stabile.getStorage().value;
|
||||
dojo.widget.html.stabile.widgetState = text ? dj_eval("("+text+")") : {};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Commits all widget state to more stable storage, so if the user
|
||||
// navigates away and returns, it can be restored.
|
||||
//
|
||||
dojo.widget.html.stabile.commit = function(state){
|
||||
dojo.widget.html.stabile.getStorage().value = dojo.widget.html.stabile.description(state);
|
||||
}
|
||||
|
||||
// Return a JSON "description string" for the given value.
|
||||
// Supports only core JavaScript types with literals, plus Date,
|
||||
// and cyclic structures are unsupported.
|
||||
// showAll defaults to false -- if true, this becomes a simple symbolic
|
||||
// object dumper, but you cannot "eval" the output.
|
||||
//
|
||||
dojo.widget.html.stabile.description = function(v, showAll){
|
||||
// Save and later restore dojo.widget.html.stabile._depth;
|
||||
var depth = dojo.widget.html.stabile._depth;
|
||||
|
||||
var describeThis = function() {
|
||||
return this.description(this, true);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
if(v===void(0)){
|
||||
return "undefined";
|
||||
}
|
||||
if(v===null){
|
||||
return "null";
|
||||
}
|
||||
if(typeof(v)=="boolean" || typeof(v)=="number"
|
||||
|| v instanceof Boolean || v instanceof Number){
|
||||
return v.toString();
|
||||
}
|
||||
|
||||
if(typeof(v)=="string" || v instanceof String){
|
||||
// Quote strings and their contents as required.
|
||||
// Replacing by $& fails in IE 5.0
|
||||
var v1 = v.replace(dojo.widget.html.stabile._sqQuotables, "\\$1");
|
||||
v1 = v1.replace(/\n/g, "\\n");
|
||||
v1 = v1.replace(/\r/g, "\\r");
|
||||
// Any other important special cases?
|
||||
return "'"+v1+"'";
|
||||
}
|
||||
|
||||
if(v instanceof Date){
|
||||
// Create a data constructor.
|
||||
return "new Date("+d.getFullYear+","+d.getMonth()+","+d.getDate()+")";
|
||||
}
|
||||
|
||||
var d;
|
||||
if(v instanceof Array || v.push){
|
||||
// "push" test needed for KHTML/Safari, don't know why -cp
|
||||
|
||||
if(depth>=dojo.widget.html.stabile.depthLimit)
|
||||
return "[ ... ]";
|
||||
|
||||
d = "[";
|
||||
var first = true;
|
||||
dojo.widget.html.stabile._depth++;
|
||||
for(var i=0; i<v.length; i++){
|
||||
// Skip functions and undefined values
|
||||
// if(v[i]==undef || typeof(v[i])=="function")
|
||||
// continue;
|
||||
if(first){
|
||||
first = false;
|
||||
}else{
|
||||
d += ",";
|
||||
}
|
||||
d+=arguments.callee(v[i], showAll);
|
||||
}
|
||||
return d+"]";
|
||||
}
|
||||
|
||||
if(v.constructor==Object
|
||||
|| v.toString==describeThis){
|
||||
if(depth>=dojo.widget.html.stabile.depthLimit)
|
||||
return "{ ... }";
|
||||
|
||||
// Instanceof Hash is good, or if we just use Objects,
|
||||
// we can say v.constructor==Object.
|
||||
// IE (5?) lacks hasOwnProperty, but perhaps objects do not always
|
||||
// have prototypes??
|
||||
if(typeof(v.hasOwnProperty)!="function" && v.prototype){
|
||||
throw new Error("description: "+v+" not supported by script engine");
|
||||
}
|
||||
var first = true;
|
||||
d = "{";
|
||||
dojo.widget.html.stabile._depth++;
|
||||
for(var key in v){
|
||||
// Skip values that are functions or undefined.
|
||||
if(v[key]==void(0) || typeof(v[key])=="function")
|
||||
continue;
|
||||
if(first){
|
||||
first = false;
|
||||
}else{
|
||||
d += ", ";
|
||||
}
|
||||
var kd = key;
|
||||
// If the key is not a legal identifier, use its description.
|
||||
// For strings this will quote the stirng.
|
||||
if(!kd.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/)){
|
||||
kd = arguments.callee(key, showAll);
|
||||
}
|
||||
d += kd+": "+arguments.callee(v[key], showAll);
|
||||
}
|
||||
return d+"}";
|
||||
}
|
||||
|
||||
if(showAll){
|
||||
if(dojo.widget.html.stabile._recur){
|
||||
// Save the original definitions of toString;
|
||||
var objectToString = Object.prototype.toString;
|
||||
return objectToString.apply(v, []);
|
||||
}else{
|
||||
dojo.widget.html.stabile._recur = true;
|
||||
return v.toString();
|
||||
}
|
||||
}else{
|
||||
// log("Description? "+v.toString()+", "+typeof(v));
|
||||
throw new Error("Unknown type: "+v);
|
||||
return "'unknown'";
|
||||
}
|
||||
|
||||
} finally {
|
||||
// Always restore the global current depth.
|
||||
dojo.widget.html.stabile._depth = depth;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//// PRIVATE TO MODULE
|
||||
|
||||
// Gets an object (form field) with a read/write "value" property.
|
||||
//
|
||||
dojo.widget.html.stabile.getStorage = function(){
|
||||
if (dojo.widget.html.stabile.dataField) {
|
||||
return dojo.widget.html.stabile.dataField;
|
||||
}
|
||||
var form = document.forms._dojo_form;
|
||||
return dojo.widget.html.stabile.dataField = form ? form.stabile : {value: ""};
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue